repo

package module
v0.0.0-...-4a0df3e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2023 License: MIT Imports: 4 Imported by: 2

README

repo

Repositories for content - for now, SQLite.

Documentation

Overview

Package repo provides a repository model that assumes the use of SQL. Enumeration [DB_type] specifies the type of SQL database, which for¨ now is always SQLite.

The (as yet unimplemented) goal is to use generics to provide a CRUD-style interface for every "interesting", persistent struct.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DBBackups

type DBBackups interface {
	MoveToBackup() (string, error)
	CopyToBackup() (string, error)
	RestoreFromMostRecentBackup() (string, error)
}

DBBackups methods work with locations, whose type (filepath, dir path, or URI/URL) and naming convention (incorporating date & time) are determined by the implementation for each DB. Methods exist to move DB to, copy DB to, or restore DB from a location. Each method returns the location of the new backup or restored-from backup.

It defines methods on a (probably empty) singleton that selects (for now: only) SQLite implementations of this interface.

At the CLI?

  • sqlite3 my_database.sq3 ".backup 'backup_file.sq3'"
  • sqlite3 m_database.sq3 ".backup m_database.sq3.bak"
  • sqlite3 my_database .backup > my_database.back

.

type DBEntity

type DBEntity interface {
	Handle() *sql.DB    // (noun) the handle to the DB
	Type() D.DB_type    // DB_SQLite ("sqlite", equiv.to "sqlite3")
	Path() string       // file/URL (or dir/URL, if uses multiple files)
	IsURL() bool        // false for a local SQLite file
	IsSingleFile() bool // true for SQLite
}

DBEntity provides realization-related operations for databases.

It defines methods on a (probably empty) singleton that selects (for now: only) SQLite implementations of this interface. .

type DBGetting

type DBGetting interface {
	OpenAtPath(string) (string, error)
	NewAtPath(string) (string, error)
	OpenExistingAtPath(string) (string, error)
}

DBGetting has methods to create / find / open databases.

The default action is to call OpenAtPath, which then selects one of the other two.

It defines methods on a (probably empty) singleton that selects (for now: only) SQLite implementations of this interface.

.

type DBImplementation

type DBImplementation interface {
	DBImplementationName() D.DB_type // "sqlite"
}

type GenericRepo

type GenericRepo[T any] interface {
	Create(T) T
	GetAll() []T
	GetByID(uint) (T, error)
	UpdateByID(uint, T) (T, error)
	DeleteByID(uint) (bool, error)
	GetSome(string) []T
}

type QueryRunner

type QueryRunner interface {
	RunQuery0(*RU.QuerySpec) (any, error)   // ie. Exec()
	RunQuery1(*RU.QuerySpec) (any, error)   // One row, like by_ID
	RunQueryN(*RU.QuerySpec) ([]any, error) // Multiple rows
}

QueryRunner runs queries!

https://github.com/golang/go/wiki/SQLInterface

  • ExecContext is used when no rows are returned ("0")
  • QueryContext is used for retrieving rows ("N")
  • QueryRowContext is used where only a single row is expected ("1")

.

type RepoAppTables

type RepoAppTables interface {
	// SetAppTables specifies the schemata of the specified app's
	// tables, which this interface creates and/or manages. Multiple
	// calls, whether with tables previously specified or not before
	// seen do not conflict; if a table name is repeated but with a
	// different schema, the result is undefined.
	SetAppTables(string, []RU.TableDescriptor) error
	// EmptyAllTables deletes (app-level) data from the app's tables
	// but does not delete any tables (i.e. no DROP TABLE are done).
	EmptyAppTables() error
	// CreateTables creates the app's tables per already-supplied
	// schema(ta); if the tables exist, they are emptied of data.
	CreateAppTables() error
}

RepoAppTables is table-related methods for a specified app's schema. The app name is case-insensitive, and used as all lower case, and prefixed to table names as "appname_". If the app name is left blank (""), a default namespace is used and no prefix is added to table names.

type SessionLifecycle

type SessionLifecycle interface {
	// Open is called on an existing repo file, and can be called
	// multiple times in a sessions, so it should not pragma-style
	// initialization; however, options passed in the connection
	// string (such as SQLite's "...?foreign_keys=on") are kosher.
	Open() error
	// TODO:? return it, for use or understanding
	// InitString() string
	// IsOpen pings the DB as a health check.
	IsOpen() bool
	// Verify runs app-level sanity & consistency checks (but things
	// like foreign key integtrity should be delegated to DB setup).
	Verify() error
	Flush() error
	// Close remembers the path (like os.File does).
	Close() error
}

SessionLifecycle is session lifecycle operations for databases.

Example

ExampleSessionLifecycle tests (for SQLite) the interface:

  • Open() error
  • IsOpen() bool
  • Verify() error
  • Flush() error
  • Close() error

.

package main

import (
	"fmt"
	RS "github.com/fbaube/reposqlite"
	"io/ioutil"
	"os"
)

func main() {
	var F *os.File
	// S implements repo.SessionLifecycle
	var S *RS.SqliteRepo
	var e error
	// func TempFile(dir, pattern string) (f *os.File, err error)
	F, e = ioutil.TempFile("", "*.db")
	if e != nil {
		panic(e)
	}
	// We would like to print out the path, but we
	// can't, because it is random but the output
	// has to be matched for the test to pass.
	// fmt.Println("Path:", F.Name())
	F.Close()

	// Now the test begins.
	S, e = RS.OpenRepoAtPath(F.Name())
	if e != nil {
		panic(e)
	}
	fmt.Printf("IsOpen #1: %t\n", S.IsOpen())
	e = S.Verify()
	if e != nil {
		panic(e)
	}
	e = S.Close()
	if e != nil {
		panic(e)
	}
	fmt.Printf("IsOpen #2: %t\n", S.IsOpen())
}
Output:

IsOpen #1: true
IsOpen #2: false

type SimpleRepo

type SimpleRepo interface {
	DBImplementation // "sqlite"
	DBEntity         // path, open, isOpen, etc.
	DBBackups        // cp, mv, restoreFrom
	SessionLifecycle // open, close, etc.
	StatementBuilder // using struct RU.QuerySpec
	QueryRunner      // return 0,1,N rows
}

SimpleRepo can be fully described by

  1. a filepath or a URL, which may be either relative or absolute, plus
  2. the ImplementationName

Each field in the struct can be a ptr, and all can (for example) point to the same single object.

A SimpleRepo is expected to implement DBBackups. .

type StatementBuilder

type StatementBuilder interface {
	BuildQueryStmt(*RU.QuerySpec) (string, error)
	BuildCreateTableStmt(*RU.TableDescriptor) (string, error)
}

type TypedRepo

type TypedRepo[T any] struct {
	// contains filtered or unexported fields
}

func (*TypedRepo[T]) Create

func (r *TypedRepo[T]) Create(t T)

func (*TypedRepo[T]) Get

func (r *TypedRepo[T]) Get(id uint) (*T, error)

type TypedRepoer

type TypedRepoer[T any] interface {
	Add(T) (int, error)
	Mod(T) error
	Del(T) error
	GetByID(int) error
	ModByID(int) error
	DelByID(int) error
	GetAll() ([]T, []error)
	AddAll([]T) ([]int, []error)
	ModAll([]T) ([]T, []error)
	DelAll([]T) []error
	DelAllByID([]int) []error
}

TypedRepoer does

  • Get (Retrieve,find,list)
  • Add (Create,save,store)
  • Mod (Update,modify)
  • Del (Delete,remove)

type UntypedRepoer

type UntypedRepoer interface {
	GetByID() (any, error)
	Add(any) (int, error)
	ModByID(any) error
}

type Zork

type Zork struct {
	I int
	S string
}

func (*Zork) GetByID

func (p *Zork) GetByID(id int) Zork

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL