You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
1.9 KiB
Go

package main
import (
"fmt"
"log"
)
//
// Database
//
type QueryResult interface {
Scan(v any) error
}
type Database interface {
Get(query string, values ...any) QueryResult
}
//
// Library
//
// DatabaseTable represents a typed database table with
type DatabaseTable[T any] struct {
Table string
IdKey string
GetIdPtr func(entry T) *string
}
func (t DatabaseTable[T]) RefForId(id string) DatabaseRef[T] {
return DatabaseRef[T]{id}
}
func (t DatabaseTable[T]) RefForValue(v T) DatabaseRef[T] {
return t.RefForId(*t.GetIdPtr(v))
}
type DatabaseRef[T any] struct{ Id string }
func DatabaseRead[T any](db Database, table DatabaseTable[T], ref DatabaseRef[T]) (*T, error) {
query := fmt.Sprintf(`select * from %s where %s = ?`, table.Table, table.IdKey)
result := db.Get(query, ref.Id)
var value T
if err := result.Scan(&value); err != nil {
return nil, err
}
return &value, nil
}
// DatabaseWrite creates a new entry in the db using the provided id in the value, this returns a typed ref to the db entry
func DatabaseWrite[T any](db Database, table DatabaseTable[T], value *T) (DatabaseRef[T], error) {
panic("not implemented")
}
// DatabaseCreate creates a new entry in the db retrieving the new generated id and returning it as a typed ref
func DatabaseCreate[T any](db Database, table DatabaseTable[T], value *T) (DatabaseRef[T], error) {
panic("not implemented")
}
//
// Client code
//
type User struct {
Username string
FirstName string
LastName string
}
var UsersTable = DatabaseTable[User]{
Table: "users",
IdKey: "username",
GetIdPtr: func(u User) *string {
return &u.Username
},
}
func _(db Database) error {
u1 := &User{"j.smith", "John", "Smith"}
log.Println(u1)
ref1, err := DatabaseWrite(db, UsersTable, u1)
if err != nil {
return err
}
u2, err := DatabaseRead(db, UsersTable, ref1)
if err != nil {
return err
}
log.Println(u2)
return nil
}