diff --git a/README.md b/README.md index 9a2b914..2060134 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,71 @@ # repo +This module is mainly an exercise with generics. Although it is a fully functional repository for any Go structs. + +Might be useful for pet-projects and like. + +Example usage. + +```go +import ( + "code.uint32.ru/tiny/repo" + _ "github.com/mattn/go-sqlite3" +) + +type My struct { + A string + B int +} + +func main() { + db, err := sql.Open("sqlite3", "test.db") + if err != nil { + panic(err) + } + + defer db.Close() + + ctx := context.Background() + + // init repository for our type "My" + r, err := repo.OpenOrCreate[My](ctx, db, "my_test_table") + if err != nil { + panic(err) + } + + first := &My{ + A: "hello", + B: 42, + } + + if err := r.Create(ctx, "first_record", first); err != nil { + panic(err) + } + + duplicate, err = r.Read(ctx, "first_record") + if err != nil { + panic(err) + } + + fmt.Printf("Type: %T, Value: %+v", duplicate) +} +``` + +The interface is a plain CRUD. +```go +type Repo[T any] interface { + // Create inserts object into repository table. If id already exists + // in the database it is an error. + Create(ctx context.Context, id string, v *T) error + // Read returns object with specified id or ErrNotFound + Read(ctx context.Context, id string) (*T, error) + // Update updates object with id. + Update(ctx context.Context, id string, v *T) error + // Delete performs soft-delete (actually marks object as unavailable). + Delete(ctx context.Context, id string) error + // Purge actually deletes database record with id. + Purge(ctx context.Context, id string) error +} +``` + + diff --git a/test/example.go b/test/example.go new file mode 100644 index 0000000..4f7d8f9 --- /dev/null +++ b/test/example.go @@ -0,0 +1,49 @@ +package main + +import ( + "context" + "database/sql" + "fmt" + + "code.uint32.ru/tiny/repo" + _ "github.com/mattn/go-sqlite3" +) + +type My struct { + A string + B int +} + +func main() { + db, err := sql.Open("sqlite3", "test.db") + if err != nil { + panic(err) + } + + defer db.Close() + + ctx := context.Background() + + // init repository for our type "My" + r, err := repo.OpenOrCreate[My](ctx, db, "my_test_table") + if err != nil { + panic(err) + } + + first := &My{ + A: "hello", + B: 42, + } + + if err := r.Create(ctx, "first_record", first); err != nil { + panic(err) + } + + duplicate, err := r.Read(ctx, "first_record") + if err != nil { + panic(err) + } + + // prints Type: *main.My, Value: &{A:hello B:42} + fmt.Printf("Type: %T, Value: %+v\n", duplicate, duplicate) +} diff --git a/test/repo_test.go b/test/repo_test.go index 3bbc4da..3b40644 100644 --- a/test/repo_test.go +++ b/test/repo_test.go @@ -1,4 +1,4 @@ -package repo_test +package main import ( "context" @@ -15,11 +15,6 @@ import ( "code.uint32.ru/tiny/repo" ) -type My struct { - A string - B int -} - func TestSqlite3(t *testing.T) { db, err := sql.Open("sqlite3", "test.db") if err != nil {