From bceb99fb3ee1e4dd34655bc2f20a743b845ec263 Mon Sep 17 00:00:00 2001 From: Son Roy Almerol Date: Thu, 29 Feb 2024 19:43:10 -0500 Subject: [PATCH 01/19] switch to sqlite --- go.mod | 2 + go.sum | 2 + m3u/parser.go | 10 ++-- m3u/save.go | 131 ++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 126 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index d71184b7..8acbac1d 100644 --- a/go.mod +++ b/go.mod @@ -3,3 +3,5 @@ module m3u-stream-merger go 1.21.5 require github.com/satori/go.uuid v1.2.0 + +require github.com/mattn/go-sqlite3 v1.14.22 // indirect diff --git a/go.sum b/go.sum index a9a76200..ffa6caf2 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= diff --git a/m3u/parser.go b/m3u/parser.go index ab15c8a7..309a61b5 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -14,10 +14,10 @@ import ( func GetStreams(skipClearing bool) error { if !skipClearing { // init - log.Println("Loading from JSON...") - fromJson, err := loadFromJSON() + log.Println("Loading from database...") + fromDB, err := loadFromSQLite() if err == nil { - Streams = fromJson + Streams = fromDB return nil } @@ -60,8 +60,8 @@ func GetStreams(skipClearing bool) error { Streams = NewStreams - fmt.Print("Saving to JSON...\n") - _ = saveToJSON(Streams) + fmt.Print("Saving to database...\n") + _ = saveToSQLite(Streams) return nil } diff --git a/m3u/save.go b/m3u/save.go index 32ea2502..e14ec854 100644 --- a/m3u/save.go +++ b/m3u/save.go @@ -1,38 +1,141 @@ package m3u import ( - "encoding/json" + "database/sql" "fmt" "os" "path/filepath" + + _ "github.com/mattn/go-sqlite3" ) -func saveToJSON(streams []StreamInfo) error { - filename := filepath.Join(".", "data", "database.json") - data, err := json.MarshalIndent(streams, "", " ") +var db *sql.DB + +func init() { + filename := filepath.Join(".", "data", "database.sqlite") + var err error + db, err = sql.Open("sqlite3", filename) if err != nil { - return fmt.Errorf("error marshalling to JSON: %v", err) + fmt.Printf("error opening SQLite database: %v\n", err) + os.Exit(1) } - err = os.WriteFile(filename, data, 0644) + // Create table if not exists + _, err = db.Exec(` + CREATE TABLE IF NOT EXISTS streams ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT UNIQUE, + tvg_id TEXT, + logo_url TEXT, + group_name TEXT + ) + `) if err != nil { - return fmt.Errorf("error writing JSON file: %v", err) + fmt.Printf("error creating table: %v\n", err) + os.Exit(1) + } + + _, err = db.Exec(` + CREATE TABLE IF NOT EXISTS stream_urls ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + stream_id INTEGER, + content TEXT, + m3u_index INTEGER, + FOREIGN KEY(stream_id) REFERENCES streams(id) + ) + `) + if err != nil { + fmt.Printf("error creating table: %v\n", err) + os.Exit(1) + } +} + +func saveToSQLite(streams []StreamInfo) error { + tx, err := db.Begin() + if err != nil { + return fmt.Errorf("error beginning transaction: %v", err) + } + defer tx.Rollback() + + stmt, err := tx.Prepare("INSERT INTO streams(title, tvg_id, logo_url, group_name) VALUES(?, ?, ?, ?)") + if err != nil { + return fmt.Errorf("error preparing statement: %v", err) + } + defer stmt.Close() + + for _, s := range streams { + res, err := stmt.Exec(s.Title, s.TvgID, s.LogoURL, s.Group) + if err != nil { + return fmt.Errorf("error inserting stream: %v", err) + } + + streamID, err := res.LastInsertId() + if err != nil { + return fmt.Errorf("error getting last inserted ID: %v", err) + } + + urlStmt, err := tx.Prepare("INSERT INTO stream_urls(stream_id, content, m3u_index) VALUES(?, ?, ?)") + if err != nil { + return fmt.Errorf("error preparing statement: %v", err) + } + defer urlStmt.Close() + + for _, u := range s.URLs { + _, err := urlStmt.Exec(streamID, u.Content, u.M3UIndex) + if err != nil { + return fmt.Errorf("error inserting stream URL: %v", err) + } + } + } + + err = tx.Commit() + if err != nil { + return fmt.Errorf("error committing transaction: %v", err) } return nil } -func loadFromJSON() ([]StreamInfo, error) { - filename := filepath.Join(".", "data", "database.json") - data, err := os.ReadFile(filename) +func loadFromSQLite() ([]StreamInfo, error) { + rows, err := db.Query("SELECT id, title, tvg_id, logo_url, group_name FROM streams") if err != nil { - return nil, fmt.Errorf("error reading JSON file: %v", err) + return nil, fmt.Errorf("error querying streams: %v", err) } + defer rows.Close() var streams []StreamInfo - err = json.Unmarshal(data, &streams) - if err != nil { - return nil, fmt.Errorf("error unmarshalling from JSON: %v", err) + for rows.Next() { + var s StreamInfo + var streamId int + err := rows.Scan(&streamId, &s.Title, &s.TvgID, &s.LogoURL, &s.Group) + if err != nil { + return nil, fmt.Errorf("error scanning stream: %v", err) + } + + urlRows, err := db.Query("SELECT content, m3u_index FROM stream_urls WHERE stream_id = ?", streamId) + if err != nil { + return nil, fmt.Errorf("error querying stream URLs: %v", err) + } + defer urlRows.Close() + + var urls []StreamURL + for urlRows.Next() { + var u StreamURL + err := urlRows.Scan(&u.Content, &u.M3UIndex) + if err != nil { + return nil, fmt.Errorf("error scanning stream URL: %v", err) + } + urls = append(urls, u) + } + if err := urlRows.Err(); err != nil { + return nil, fmt.Errorf("error iterating over URL rows: %v", err) + } + + s.URLs = urls + streams = append(streams, s) + } + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("error iterating over rows: %v", err) } return streams, nil From 0d1961417222438755391021c432c407e1cd3ae6 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 19:52:16 -0500 Subject: [PATCH 02/19] fix indents and initialize --- m3u/parser.go | 3 +++ m3u/save.go | 34 +++++++++++++++++----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/m3u/parser.go b/m3u/parser.go index 309a61b5..02e18f6b 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -12,6 +12,9 @@ import ( // GetStreams retrieves and merges stream information from multiple M3U files. func GetStreams(skipClearing bool) error { + // Initialize database + init() + if !skipClearing { // init log.Println("Loading from database...") diff --git a/m3u/save.go b/m3u/save.go index e14ec854..0501a2a8 100644 --- a/m3u/save.go +++ b/m3u/save.go @@ -22,28 +22,28 @@ func init() { // Create table if not exists _, err = db.Exec(` - CREATE TABLE IF NOT EXISTS streams ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - title TEXT UNIQUE, - tvg_id TEXT, - logo_url TEXT, - group_name TEXT - ) - `) + CREATE TABLE IF NOT EXISTS streams ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT UNIQUE, + tvg_id TEXT, + logo_url TEXT, + group_name TEXT + ) + `) if err != nil { fmt.Printf("error creating table: %v\n", err) os.Exit(1) } - _, err = db.Exec(` - CREATE TABLE IF NOT EXISTS stream_urls ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - stream_id INTEGER, - content TEXT, - m3u_index INTEGER, - FOREIGN KEY(stream_id) REFERENCES streams(id) - ) - `) + _, err = db.Exec(` + CREATE TABLE IF NOT EXISTS stream_urls ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + stream_id INTEGER, + content TEXT, + m3u_index INTEGER, + FOREIGN KEY(stream_id) REFERENCES streams(id) + ) + `) if err != nil { fmt.Printf("error creating table: %v\n", err) os.Exit(1) From b22533bcc0fc58ea80a45983ac7ba2d196453e03 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 19:56:05 -0500 Subject: [PATCH 03/19] move db to separate namespace --- m3u/save.go => database/db.go | 8 ++++---- m3u/parser.go | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) rename m3u/save.go => database/db.go (95%) diff --git a/m3u/save.go b/database/db.go similarity index 95% rename from m3u/save.go rename to database/db.go index 0501a2a8..de8280cc 100644 --- a/m3u/save.go +++ b/database/db.go @@ -1,4 +1,4 @@ -package m3u +package database import ( "database/sql" @@ -11,7 +11,7 @@ import ( var db *sql.DB -func init() { +func InitializeSQLite() { filename := filepath.Join(".", "data", "database.sqlite") var err error db, err = sql.Open("sqlite3", filename) @@ -50,7 +50,7 @@ func init() { } } -func saveToSQLite(streams []StreamInfo) error { +func SaveToSQLite(streams []StreamInfo) error { tx, err := db.Begin() if err != nil { return fmt.Errorf("error beginning transaction: %v", err) @@ -96,7 +96,7 @@ func saveToSQLite(streams []StreamInfo) error { return nil } -func loadFromSQLite() ([]StreamInfo, error) { +func LoadFromSQLite() ([]StreamInfo, error) { rows, err := db.Query("SELECT id, title, tvg_id, logo_url, group_name FROM streams") if err != nil { return nil, fmt.Errorf("error querying streams: %v", err) diff --git a/m3u/parser.go b/m3u/parser.go index 02e18f6b..44c4a6ab 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -8,17 +8,20 @@ import ( "regexp" "strings" "sync" + + + "m3u-stream-merger/database" ) // GetStreams retrieves and merges stream information from multiple M3U files. func GetStreams(skipClearing bool) error { // Initialize database - init() + database.InitializeSQLite() if !skipClearing { // init log.Println("Loading from database...") - fromDB, err := loadFromSQLite() + fromDB, err := database.LoadFromSQLite() if err == nil { Streams = fromDB @@ -64,7 +67,7 @@ func GetStreams(skipClearing bool) error { Streams = NewStreams fmt.Print("Saving to database...\n") - _ = saveToSQLite(Streams) + _ = database.SaveToSQLite(Streams) return nil } From e17468ec5ded6d700fd6b35eae2e0d0ed99a5823 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 19:59:09 -0500 Subject: [PATCH 04/19] move types to database --- {m3u => database}/types.go | 2 +- m3u/generate.go | 5 +++-- m3u/global.go | 8 ++++++-- m3u/parser.go | 15 +++++++-------- 4 files changed, 17 insertions(+), 13 deletions(-) rename {m3u => database}/types.go (90%) diff --git a/m3u/types.go b/database/types.go similarity index 90% rename from m3u/types.go rename to database/types.go index b0b2b9a1..25db1b80 100644 --- a/m3u/types.go +++ b/database/types.go @@ -1,4 +1,4 @@ -package m3u +package database type StreamInfo struct { Title string diff --git a/m3u/generate.go b/m3u/generate.go index 7773c07c..6c0870af 100644 --- a/m3u/generate.go +++ b/m3u/generate.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "m3u-stream-merger/utils" + "m3u-stream-merger/database" "net/http" ) @@ -40,12 +41,12 @@ func GenerateM3UContent(w http.ResponseWriter, r *http.Request) { } } -func FindStreamByName(streamName string) (*StreamInfo, error) { +func FindStreamByName(streamName string) (*database.StreamInfo, error) { for _, s := range Streams { if s.Title == streamName { return &s, nil } } - return &StreamInfo{}, errors.New("stream not found") + return &database.StreamInfo{}, errors.New("stream not found") } diff --git a/m3u/global.go b/m3u/global.go index 71369c64..e92831ef 100644 --- a/m3u/global.go +++ b/m3u/global.go @@ -1,4 +1,8 @@ package m3u -var Streams []StreamInfo -var NewStreams []StreamInfo +import ( + "m3u-stream-merger/database" +) + +var Streams []database.StreamInfo +var NewStreams []database.StreamInfo diff --git a/m3u/parser.go b/m3u/parser.go index 44c4a6ab..300093fd 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -9,7 +9,6 @@ import ( "strings" "sync" - "m3u-stream-merger/database" ) @@ -72,14 +71,14 @@ func GetStreams(skipClearing bool) error { return nil } -// mergeStreamInfo merges two slices of StreamInfo based on Title. -func mergeStreamInfo(existing, new []StreamInfo) []StreamInfo { +// mergeStreamInfo merges two slices of database.StreamInfo based on Title. +func mergeStreamInfo(existing, new []database.StreamInfo) []database.StreamInfo { var wg sync.WaitGroup var mutex sync.Mutex for _, stream := range new { wg.Add(1) - go func(s StreamInfo) { + go func(s database.StreamInfo) { defer wg.Done() mutex.Lock() defer mutex.Unlock() @@ -101,9 +100,9 @@ func mergeStreamInfo(existing, new []StreamInfo) []StreamInfo { return existing } -func parseM3UFile(filePath string, m3uIndex int) ([]StreamInfo, error) { +func parseM3UFile(filePath string, m3uIndex int) ([]database.StreamInfo, error) { fmt.Printf("Parsing: %s\n", filePath) - var streams []StreamInfo + var streams []database.StreamInfo file, err := os.Open(filePath) if err != nil { @@ -113,13 +112,13 @@ func parseM3UFile(filePath string, m3uIndex int) ([]StreamInfo, error) { scanner := bufio.NewScanner(file) - var currentStream StreamInfo + var currentStream database.StreamInfo for scanner.Scan() { line := scanner.Text() if strings.HasPrefix(line, "#EXTINF:") { - currentStream = StreamInfo{} + currentStream = database.StreamInfo{} // Define a regular expression to capture key-value pairs regex := regexp.MustCompile(`(\S+?)="([^"]*?)"`) From d1a1a80b1d54259ffe87ae5478e1fccac914bad1 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:00:45 -0500 Subject: [PATCH 05/19] fix StreamURL --- m3u/parser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m3u/parser.go b/m3u/parser.go index 300093fd..4c294ddd 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -149,7 +149,7 @@ func parseM3UFile(filePath string, m3uIndex int) ([]database.StreamInfo, error) } } else if strings.HasPrefix(line, "http") { // Extract URL - currentStream.URLs = []StreamURL{ + currentStream.URLs = []database.StreamURL{ { Content: line, M3UIndex: m3uIndex, From 2d20d1aac08c7bb9c5b0a3a7cf8f7fbd557684bb Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:04:07 -0500 Subject: [PATCH 06/19] fix minor indent --- database/db.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/db.go b/database/db.go index de8280cc..671f552d 100644 --- a/database/db.go +++ b/database/db.go @@ -106,7 +106,7 @@ func LoadFromSQLite() ([]StreamInfo, error) { var streams []StreamInfo for rows.Next() { var s StreamInfo - var streamId int + var streamId int err := rows.Scan(&streamId, &s.Title, &s.TvgID, &s.LogoURL, &s.Group) if err != nil { return nil, fmt.Errorf("error scanning stream: %v", err) From b847b1d882ed74e5f91600166ed54daafed93716 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:34:18 -0500 Subject: [PATCH 07/19] add database test and add to dockerfile --- Dockerfile | 3 +++ database/database_test.go | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 database/database_test.go diff --git a/Dockerfile b/Dockerfile index daa18556..ac6e22f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,6 +16,9 @@ COPY . . # Build the Go app RUN go build -o main . +# Run tests +RUN go test ./... + #################### FROM scratch diff --git a/database/database_test.go b/database/database_test.go new file mode 100644 index 00000000..c1b830a7 --- /dev/null +++ b/database/database_test.go @@ -0,0 +1,51 @@ +package database + +import ( + "testing" + "os" +) + +func TestInitializeSQLite(t *testing.T) { + // Test InitializeSQLite and check if the database file exists + err := InitializeSQLite() + if err != nil { + t.Errorf("InitializeSQLite returned error: %v", err) + } + defer os.Remove(sqliteDBPath) // Cleanup the database file after the test +} + +func TestSaveAndLoadFromSQLite(t *testing.T) { + // Test LoadFromSQLite with existing data in the database + expected := []StreamInfo{{ + Title: "stream1", + TvgID: "test1", + LogoURL: "http://test.com/image.png", + Group: "test", + URLs: []StreamURL{{ + Content: "testing", + M3UIndex: 1 + }} + }, { + Title: "stream2" + TvgID: "test2", + LogoURL: "http://test2.com/image.png", + Group: "test2", + URLs: []StreamURL{{ + Content: "testing2", + M3UIndex: 2 + }} + }} + err = SaveToSQLite(expected) // Insert test data into the database + if err != nil { + t.Errorf("SaveToSQLite returned error: %v", err) + } + + result, err := LoadFromSQLite() + if err != nil { + t.Errorf("LoadFromSQLite returned error: %v", err) + } + + if len(result) != len(expected) { + t.Errorf("LoadFromSQLite returned %+v, expected %+v", result, expected) + } +} From c643f4a60273d689b8fede54f33d8c955540fb69 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:35:20 -0500 Subject: [PATCH 08/19] fix commas --- database/database_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/database/database_test.go b/database/database_test.go index c1b830a7..201d0618 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -23,8 +23,8 @@ func TestSaveAndLoadFromSQLite(t *testing.T) { Group: "test", URLs: []StreamURL{{ Content: "testing", - M3UIndex: 1 - }} + M3UIndex: 1, + }}, }, { Title: "stream2" TvgID: "test2", @@ -32,8 +32,8 @@ func TestSaveAndLoadFromSQLite(t *testing.T) { Group: "test2", URLs: []StreamURL{{ Content: "testing2", - M3UIndex: 2 - }} + M3UIndex: 2, + }}, }} err = SaveToSQLite(expected) // Insert test data into the database if err != nil { From f4ab032035165f37abf3045f0944f8213d9fe2e9 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:37:07 -0500 Subject: [PATCH 09/19] fix comma missing --- database/database_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/database_test.go b/database/database_test.go index 201d0618..3c64b994 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -26,7 +26,7 @@ func TestSaveAndLoadFromSQLite(t *testing.T) { M3UIndex: 1, }}, }, { - Title: "stream2" + Title: "stream2", TvgID: "test2", LogoURL: "http://test2.com/image.png", Group: "test2", From 356fcbabd20b478719e0339cd1bc49fe4c2f6c39 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:38:26 -0500 Subject: [PATCH 10/19] add filepath to tests --- database/database_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/database/database_test.go b/database/database_test.go index 3c64b994..4299db89 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -3,9 +3,12 @@ package database import ( "testing" "os" + "path/filepath" ) func TestInitializeSQLite(t *testing.T) { + sqliteDBPath := filepath.Join(".", "data", "database.sqlite") + // Test InitializeSQLite and check if the database file exists err := InitializeSQLite() if err != nil { From d0fb4944751b4de3eb3419d6739a2370662c9f17 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:40:44 -0500 Subject: [PATCH 11/19] return error InitializeSQLite --- database/db.go | 11 ++++------- m3u/parser.go | 5 ++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/database/db.go b/database/db.go index 671f552d..d41644f4 100644 --- a/database/db.go +++ b/database/db.go @@ -11,13 +11,12 @@ import ( var db *sql.DB -func InitializeSQLite() { +func InitializeSQLite() error { filename := filepath.Join(".", "data", "database.sqlite") var err error db, err = sql.Open("sqlite3", filename) if err != nil { - fmt.Printf("error opening SQLite database: %v\n", err) - os.Exit(1) + return fmt.Errorf("error opening SQLite database: %v\n", err) } // Create table if not exists @@ -31,8 +30,7 @@ func InitializeSQLite() { ) `) if err != nil { - fmt.Printf("error creating table: %v\n", err) - os.Exit(1) + return fmt.Errorf("error creating table: %v\n", err) } _, err = db.Exec(` @@ -45,8 +43,7 @@ func InitializeSQLite() { ) `) if err != nil { - fmt.Printf("error creating table: %v\n", err) - os.Exit(1) + return fmt.Errorf("error creating table: %v\n", err) } } diff --git a/m3u/parser.go b/m3u/parser.go index 4c294ddd..81ffac46 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -15,7 +15,10 @@ import ( // GetStreams retrieves and merges stream information from multiple M3U files. func GetStreams(skipClearing bool) error { // Initialize database - database.InitializeSQLite() + err := database.InitializeSQLite() + if err != nil { + return fmt.Errorf("InitializeSQLite error: %v", err) + } if !skipClearing { // init From 34a21217bc0eebee17a88c70c02299fab8a42720 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:44:11 -0500 Subject: [PATCH 12/19] remove os import and return nil by default --- database/db.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/database/db.go b/database/db.go index d41644f4..b3e8b8ea 100644 --- a/database/db.go +++ b/database/db.go @@ -3,7 +3,6 @@ package database import ( "database/sql" "fmt" - "os" "path/filepath" _ "github.com/mattn/go-sqlite3" @@ -45,6 +44,8 @@ func InitializeSQLite() error { if err != nil { return fmt.Errorf("error creating table: %v\n", err) } + + return nil } func SaveToSQLite(streams []StreamInfo) error { From 836515f658c8e7285a2db64a1aa4e403b4134b71 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:52:55 -0500 Subject: [PATCH 13/19] fix error declaration --- m3u/parser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m3u/parser.go b/m3u/parser.go index 81ffac46..b116cf3b 100644 --- a/m3u/parser.go +++ b/m3u/parser.go @@ -31,7 +31,7 @@ func GetStreams(skipClearing bool) error { } } - err := loadM3UFiles(skipClearing) + err = loadM3UFiles(skipClearing) if err != nil { return fmt.Errorf("loadM3UFiles error: %v", err) } From c686e7828a3039c8a1bfe1405b2d3e71bc6873ef Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:54:23 -0500 Subject: [PATCH 14/19] fix err declaration again --- database/database_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/database_test.go b/database/database_test.go index 4299db89..097ff2e4 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -38,7 +38,7 @@ func TestSaveAndLoadFromSQLite(t *testing.T) { M3UIndex: 2, }}, }} - err = SaveToSQLite(expected) // Insert test data into the database + err := SaveToSQLite(expected) // Insert test data into the database if err != nil { t.Errorf("SaveToSQLite returned error: %v", err) } From cc9038dbdf8ea6ab6b81f7a7a315bd27e941d697 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 20:56:35 -0500 Subject: [PATCH 15/19] add cgo to dockerfile --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ac6e22f0..88798d40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,9 @@ RUN go mod download COPY . . # Build the Go app -RUN go build -o main . +ENV CGO_ENABLED=1 +RUN apk add --no-cache gcc musl-dev +RUN go build -ldflags='-s -w -extldflags "-static"' -o main . # Run tests RUN go test ./... From a7196344c9d25b8f94bb32f845d2f7f306ff13a8 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 21:03:02 -0500 Subject: [PATCH 16/19] create database file before opening --- database/db.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/database/db.go b/database/db.go index b3e8b8ea..7c8c3bee 100644 --- a/database/db.go +++ b/database/db.go @@ -3,6 +3,7 @@ package database import ( "database/sql" "fmt" + "os" "path/filepath" _ "github.com/mattn/go-sqlite3" @@ -11,8 +12,19 @@ import ( var db *sql.DB func InitializeSQLite() error { - filename := filepath.Join(".", "data", "database.sqlite") - var err error + foldername := filepath.Join(".", "data") + filename := filepath.Join(foldername, "database.sqlite") + + err := os.MkdirAll(foldername, 0755) + if err != nil { + return fmt.Errorf("error creating data folder: %v\n", err) + } + + err = os.Create(filename) + if err != nil { + return fmt.Errorf("error creating database file: %v\n", err) + } + db, err = sql.Open("sqlite3", filename) if err != nil { return fmt.Errorf("error opening SQLite database: %v\n", err) From 1c5cb8a6195577057074a13104e85316c31a2cd5 Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 21:05:03 -0500 Subject: [PATCH 17/19] ignore file return --- database/db.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/db.go b/database/db.go index 7c8c3bee..5a99a706 100644 --- a/database/db.go +++ b/database/db.go @@ -20,7 +20,7 @@ func InitializeSQLite() error { return fmt.Errorf("error creating data folder: %v\n", err) } - err = os.Create(filename) + _, err = os.Create(filename) if err != nil { return fmt.Errorf("error creating database file: %v\n", err) } From 9628a3d76a877ba7f3509ca4a59bbf5ebb25f52b Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 21:11:34 -0500 Subject: [PATCH 18/19] explicit openfile and close --- database/db.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/database/db.go b/database/db.go index 5a99a706..d289a0cf 100644 --- a/database/db.go +++ b/database/db.go @@ -20,10 +20,11 @@ func InitializeSQLite() error { return fmt.Errorf("error creating data folder: %v\n", err) } - _, err = os.Create(filename) + file, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0666) if err != nil { return fmt.Errorf("error creating database file: %v\n", err) } + file.Close() db, err = sql.Open("sqlite3", filename) if err != nil { From e55fb5b8b8575f5973abc4e4e5e7b4985f2105af Mon Sep 17 00:00:00 2001 From: Son Date: Thu, 29 Feb 2024 21:14:30 -0500 Subject: [PATCH 19/19] combine initialization and save/load test --- database/database_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/database/database_test.go b/database/database_test.go index 097ff2e4..be5e2ecc 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -6,8 +6,8 @@ import ( "path/filepath" ) -func TestInitializeSQLite(t *testing.T) { - sqliteDBPath := filepath.Join(".", "data", "database.sqlite") +func TestSaveAndLoadFromSQLite(t *testing.T) { + sqliteDBPath := filepath.Join(".", "data", "database.sqlite") // Test InitializeSQLite and check if the database file exists err := InitializeSQLite() @@ -15,9 +15,7 @@ func TestInitializeSQLite(t *testing.T) { t.Errorf("InitializeSQLite returned error: %v", err) } defer os.Remove(sqliteDBPath) // Cleanup the database file after the test -} -func TestSaveAndLoadFromSQLite(t *testing.T) { // Test LoadFromSQLite with existing data in the database expected := []StreamInfo{{ Title: "stream1", @@ -38,7 +36,7 @@ func TestSaveAndLoadFromSQLite(t *testing.T) { M3UIndex: 2, }}, }} - err := SaveToSQLite(expected) // Insert test data into the database + err = SaveToSQLite(expected) // Insert test data into the database if err != nil { t.Errorf("SaveToSQLite returned error: %v", err) }