diff options
author | Grail Finder <wohilas@gmail.com> | 2025-04-05 15:04:15 +0300 |
---|---|---|
committer | Grail Finder <wohilas@gmail.com> | 2025-04-05 15:04:15 +0300 |
commit | 8bc7544e8933d64abc2610a265f37fe13b5767d5 (patch) | |
tree | ddcb10ff89723d0c490f6c1e781928ae89666b25 | |
parent | 287da7acfa71ff07c52035a437209022b4ddc5d6 (diff) |
Feat: question repo
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | demoon.db | bin | 0 -> 36864 bytes | |||
-rw-r--r-- | go.mod | 3 | ||||
-rw-r--r-- | go.sum | 7 | ||||
-rw-r--r-- | internal/database/migrations/001_init.down.sql | 4 | ||||
-rw-r--r-- | internal/database/migrations/001_init.up.sql | 8 | ||||
-rw-r--r-- | internal/database/migrations/002_defaults.down.sql | 5 | ||||
-rw-r--r-- | internal/database/migrations/002_defaults.up.sql | 11 | ||||
-rw-r--r-- | internal/database/migrations/002_quiz_schema.down.sql | 1 | ||||
-rw-r--r-- | internal/database/migrations/002_quiz_schema.up.sql | 17 | ||||
-rw-r--r-- | internal/database/migrations/init.go | 28 | ||||
-rw-r--r-- | internal/database/migrations/migrations.bindata.go | 267 | ||||
-rw-r--r-- | internal/database/repos/questions.go | 16 |
13 files changed, 23 insertions, 346 deletions
@@ -32,4 +32,4 @@ stop-container: docker rm -f demoon 2>/dev/null && echo "old container removed" run-container: stop-container - docker run --name=demoon -v $(CURDIR)/store.json:/root/store.json -p 0.0.0.0:9000:9000 -d demoon:master + docmer run --name=demoon -v $(CURDIR)/store.json:/root/store.json -p 0.0.0.0:9000:9000 -d demoon:master diff --git a/demoon.db b/demoon.db Binary files differnew file mode 100644 index 0000000..1536d17 --- /dev/null +++ b/demoon.db @@ -21,6 +21,7 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect @@ -35,7 +36,7 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -28,11 +28,11 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU= github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -107,8 +107,9 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/internal/database/migrations/001_init.down.sql b/internal/database/migrations/001_init.down.sql deleted file mode 100644 index 41cc5c9..0000000 --- a/internal/database/migrations/001_init.down.sql +++ /dev/null @@ -1,4 +0,0 @@ -BEGIN TRANSACTION; -DROP SCHEMA public CASCADE; -CREATE SCHEMA public; -COMMIT; diff --git a/internal/database/migrations/001_init.up.sql b/internal/database/migrations/001_init.up.sql deleted file mode 100644 index e3b052d..0000000 --- a/internal/database/migrations/001_init.up.sql +++ /dev/null @@ -1,8 +0,0 @@ -BEGIN TRANSACTION; -CREATE TABLE IF NOT EXISTS users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - username TEXT UNIQUE NOT NULL, - password TEXT NOT NULL, - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); -COMMIT; diff --git a/internal/database/migrations/002_defaults.down.sql b/internal/database/migrations/002_defaults.down.sql deleted file mode 100644 index 3e38fa2..0000000 --- a/internal/database/migrations/002_defaults.down.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN TRANSACTION; - -DROP TABLE defaults; - -COMMIT; diff --git a/internal/database/migrations/002_defaults.up.sql b/internal/database/migrations/002_defaults.up.sql deleted file mode 100644 index 4bf42b7..0000000 --- a/internal/database/migrations/002_defaults.up.sql +++ /dev/null @@ -1,11 +0,0 @@ -BEGIN TRANSACTION; - -CREATE TABLE IF NOT EXISTS defaults ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - key TEXT UNIQUE NOT NULL, - value TEXT NOT NULL, - description TEXT NOT NULL DEFAULT '', - created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -COMMIT; diff --git a/internal/database/migrations/002_quiz_schema.down.sql b/internal/database/migrations/002_quiz_schema.down.sql deleted file mode 100644 index 8f644e8..0000000 --- a/internal/database/migrations/002_quiz_schema.down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE IF EXISTS questions; diff --git a/internal/database/migrations/002_quiz_schema.up.sql b/internal/database/migrations/002_quiz_schema.up.sql deleted file mode 100644 index 406432b..0000000 --- a/internal/database/migrations/002_quiz_schema.up.sql +++ /dev/null @@ -1,17 +0,0 @@ -CREATE TABLE IF NOT EXISTS questions ( - id INTEGER PRIMARY KEY, - text TEXT NOT NULL, - option1 TEXT, - option2 TEXT, - option3 TEXT, - option4 TEXT, - correct_index INTEGER NOT NULL, - requirement TEXT, - explanation TEXT, - status INTEGER DEFAULT 0, - exam_id INTEGER, - mixed_id INTEGER -); - -CREATE INDEX IF NOT EXISTS idx_questions_exam_id ON questions(exam_id); -CREATE INDEX IF NOT EXISTS idx_questions_mixed_id ON questions(mixed_id); diff --git a/internal/database/migrations/init.go b/internal/database/migrations/init.go deleted file mode 100644 index 754a097..0000000 --- a/internal/database/migrations/init.go +++ /dev/null @@ -1,28 +0,0 @@ -package migrations - -import ( - "log/slog" - - migrate "github.com/rubenv/sql-migrate" -) - -//go:generate go-bindata -o ./migrations.bindata.go -pkg migrations -ignore=\\*.go ./... - -func GetMigrationSource() *migrate.AssetMigrationSource { - return &migrate.AssetMigrationSource{ - Asset: Asset, - AssetDir: AssetDir, - Dir: ".", - } -} - -func RunMigrations(db migrate.Execer, driver string) (int, error) { - source := GetMigrationSource() - n, err := migrate.Exec(db, driver, source, migrate.Up) - if err != nil { - slog.Error("failed to run migrations", "error", err) - return 0, err - } - slog.Info("applied database migrations", "count", n) - return n, nil -} diff --git a/internal/database/migrations/migrations.bindata.go b/internal/database/migrations/migrations.bindata.go deleted file mode 100644 index a3276ee..0000000 --- a/internal/database/migrations/migrations.bindata.go +++ /dev/null @@ -1,267 +0,0 @@ -// Code generated for package migrations by go-bindata DO NOT EDIT. (@generated) -// sources: -// 001_init.down.sql -// 001_init.up.sql -package migrations - -import ( - "bytes" - "compress/gzip" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "time" -) - -func bindataRead(data []byte, name string) ([]byte, error) { - gz, err := gzip.NewReader(bytes.NewBuffer(data)) - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - - var buf bytes.Buffer - _, err = io.Copy(&buf, gz) - clErr := gz.Close() - - if err != nil { - return nil, fmt.Errorf("Read %q: %v", name, err) - } - if clErr != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindataFileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -// Name return file name -func (fi bindataFileInfo) Name() string { - return fi.name -} - -// Size return file size -func (fi bindataFileInfo) Size() int64 { - return fi.size -} - -// Mode return file mode -func (fi bindataFileInfo) Mode() os.FileMode { - return fi.mode -} - -// Mode return file modify time -func (fi bindataFileInfo) ModTime() time.Time { - return fi.modTime -} - -// IsDir return file whether a directory -func (fi bindataFileInfo) IsDir() bool { - return fi.mode&os.ModeDir != 0 -} - -// Sys return file is sys mode -func (fi bindataFileInfo) Sys() interface{} { - return nil -} - -var __001_initDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x72\x75\xf7\xf4\xb3\xe6\x72\x09\xf2\x0f\x50\x08\x76\xf6\x70\xf5\x75\x54\x28\x28\x4d\xca\xc9\x4c\x56\x70\x76\x0c\x76\x76\x74\x71\xb5\xe6\x72\x0e\x72\x75\x0c\x71\x45\x95\xb5\xe6\x72\xf6\xf7\xf5\xf5\x0c\xb1\xe6\x02\x04\x00\x00\xff\xff\x47\x78\xff\x61\x41\x00\x00\x00") - -func _001_initDownSqlBytes() ([]byte, error) { - return bindataRead( - __001_initDownSql, - "001_init.down.sql", - ) -} - -func _001_initDownSql() (*asset, error) { - bytes, err := _001_initDownSqlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "001_init.down.sql", size: 65, mode: os.FileMode(420), modTime: time.Unix(1712559447, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var __001_initUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x92\x41\x6f\x82\x40\x10\x85\xef\xfc\x8a\x77\x53\x53\x2f\x9e\x3d\x2d\x38\x98\x4d\x97\xdd\x16\x96\xb4\x9e\xc8\x2a\xdb\x86\x54\xd1\xe0\xda\xc4\x7f\xdf\xe0\x5a\x28\xa9\x49\x1b\xcf\xf3\xcd\x9b\xf7\x66\x26\xa4\x25\x97\xf3\x20\x4a\x89\x69\x82\x66\xa1\x20\x9c\x8e\xb6\x29\x8e\x9b\x7d\x63\x31\x0e\x00\xa0\x2a\xc1\xa5\xc6\x92\x24\xa5\x4c\xd3\x02\xe1\x0a\x0b\x8a\x59\x2e\x34\x58\x06\xbe\x20\xa9\xb9\x5e\x4d\x2f\x70\xdb\x5d\x9b\x9d\x85\xa6\x57\x8d\x5c\xf2\xe7\x9c\x20\x95\x86\xcc\x85\xf0\xc8\xfa\xd4\xd4\x85\xab\x5a\x86\x27\x94\x69\x96\x3c\x75\x44\x27\x2c\xd5\xcb\x78\x82\x07\x54\xb5\xb3\xcd\xa7\xd9\x62\x34\x43\x69\xce\x23\x2f\xe1\xed\x65\x09\x13\xa2\xb5\x36\xd4\xdf\x34\xd6\x38\x5b\x16\xc6\xfd\x39\x20\x98\xcc\x83\x61\x7a\xb3\x71\xd5\xbe\xbe\x27\x79\x9f\x7a\x68\x67\x67\xde\xeb\xca\x9d\xca\x1b\x7e\x3b\xb1\x99\x47\x1b\x7b\xb0\xc6\x99\xf5\xd6\x22\x54\x4a\x10\x93\xbf\xd1\x98\x89\x8c\x3c\xee\xce\x87\x9b\x13\xcb\x7d\xfd\x3f\x81\xe1\xb1\xee\xde\xa2\x6f\xf0\xb7\x1e\x7f\x6b\x4e\x2f\x0b\xb9\xd6\x22\x25\x33\x9d\xb2\x36\xfb\xdb\x47\xd1\x7f\xd8\xa5\x08\xc4\x2a\x25\xbe\x94\x78\xa4\x55\xd7\x3f\xc1\xb5\x98\x52\x4c\x29\xc9\x88\xb2\x1f\xaf\xd9\x63\xed\x09\x23\x95\x24\x5c\xcf\x83\xaf\x00\x00\x00\xff\xff\x9f\xe9\x59\xfc\xcf\x02\x00\x00") - -func _001_initUpSqlBytes() ([]byte, error) { - return bindataRead( - __001_initUpSql, - "001_init.up.sql", - ) -} - -func _001_initUpSql() (*asset, error) { - bytes, err := _001_initUpSqlBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "001_init.up.sql", size: 719, mode: os.FileMode(420), modTime: time.Unix(1712558242, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -// Asset loads and returns the asset for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func Asset(name string) ([]byte, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) - } - return a.bytes, nil - } - return nil, fmt.Errorf("Asset %s not found", name) -} - -// MustAsset is like Asset but panics when Asset would return an error. -// It simplifies safe initialization of global variables. -func MustAsset(name string) []byte { - a, err := Asset(name) - if err != nil { - panic("asset: Asset(" + name + "): " + err.Error()) - } - - return a -} - -// AssetInfo loads and returns the asset info for the given name. -// It returns an error if the asset could not be found or -// could not be loaded. -func AssetInfo(name string) (os.FileInfo, error) { - cannonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[cannonicalName]; ok { - a, err := f() - if err != nil { - return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) - } - return a.info, nil - } - return nil, fmt.Errorf("AssetInfo %s not found", name) -} - -// AssetNames returns the names of the assets. -func AssetNames() []string { - names := make([]string, 0, len(_bindata)) - for name := range _bindata { - names = append(names, name) - } - return names -} - -// _bindata is a table, holding each asset generator, mapped to its name. -var _bindata = map[string]func() (*asset, error){ - "001_init.down.sql": _001_initDownSql, - "001_init.up.sql": _001_initUpSql, -} - -// AssetDir returns the file names below a certain -// directory embedded in the file by go-bindata. -// For example if you run go-bindata on data/... and data contains the -// following hierarchy: -// data/ -// foo.txt -// img/ -// a.png -// b.png -// then AssetDir("data") would return []string{"foo.txt", "img"} -// AssetDir("data/img") would return []string{"a.png", "b.png"} -// AssetDir("foo.txt") and AssetDir("notexist") would return an error -// AssetDir("") will return []string{"data"}. -func AssetDir(name string) ([]string, error) { - node := _bintree - if len(name) != 0 { - cannonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(cannonicalName, "/") - for _, p := range pathList { - node = node.Children[p] - if node == nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - } - } - if node.Func != nil { - return nil, fmt.Errorf("Asset %s not found", name) - } - rv := make([]string, 0, len(node.Children)) - for childName := range node.Children { - rv = append(rv, childName) - } - return rv, nil -} - -type bintree struct { - Func func() (*asset, error) - Children map[string]*bintree -} - -var _bintree = &bintree{nil, map[string]*bintree{ - "001_init.down.sql": &bintree{_001_initDownSql, map[string]*bintree{}}, - "001_init.up.sql": &bintree{_001_initUpSql, map[string]*bintree{}}, -}} - -// RestoreAsset restores an asset under the given directory -func RestoreAsset(dir, name string) error { - data, err := Asset(name) - if err != nil { - return err - } - info, err := AssetInfo(name) - if err != nil { - return err - } - err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) - if err != nil { - return err - } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) - if err != nil { - return err - } - err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) - if err != nil { - return err - } - return nil -} - -// RestoreAssets restores an asset under the given directory recursively -func RestoreAssets(dir, name string) error { - children, err := AssetDir(name) - // File - if err != nil { - return RestoreAsset(dir, name) - } - // Dir - for _, child := range children { - err = RestoreAssets(dir, filepath.Join(name, child)) - if err != nil { - return err - } - } - return nil -} - -func _filePath(dir, name string) string { - cannonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) -} diff --git a/internal/database/repos/questions.go b/internal/database/repos/questions.go new file mode 100644 index 0000000..d9978a4 --- /dev/null +++ b/internal/database/repos/questions.go @@ -0,0 +1,16 @@ +package repos + +import "demoon/internal/models" + +type QuestionsRepo interface { + DBGetQuestion(id string) (*models.Question, error) +} + +func (p *Provider) DBGetQuestion(id string) (*models.Question, error) { + var question models.Question + err := p.db.Get(&question, "SELECT * FROM questions WHERE id = ?", id) + if err != nil { + return nil, err + } + return &question, nil +} |