• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jo-hoe / video-to-podcast-service / 16167033865

09 Jul 2025 10:34AM UTC coverage: 21.022% (-1.6%) from 22.669%
16167033865

push

github

jo-hoe
refactor: enhance deleteFeedItem and validateItemPathComponents methods for improved error handling and path validation

0 of 54 new or added lines in 1 file covered. (0.0%)

71 existing lines in 4 files now uncovered.

214 of 1018 relevant lines covered (21.02%)

0.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.83
/internal/core/database/sqlitedatabase.go
1
package database
2

3
import (
4
        "database/sql"
5
        "fmt"
6
        "os"
7

8
        _ "github.com/mattn/go-sqlite3"
9
)
10

11
const (
12
        defaultDatabaseName     = "podcast_items"
13
        defaultDatabaseExt      = ".db"
14
        defaultDatabaseFileName = defaultDatabaseName + defaultDatabaseExt
15
)
16

17
// SQLiteDatabase implements the Database interface using SQLite and prepared statements.
18
type SQLiteDatabase struct {
19
        db               *sql.DB
20
        connectionString string
21
}
22

23
func NewSQLiteDatabase(connectionString string) *SQLiteDatabase {
2✔
24
        return &SQLiteDatabase{
2✔
25
                connectionString: connectionString,
2✔
26
        }
2✔
27
}
2✔
28

29
func (s *SQLiteDatabase) InitializeDatabase() (*sql.DB, error) {
×
30
        db, err := sql.Open("sqlite3", s.connectionString)
×
31
        if err != nil {
×
32
                return nil, err
×
33
        }
×
34
        // Optionally, check if the connection is valid
35
        if err := db.Ping(); err != nil {
×
36
                _ = db.Close()
×
37
                return nil, err
×
38
        }
×
39
        s.db = db
×
40
        return db, nil
×
41
}
42

43
func (s *SQLiteDatabase) CreateDatabase() (*sql.DB, error) {
2✔
44
        // Handle empty connection string by setting a default file-based database
2✔
45
        if s.connectionString == "" {
2✔
46
                s.connectionString = defaultDatabaseFileName
×
47
        }
×
48
        db, err := sql.Open("sqlite3", s.connectionString)
2✔
49
        if err != nil {
2✔
50
                return nil, err
×
51
        }
×
52
        createTableStmt := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s (
2✔
53
                id TEXT PRIMARY KEY,
2✔
54
                title TEXT,
2✔
55
                description TEXT,
2✔
56
                author TEXT,
2✔
57
                thumbnail TEXT,
2✔
58
                duration_in_milliseconds INTEGER,
2✔
59
                video_url TEXT,
2✔
60
                audio_file_path TEXT,
2✔
61
                created_at DATETIME,
2✔
62
                updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
2✔
63
        )`, defaultDatabaseName)
2✔
64
        _, err = db.Exec(createTableStmt)
2✔
65
        if err != nil {
2✔
66
                _ = db.Close()
×
67
                return nil, err
×
68
        }
×
69
        s.db = db
2✔
70
        return db, nil
2✔
71
}
72

73
func (s *SQLiteDatabase) DoesDatabaseExist() bool {
×
74
        // Check if the database file exists
×
75
        if s.db == nil {
×
76
                return false
×
77
        }
×
78
        var exists bool
×
79
        // Check if the table exists in the database
×
80
        err := s.db.QueryRow(fmt.Sprintf(`SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE type='table' AND name='%s')`, defaultDatabaseName)).Scan(&exists)
×
81
        if err != nil {
×
82
                return false
×
83
        }
×
84
        return exists
×
85
}
86

87
func (s *SQLiteDatabase) CreatePodcastItem(item *PodcastItem) error {
3✔
88
        stmt, err := s.db.Prepare(fmt.Sprintf(`INSERT OR REPLACE INTO %s (
3✔
89
                id, title, description, author, thumbnail, duration_in_milliseconds, video_url, audio_file_path, created_at, updated_at
3✔
90
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, defaultDatabaseName))
3✔
91
        if err != nil {
3✔
92
                return err
×
93
        }
×
94
        defer func() { _ = stmt.Close() }()
6✔
95
        _, err = stmt.Exec(
3✔
96
                item.ID, item.Title, item.Description, item.Author, item.Thumbnail,
3✔
97
                item.DurationInMilliseconds, item.VideoURL, item.AudioFilePath, item.CreatedAt, item.UpdatedAt,
3✔
98
        )
3✔
99
        return err
3✔
100
}
101

102
func (s *SQLiteDatabase) GetAllPodcastItems() ([]*PodcastItem, error) {
2✔
103
        rows, err := s.db.Query(fmt.Sprintf(`SELECT id, title, description, author, thumbnail, duration_in_milliseconds, video_url, audio_file_path, created_at, updated_at FROM %s`, defaultDatabaseName))
2✔
104
        if err != nil {
2✔
105
                return nil, err
×
106
        }
×
107
        defer func() { _ = rows.Close() }()
4✔
108
        var items []*PodcastItem
2✔
109
        for rows.Next() {
4✔
110
                item := &PodcastItem{}
2✔
111
                err := rows.Scan(&item.ID, &item.Title, &item.Description, &item.Author, &item.Thumbnail, &item.DurationInMilliseconds, &item.VideoURL, &item.AudioFilePath, &item.CreatedAt, &item.UpdatedAt)
2✔
112
                if err != nil {
2✔
113
                        return nil, err
×
114
                }
×
115
                items = append(items, item)
2✔
116
        }
117
        return items, nil
2✔
118
}
119

120
func (m *SQLiteDatabase) DeletePodcastItem(id string) error {
×
121
        stmt, err := m.db.Prepare(fmt.Sprintf(`DELETE FROM %s WHERE id = ?`, defaultDatabaseName))
×
122
        if err != nil {
×
123
                return err
×
124
        }
×
125
        defer func() { _ = stmt.Close() }()
×
126
        _, err = stmt.Exec(id)
×
127
        if err != nil {
×
128
                return fmt.Errorf("failed to delete podcast item with id %s: %w", id, err)
×
129
        }
×
130
        return nil
×
131
}
132

UNCOV
133
func (s *SQLiteDatabase) GetPodcastItemByID(id string) (*PodcastItem, error) {
×
UNCOV
134
        stmt, err := s.db.Prepare(fmt.Sprintf(`SELECT id, title, description, author, thumbnail, duration_in_milliseconds, video_url, audio_file_path, created_at, updated_at FROM %s WHERE id = ?`, defaultDatabaseName))
×
UNCOV
135
        if err != nil {
×
UNCOV
136
                return nil, err
×
UNCOV
137
        }
×
UNCOV
138
        defer func() { _ = stmt.Close() }()
×
UNCOV
139
        item := &PodcastItem{}
×
140
        err = stmt.QueryRow(id).Scan(&item.ID, &item.Title, &item.Description, &item.Author, &item.Thumbnail, &item.DurationInMilliseconds, &item.VideoURL, &item.AudioFilePath, &item.CreatedAt, &item.UpdatedAt)
×
141
        if err != nil {
×
UNCOV
142
                if err == sql.ErrNoRows {
×
UNCOV
143
                        return nil, fmt.Errorf("podcast item with id %s not found", id)
×
144
                }
×
145
                return nil, err
×
146
        }
UNCOV
147
        return item, nil
×
148
}
149

150
// Close closes the database connection.
151
func (s *SQLiteDatabase) CloseConnection() error {
2✔
152
        return s.db.Close()
2✔
153
}
2✔
154

155
func (s *SQLiteDatabase) DropDatabase() error {
2✔
156
        if s.db == nil {
2✔
UNCOV
157
                return fmt.Errorf("database connection is not initialized")
×
UNCOV
158
        }
×
159
        // Close the database connection before dropping it
160
        if err := s.CloseConnection(); err != nil {
2✔
UNCOV
161
                return err
×
UNCOV
162
        }
×
163
        // Remove the database file
164
        return os.Remove(s.connectionString)
2✔
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc