summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrail Finder <wohilas@gmail.com>2025-04-05 15:04:15 +0300
committerGrail Finder <wohilas@gmail.com>2025-04-05 15:04:15 +0300
commit8bc7544e8933d64abc2610a265f37fe13b5767d5 (patch)
treeddcb10ff89723d0c490f6c1e781928ae89666b25
parent287da7acfa71ff07c52035a437209022b4ddc5d6 (diff)
Feat: question repo
-rw-r--r--Makefile2
-rw-r--r--demoon.dbbin0 -> 36864 bytes
-rw-r--r--go.mod3
-rw-r--r--go.sum7
-rw-r--r--internal/database/migrations/001_init.down.sql4
-rw-r--r--internal/database/migrations/001_init.up.sql8
-rw-r--r--internal/database/migrations/002_defaults.down.sql5
-rw-r--r--internal/database/migrations/002_defaults.up.sql11
-rw-r--r--internal/database/migrations/002_quiz_schema.down.sql1
-rw-r--r--internal/database/migrations/002_quiz_schema.up.sql17
-rw-r--r--internal/database/migrations/init.go28
-rw-r--r--internal/database/migrations/migrations.bindata.go267
-rw-r--r--internal/database/repos/questions.go16
13 files changed, 23 insertions, 346 deletions
diff --git a/Makefile b/Makefile
index 71d46fa..711c5be 100644
--- a/Makefile
+++ b/Makefile
@@ -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
new file mode 100644
index 0000000..1536d17
--- /dev/null
+++ b/demoon.db
Binary files differ
diff --git a/go.mod b/go.mod
index 42e9089..4aa15e0 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 32f5761..05797b4 100644
--- a/go.sum
+++ b/go.sum
@@ -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
+}