diff --git a/cmd/serve/main.go b/cmd/serve/main.go index c4e96f5..66df405 100644 --- a/cmd/serve/main.go +++ b/cmd/serve/main.go @@ -1,5 +1,13 @@ -package serve +package main + +import ( + "scrap/internal/config" + "scrap/internal/db" +) func main() { + config.Setup() + db.Setup() + defer db.Close() } diff --git a/config.json b/config.json new file mode 100644 index 0000000..e210c76 --- /dev/null +++ b/config.json @@ -0,0 +1,3 @@ +{ + "sql-tables-dir": "./sqltable/" +} \ No newline at end of file diff --git a/example.db b/example.db new file mode 100644 index 0000000..dd49cbd Binary files /dev/null and b/example.db differ diff --git a/go.mod b/go.mod index f51bd68..83ffde0 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module scrap go 1.24.4 + +require github.com/mattn/go-sqlite3 v1.14.32 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..66f7516 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= diff --git a/internal/config/setup.go b/internal/config/setup.go new file mode 100644 index 0000000..63869de --- /dev/null +++ b/internal/config/setup.go @@ -0,0 +1,25 @@ +package config + +import ( + "encoding/json" + "os" +) + +type AppConfig struct { + SqlTablesDir string `json:"sql-tables-dir"` +} + +var appConfigInstance *AppConfig + +func Setup() { + file, err := os.ReadFile("config.json") + if err != nil { + panic(err) + } + + if err = json.Unmarshal(file, &appConfigInstance); err != nil { + panic(err) + } +} + +func GetAppConfig() *AppConfig { return appConfigInstance } diff --git a/internal/db/irepository.go b/internal/db/irepository.go new file mode 100644 index 0000000..c6c67be --- /dev/null +++ b/internal/db/irepository.go @@ -0,0 +1,14 @@ +package db + +import "database/sql" + +type ITxRepository interface { + // Creates a new tx. + Begin() (*sql.Tx, error) + + // Rollbacks tx's data or returns an error to the given error's pointer address. + RollbackOnError(*sql.Tx, *error) + + // Applies changes to the database. + Commit(*sql.Tx) error +} diff --git a/internal/db/repository.go b/internal/db/repository.go new file mode 100644 index 0000000..a3d1fa5 --- /dev/null +++ b/internal/db/repository.go @@ -0,0 +1,34 @@ +package db + +import ( + "database/sql" +) + +type TxRepository struct { + db *sql.DB +} + +func NewTxRepository(instance *sql.DB) ITxRepository { + return &TxRepository{ + db: instance, + } +} + +func (t TxRepository) Begin() (*sql.Tx, error) { + tx, err := t.db.Begin() + if err != nil { + return nil, err + } + + return tx, nil +} + +func (TxRepository) RollbackOnError(tx *sql.Tx, errObserve *error) { + if *errObserve != nil { + tx.Rollback() + } +} + +func (TxRepository) Commit(tx *sql.Tx) error { + return tx.Commit() +} diff --git a/internal/db/setup.go b/internal/db/setup.go new file mode 100644 index 0000000..0ea40d2 --- /dev/null +++ b/internal/db/setup.go @@ -0,0 +1,65 @@ +package db + +import ( + "database/sql" + "os" + "scrap/internal/config" + "strings" + + _ "github.com/mattn/go-sqlite3" +) + +var dbInstance *sql.DB + +func Setup() { + db, err := sql.Open("sqlite3", "./example.db") + if err != nil { + panic(err) + } + + dbInstance = db + + tableFilenames := getTableFilenames() + createTablesFromSQLFiles(tableFilenames) +} + +func GetInstance() *sql.DB { return dbInstance } + +func Close() { dbInstance.Close() } + +func getTableFilenames() []string { + appConfig := config.GetAppConfig() + + files, err := os.ReadDir(appConfig.SqlTablesDir) + if err != nil { + panic(err) + } + + filenames := []string{} + for _, f := range files { + fName := f.Name() + if !strings.HasSuffix(fName, ".sql") { + continue + } + + filenames = append(filenames, fName) + } + + return filenames +} + +func createTablesFromSQLFiles(filenames []string) { + appConfig := config.GetAppConfig() + + for _, fName := range filenames { + tableBytes, err := os.ReadFile(appConfig.SqlTablesDir + fName) + if err != nil { + panic(err) + } + + tableQuery := string(tableBytes) + if _, err = dbInstance.Exec(tableQuery); err != nil { + panic(err) + } + } +} diff --git a/sqltable/1_articles.sql b/sqltable/1_articles.sql new file mode 100644 index 0000000..89f9137 --- /dev/null +++ b/sqltable/1_articles.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS articles( + uuid CHAR(36), + title VARCHAR(255), + content TEXT +) \ No newline at end of file