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
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
|
|
}
|