commit 80788f044129b600cc535d9c88c2ec192a4d8ceb
parent 46241dbcdbebb9a14b309a95fc05d91f1de60d17
Author: lash <dev@holbrook.no>
Date: Fri, 30 Aug 2024 04:19:28 +0100
WIP add postgres backend
Diffstat:
7 files changed, 152 insertions(+), 17 deletions(-)
diff --git a/db/db.go b/db/db.go
@@ -1,6 +1,8 @@
package db
import (
+ "context"
+
"git.defalsify.org/vise.git/lang"
)
@@ -12,9 +14,9 @@ const (
)
type Db interface {
- Connect(connStr string) error
- Get(key []byte) ([]byte, error)
- Put(key []byte, val []byte) error
+ Connect(ctx context.Context, connStr string) error
+ Get(ctx context.Context, key []byte) ([]byte, error)
+ Put(ctx context.Context, key []byte, val []byte) error
}
func ToDbKey(typ uint8, s string, l *lang.Language) []byte {
diff --git a/db/fs.go b/db/fs.go
@@ -1,6 +1,7 @@
package db
import (
+ "context"
"fmt"
"io/ioutil"
"os"
@@ -12,7 +13,7 @@ type FsDb struct {
dir string
}
-func(fds *FsDb) Connect(connStr string) error {
+func(fdb *FsDb) Connect(ctx context.Context, connStr string) error {
fi, err := os.Stat(connStr)
if err != nil {
return err
@@ -20,16 +21,12 @@ func(fds *FsDb) Connect(connStr string) error {
if !fi.IsDir() {
return fmt.Errorf("fs db %s is not a directory", connStr)
}
- fds.dir = connStr
+ fdb.dir = connStr
return nil
}
-func(fsd *FsDb) pathFor(key []byte) string{
- return path.Join(fsd.dir, string(key))
-}
-
-func(fsd *FsDb) Get(key []byte) ([]byte, error) {
- fp := fsd.pathFor(key)
+func(fdb *FsDb) Get(ctx context.Context, key []byte) ([]byte, error) {
+ fp := fdb.pathFor(key)
f, err := os.Open(fp)
if err != nil {
return nil, err
@@ -42,7 +39,11 @@ func(fsd *FsDb) Get(key []byte) ([]byte, error) {
return b, nil
}
-func(fsd *FsDb) Put(key []byte, val []byte) error {
- fp := fsd.pathFor(key)
+func(fdb *FsDb) Put(ctx context.Context, key []byte, val []byte) error {
+ fp := fdb.pathFor(key)
return ioutil.WriteFile(fp, val, 0600)
}
+
+func(fdb *FsDb) pathFor(key []byte) string{
+ return path.Join(fdb.dir, string(key))
+}
diff --git a/db/fs_test.go b/db/fs_test.go
@@ -2,32 +2,34 @@ package db
import (
"bytes"
+ "context"
"io/ioutil"
"testing"
)
func TestPutGet(t *testing.T) {
+ ctx := context.Background()
d, err := ioutil.TempDir("", "vise-db-*")
if err != nil {
t.Fatal(err)
}
db := &FsDb{}
- err = db.Connect(d)
+ err = db.Connect(ctx, d)
if err != nil {
t.Fatal(err)
}
- err = db.Put([]byte("foo"), []byte("bar"))
+ err = db.Put(ctx, []byte("foo"), []byte("bar"))
if err != nil {
t.Fatal(err)
}
- v, err := db.Get([]byte("foo"))
+ v, err := db.Get(ctx, []byte("foo"))
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(v, []byte("bar")) {
t.Fatalf("expected value 'bar', found '%s'", v)
}
- _, err = db.Get([]byte("bar"))
+ _, err = db.Get(ctx, []byte("bar"))
if err == nil {
t.Fatal("expected get error for key 'bar'")
}
diff --git a/db/pg.go b/db/pg.go
@@ -0,0 +1,87 @@
+package db
+
+import (
+ "context"
+ "fmt"
+// "errors"
+
+ "github.com/jackc/pgx/v5/pgxpool"
+// pgx "github.com/jackc/pgx/v5"
+)
+
+type PgDb struct {
+ conn *pgxpool.Pool
+ schema string
+}
+
+func NewPgDb() *PgDb {
+ return &PgDb{
+ schema: "public",
+ }
+}
+
+func(pdb *PgDb) WithSchema(schema string) *PgDb {
+ pdb.schema = schema
+ return pdb
+}
+
+func(pdb *PgDb) Connect(ctx context.Context, connStr string) error {
+ var err error
+ conn, err := pgxpool.New(ctx, connStr)
+ if err != nil {
+ return err
+ }
+ pdb.conn = conn
+ return pdb.prepare(ctx)
+}
+
+func(pdb *PgDb) prepare(ctx context.Context) error {
+ tx, err := pdb.conn.Begin(ctx)
+ if err != nil {
+ tx.Rollback(ctx)
+ return err
+ }
+ query := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s.kv_vise_domain (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(256) NOT NULL
+ );
+`, pdb.schema)
+ _, err = tx.Exec(ctx, query)
+ if err != nil {
+ tx.Rollback(ctx)
+ return err
+ }
+
+ query = fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s.kv_vise (
+ id SERIAL NOT NULL,
+ domain_id INT NOT NULL,
+ key VARCHAR(256) NOT NULL,
+ value BYTEA NOT NULL,
+ constraint fk_domain
+ FOREIGN KEY (domain_id)
+ REFERENCES %s.kv_vise_domain(id)
+ );
+`, pdb.schema, pdb.schema)
+ _, err = tx.Exec(ctx, query)
+ if err != nil {
+ tx.Rollback(ctx)
+ return err
+ }
+
+ err = tx.Commit(ctx)
+ if err != nil {
+ //if !errors.Is(pgx.ErrTxCommitRollback) {
+ tx.Rollback(ctx)
+ return err
+ //}
+ }
+ return nil
+}
+
+func(pdb *PgDb) Put(ctx context.Context, key []byte, val []byte) error {
+ return nil
+}
+
+func(pdb *PgDb) Get(ctx context.Context, key []byte) ([]byte, error) {
+ return nil, nil
+}
diff --git a/db/pg_test.go b/db/pg_test.go
@@ -0,0 +1,15 @@
+package db
+
+import (
+ "context"
+ "testing"
+)
+
+func TestCreate(t *testing.T) {
+ db := NewPgDb().WithSchema("govise")
+ ctx := context.Background()
+ err := db.Connect(ctx, "postgres://vise:esiv@localhost:5432/visedb")
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/go.mod b/go.mod
@@ -10,7 +10,14 @@ require (
)
require (
+ github.com/jackc/pgpassfile v1.0.0 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+ github.com/jackc/pgx/v5 v5.6.0 // indirect
+ github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
github.com/x448/float16 v0.8.4 // indirect
+ golang.org/x/crypto v0.17.0 // indirect
+ golang.org/x/sync v0.1.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 // indirect
)
diff --git a/go.sum b/go.sum
@@ -4,14 +4,35 @@ github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmE
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY=
+github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY=
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 h1:8d9/fdTG0kn/B7NNGV1BsEyvektXFAbkMsTZS2sFSCc=
gopkg.in/leonelquinteros/gotext.v1 v1.3.1/go.mod h1:X1WlGDeAFIYsW6GjgMm4VwUwZ2XjI7Zan2InxSUQWrU=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=