From 15e4e893b1af9ca93f40180edb34794553acdbe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9E=D0=BB=D0=B5=D0=B3=20=D0=91=D0=BE=D1=80=D0=BE=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Mon, 26 Jan 2026 17:44:54 +0200 Subject: [PATCH] working commit --- .gitignore | 1 + Makefile.am | 2 +- Makefile.in | 2 +- app/database/database.go | 12 ----- app/descr/file.go | 14 ++++++ app/handler/file.go | 2 + app/maindb/file.go | 101 +++++++++++++++++++++++++++++++++++++++ app/maindb/file_test.go | 48 +++++++++++++++++++ app/maindb/maindb.go | 48 +++++++++++++++++++ app/maindb/schema.go | 17 +++++++ app/operator/file.go | 5 ++ app/operator/operator.go | 8 ++-- go.mod | 4 +- go.sum | 13 +++++ pkg/auxtool/randstr.go | 18 +++++++ pkg/auxtool/unixnow.go | 10 ++++ pkg/auxuuid/uuid.go | 11 +++++ pkg/client/client.go | 5 +- 18 files changed, 300 insertions(+), 21 deletions(-) delete mode 100644 app/database/database.go create mode 100644 app/descr/file.go create mode 100644 app/maindb/file.go create mode 100644 app/maindb/file_test.go create mode 100644 app/maindb/maindb.go create mode 100644 app/maindb/schema.go create mode 100644 pkg/auxtool/randstr.go create mode 100644 pkg/auxtool/unixnow.go create mode 100644 pkg/auxuuid/uuid.go diff --git a/.gitignore b/.gitignore index 65295d6..f0715eb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ config.log mstored cmd/mstored/mstored cmd/mstorectl/mstorectl +*.db diff --git a/Makefile.am b/Makefile.am index 42cb3a0..757bed1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,5 +21,5 @@ format: done clean-local: - $(FIND) $(CWD) -name '*~' | $(XARGS) rm -f + $(FIND) $(CWD) -name '*~' | $(XARGS) rm -f rm -rf autom4te.cache diff --git a/Makefile.in b/Makefile.in index cb3a19b..e841248 100644 --- a/Makefile.in +++ b/Makefile.in @@ -732,7 +732,7 @@ format: done clean-local: - $(FIND) $(CWD) -name '*~' | $(XARGS) rm -f + $(FIND) $(CWD) -name '*~' | $(XARGS) rm -f rm -rf autom4te.cache # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/app/database/database.go b/app/database/database.go deleted file mode 100644 index 46a0f98..0000000 --- a/app/database/database.go +++ /dev/null @@ -1,12 +0,0 @@ -package database - -type DatabaseParams struct { -} - -type Database struct { -} - -func NewDatabase(params *DatabaseParams) (*Database, error) { - var err error - return &Database{}, err -} diff --git a/app/descr/file.go b/app/descr/file.go new file mode 100644 index 0000000..76d821e --- /dev/null +++ b/app/descr/file.go @@ -0,0 +1,14 @@ +package descr + +type File struct { + ID string `db:"id" json:"id,omitempty" yaml:"id,omitempty"` + Collection string `db:"collection" json:"collection,omitempty" yaml:"collection,omitempty"` + Name string `db:"name" json:"name,omitempty" yaml:"name,omitempty"` + Checksum string `db:"checksum" json:"checksum,omitempty" yaml:"checksum,omitempty"` + Size int64 `db:"size" json:"size,omitempty" yaml:"size,omitempty"` + CreatedAt string `db:"created_at" json:"createdAt,omitempty" yaml:"createdAt,omitempty"` + UpdatedAt string `db:"updated_at" json:"updatedAt,omitempty" yaml:"updatedAt,omitempty"` + CreatedBy string `db:"created_by" json:"createdBy,omitempty" yaml:"createdBy,omitempty"` + UpdatedBy string `db:"updated_by" json:"updatedBy,omitempty" yaml:"updatedBy,omitempty"` +} + diff --git a/app/handler/file.go b/app/handler/file.go index 20d7d2e..492a05d 100644 --- a/app/handler/file.go +++ b/app/handler/file.go @@ -14,6 +14,8 @@ func (hand *Handler) FileExists(rctx *router.Context) { } hand.logg.Debugf("filepath: %s", filepath) + + code, _, _ := hand.oper.FileExists(params) rctx.SetStatus(code) } diff --git a/app/maindb/file.go b/app/maindb/file.go new file mode 100644 index 0000000..cbffab3 --- /dev/null +++ b/app/maindb/file.go @@ -0,0 +1,101 @@ +package maindb + +import ( + "mstore/app/descr" +) + +func (db *Database) InsertFile(file *descr.File) error { + var err error + request := `INSERT INTO file(id, collection, name, checksum, size, created_at, updated_at, created_by, updated_by) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)` + _, err = db.db.Exec(request, file.ID, file.Collection, file.Name, file.Checksum, file.Size, + file.CreatedAt, file.UpdatedAt, file.CreatedBy, file.UpdatedBy) + if err != nil { + return err + } + return err +} + +func (db *Database) UpdateFileByID(fileID string, file *descr.File) error { + var err error + request := `UPDATE file SET id = $1, collection = $2, name = $3, checksum = $4, + size = $5, updated_at = $6, created_by = $7, updated_by = $8 + WHERE id = $9` + _, err = db.db.Exec(request, file.ID, file.Collection, file.Name, file.Checksum, + file.Size, file.UpdatedAt, file.CreatedBy, file.UpdatedBy, fileID) + if err != nil { + return err + } + return err +} + +func (db *Database) ListFilesByCollection(collection string) ([]descr.File, error) { + var err error + request := `SELECT * FROM file WHERE collection = $1 ORDER BY collection, name` + res := make([]descr.File, 0) + err = db.db.Select(&res, request, collection) + if err != nil { + return res, err + } + return res, err +} + +func (db *Database) ListAllFiles() ([]descr.File, error) { + var err error + request := `SELECT * FROM file ORDER BY collection, name` + res := make([]descr.File, 0) + err = db.db.Select(&res, request) + if err != nil { + return res, err + } + return res, err +} + +func (db *Database) GetFileByID(fileID int64) (bool, *descr.File, error) { + var err error + var res *descr.File + var exists bool + request := `SELECT * FROM file WHERE id = $1 LiMIT 1` + dbRes := make([]descr.File, 0) + err = db.db.Select(&dbRes, request, fileID) + if err != nil { + return exists, res, err + } + if len(dbRes) == 0 { + return exists, res, err + } + exists = true + res = &dbRes[0] + return exists, res, err +} + +func (db *Database) GetFileByCollection(collection, name string) (bool, *descr.File, error) { + var err error + var res *descr.File + var exists bool + request := `SELECT * FROM file + WHERE collection = $1 AND name = $2 LIMIT 1` + dbRes := make([]descr.File, 0) + err = db.db.Select(&dbRes, request, collection, name) + if err != nil { + return exists, res, err + } + + if len(dbRes) == 0 { + return false, res, err + } + exists = true + res = &dbRes[0] + return exists, res, err +} + +func (db *Database) DeleteFileByCollection(collection, name string) error { + var err error + + request := `DELETE FROM file WHERE collection = $1 AND name = $2` + _, err = db.db.Exec(request, collection, name) + if err != nil { + return err + } + return err +} diff --git a/app/maindb/file_test.go b/app/maindb/file_test.go new file mode 100644 index 0000000..6a25824 --- /dev/null +++ b/app/maindb/file_test.go @@ -0,0 +1,48 @@ +package maindb + + + +import ( + "testing" + + "mstore/app/descr" + "mstore/pkg/auxtool" + "mstore/pkg/auxuuid" + + "github.com/stretchr/testify/require" +) + +func TestFile(t *testing.T) { + var err error + + dbDir := t.TempDir() + db := NewDatabase(dbDir) + + err = db.OpenDatabase() + require.NoError(t, err) + + err = db.InitDatabase() + require.NoError(t, err) + + id := auxuuid.NewUUID() + timenow := auxtool.TimeNow() + creator := "some" + collection := "foo" + newFile := &descr.File{ + ID: id, + Collection: "foo" , + Name: "bare", + CreatedAt: timenow, + UpdatedAt: timenow, + CreatedBy: creator, + UpdatedBy: creator, + } + + err = db.InsertFile(newFile) + require.NoError(t, err) + + files, err := db.ListFilesByCollection(collection) + require.NoError(t, err) + require.Equal(t, len(files), 1) + require.Equal(t, files[0].ID, id) +} diff --git a/app/maindb/maindb.go b/app/maindb/maindb.go new file mode 100644 index 0000000..4bb0296 --- /dev/null +++ b/app/maindb/maindb.go @@ -0,0 +1,48 @@ +package maindb + +import ( + "fmt" + "path/filepath" + + "mstore/app/logger" + + "github.com/jmoiron/sqlx" + _ "github.com/mattn/go-sqlite3" +) + + +type Database struct { + datapath string + log *logger.Logger + db *sqlx.DB +} + +func NewDatabase(datapath string) *Database { + return &Database{ + datapath: datapath, + log: logger.NewLogger("maindb"), + } +} + +func (db *Database) OpenDatabase() error { + var err error + dbPath := filepath.Join(db.datapath, "mstore.db") + db.db, err = sqlx.Open("sqlite3", fmt.Sprintf("%s?cache=shared&mode=rwc&_journal_mode=WAL", dbPath)) + if err != nil { + return fmt.Errorf("Open database error: %v", err) + } + err = db.db.Ping() + if err != nil { + return fmt.Errorf("Ping database error: %v", err) + } + return err +} + +func (db *Database) InitDatabase() error { + var err error + _, err = db.db.Exec(schema) + if err != nil { + return fmt.Errorf("Init database error: %v", err) + } + return err +} diff --git a/app/maindb/schema.go b/app/maindb/schema.go new file mode 100644 index 0000000..8940297 --- /dev/null +++ b/app/maindb/schema.go @@ -0,0 +1,17 @@ +package maindb + +const schema = ` + CREATE TABLE IF NOT EXISTS file ( + id VARCHAR(255) NOT NULL, + collection VARCHAR(255) NOT NULL, + name VARCHAR(255) NOT NULL, + checksum VARCHAR(255) NOT NULL, + size INTEGER, + created_at VARCHAR(255) NOT NULL, + updated_at VARCHAR(255) NOT NULL, + created_by VARCHAR(255) NOT NULL, + updated_by VARCHAR(255) NOT NULL + ); + CREATE UNIQUE INDEX IF NOT EXISTS file_index + ON file(collection, name); +` diff --git a/app/operator/file.go b/app/operator/file.go index 73887a6..cec8213 100644 --- a/app/operator/file.go +++ b/app/operator/file.go @@ -3,6 +3,7 @@ package operator import ( "io" "net/http" + "path" ) // File exists @@ -15,6 +16,10 @@ type FileExistsResult struct{} func (oper *Operator) FileExists(param *FileExistsParams) (int, *FileExistsResult, error) { var err error + + filename := path.Base(param.Filepath) + dirname := path.Dir(filepath) + res := &FileExistsResult{} code := http.StatusOK return code, res, err diff --git a/app/operator/operator.go b/app/operator/operator.go index 1fb0e3d..692b1df 100644 --- a/app/operator/operator.go +++ b/app/operator/operator.go @@ -1,21 +1,21 @@ package operator import ( - "mstore/app/database" + "mstore/app/maindb" ) type OperatorParams struct { - Database *database.Database + MainDB *database.Database } type Operator struct { - db *database.Database + maindb *main.Database } func NewOperator(params *OperatorParams) (*Operator, error) { var err error oper := &Operator{ - db: params.Database, + db: params.MainDB, } return oper, err } diff --git a/go.mod b/go.mod index 98cde8b..24e5008 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module mstore go 1.24.4 require ( + github.com/google/uuid v1.6.0 + github.com/jmoiron/sqlx v1.4.0 + github.com/mattn/go-sqlite3 v1.14.33 github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.11.1 ) @@ -14,4 +17,3 @@ require ( github.com/spf13/pflag v1.0.9 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - diff --git a/go.sum b/go.sum index 5352f4f..ae0b668 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,21 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= diff --git a/pkg/auxtool/randstr.go b/pkg/auxtool/randstr.go new file mode 100644 index 0000000..5a65306 --- /dev/null +++ b/pkg/auxtool/randstr.go @@ -0,0 +1,18 @@ +/* + * Copyright 2019 Oleg Borodin + */ + +package auxtool + +import ( + "math/rand" +) + +func RandomString(n int) string { + const letters = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + arr := make([]byte, n) + for i := range arr { + arr[i] = letters[rand.Intn(len(letters))] + } + return string(arr) +} diff --git a/pkg/auxtool/unixnow.go b/pkg/auxtool/unixnow.go new file mode 100644 index 0000000..7259dbf --- /dev/null +++ b/pkg/auxtool/unixnow.go @@ -0,0 +1,10 @@ +package auxtool + +import ( + "time" +) + +func TimeNow() string { + return time.Now().Format(time.RFC3339) + +} diff --git a/pkg/auxuuid/uuid.go b/pkg/auxuuid/uuid.go new file mode 100644 index 0000000..ebccb21 --- /dev/null +++ b/pkg/auxuuid/uuid.go @@ -0,0 +1,11 @@ +package auxuuid + +import ( + "github.com/google/uuid" +) + +const ZeroUUID = "00000000-0000-0000-0000-000000000000" + +func NewUUID() string { + return uuid.New().String() +} diff --git a/pkg/client/client.go b/pkg/client/client.go index a5e0a10..eadb2ac 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -1,9 +1,10 @@ package client + type Client struct { } func (cli *Client) FileExists(path string) (bool, error) { - //reqPath = fmt.Sprintf("/v3/api/file/%s", path) - //request, err := http.NewRequest("HEAD", reqPath, nil) + //reqPath = fmt.Sprintf("/v3/api/file/%s", path) + //request, err := http.NewRequest("HEAD", reqPath, nil) }