persistence
A dialect agnostic database driver extension to provide simplified query and transaction execution
Created for the sake of learning and memes
Features
- Off the shelf support for sqlite and postgres
- Execute raw queries/statements
- Transactions
- Primary/Foreign/Composite Primary key support
- Support for Eagerly loading items which require joins
- Support for insertion of items joined to the primary item without requiring multiple calls
- Optionally update items with their current primary keys on insert/update
- Write only data (more on this later)
- Support for multiple dialects (requires drivers to be written)
- Aims to be simple to use
Connecting
Open the connection to your database and specify which driver you will be using. Currently only postgres the postgres driver is written.
Example
import (
_ "gitlab.com/cosban/persistence/postgres"
"gitlab.com/cosban/persistence"
)
func main() {
var connectionTemplate = "postgres://%s:%s@%s:%d/%s?sslmode=%s"
c, err := persistence.Open(
"postgres",
fmt.Sprintf(connectionTemplate, username, password, host, port, database, sslmode),
)
}
Querying
persistence can perform both raw, and built up queries.
var actualText string
query := persistence.Prepare("SELECT value FROM raw_example")
err := c.RawStatement().QueryRow(query, &actualText)
type Object struct {
Value string
}
var actual Object
err := c.BuildStatement().Query(&actual)
Prepared Statements
If a query is too complicated to easily build within the query builder, it is very simple to write and execute your
own queries within a prepared statement.
var value1 string
var value2 string
statement := persistence.Prepare("SELECT value1, value2 FROM raw_example LIMIT 1")
err := c.RawStatement().QueryRow(query, &value1, &value2)
if err != nil {
panic(err)
}
fmt.Println(value1, value2)
statement := persistence.Prepare("SELECT value1, value2 FROM raw_example LIMIT 1")
rows, err := c.RawStatement().Query(query)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
var value string
err = rows.Scan(&value)
if err != nil {
panic(err)
}
fmt.Println(value)
}
Statement Execution
Either execute your transactions, i.e. your inserts, updates, deletes, Or your queries which return data.
For single statement operations, you may prepare and execute/query in one step using the PrepareAnd... methods available
from your connection. You can either query for a single row, or multiple. It's up to you.
statement := persistence.Prepare("INSERT INTO raw_example (value) VALUES ($1)", "beep boop")
err := persistence.RawStatement().ExecuteStatements(statement)
type Object struct {
Value string
}
actual := Object{"beep boop"}
err := c.BuildStatement().Insert(actual)