The following example illustrates the general usage of the sqac library.
package main
import (
"flag"
"fmt"
"github.com/1414C/sqac"
_ "github.com/SAP/go-hdb/driver"
_ "github.com/denisenkom/go-mssqldb"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
)
func main() {
dbFlag := flag.String("db", "sqlite", "db-type for connection")
csFlag := flag.String("cs", "testdb.sqlite", "connection-string for the database")
logFlag := flag.Bool("l", false, "activate sqac detail logging to stdout")
dbLogFlag := flag.Bool("dbl", false, "activate DDL/DML logging to stdout)")
flag.Parse()
// This will be the central access-point to the ORM and should be made
// available in all locations where access to the persistent storage
// (database) is required.
var (
Handle sqac.PublicDB
)
// Declare a struct to be used as the source for table creation.
type Depot struct {
DepotNum int `db:"depot_num" sqac:"primary_key:inc"`
CreateDate time.Time `db:"create_date" sqac:"nullable:false;default:now();"`
Region string `db:"region" sqac:"nullable:false;default:YYC"`
Province string `db:"province" sqac:"nullable:false;default:AB"`
Country string `db:"country" sqac:"nullable:false;default:CA"`
Population int `db:"population" sqac:"nullable:false;default:0;index:non-unique"`
}
// Create a PublicDB instance. Check the sqac.Create function, as the return parameter contains
// not only an implementation of PublicDB targeting the db-type/db, but also a pointer
// facilitating access to the db via jmoiron's sqlx package. This is useful if you wish
// to access the sql/sqlx APIs directly.
Handle = sqac.Create(*dbFlag, *logFlag, *dbLogFlag, *cs)
// Execute a call to get the name of the db-driver being used. At this point, any method
// contained in the sqac.PublicDB interface may be called.
driverName := Handle.GetDBDriverName()
fmt.Println("driverName:", driverName)
// Create a new table in the database
err := Handle.CreateTables(Depot{})
if err != nil {
t.Errorf("%s", err.Error())
}
// Determine the table name as per the table creation logic
tn := common.GetTableName(Depot{})
// Expect that table depot exists
if !Handle.ExistsTable(tn) {
t.Errorf("table %s was not created", tn)
}
// prepare data for insertion into the db-table
var newDepot = Depot{
// DepotNum: 1234, // not needed - autoinc primary key
// CreateDate: , // not needed - default:now()
Region: "YVR",
Province: "BC",
Country: "CA",
Population: 2500000,
}
// create a new record via the CRUD Create call
err = Handle.Create(&newDepot)
if err != nil {
t.Errorf(err.Error())
}
// Drop the table
err = Handle.DropTables(Depot{})
if err != nil {
t.Errorf("table %s was not dropped", tn)
}
// Close the connection.
Handle.Close()
}
Execute the sample program against a local sqlite database as follows. Note that the sample program makes no effort to validate the flag parameters.
go run -db sqlite -cs testdb.sqlite main.go
Experiment by commenting out the the DropTables(Depot{}) call, and add code to test some simple CRUD type operations.
Update an existing db record:
newDepot.Region = "YYC" // "YVR" -> "YYC"
newDepot.Province = "AB" // "BC" -> "AB"
newDepot.Population = 1000000 // 2500000 -> 1000000
err = Handle.Update(&newDepot)
if err != nil {
t.Errorf(err.Error())
}
Read an existing db record:
// create a struct to read into and populate the keys
depotRead := Depot{
DepotNum: newDepot.DepotNum,
}
err = Handle.GetEntity(&depotRead)
if err != nil {
t.Errorf("%s", err.Error())
}
if depotRead.Region != "YYC" || depotRead.Region != "YVR" {
t.Errorf("depotRead.Region error!")
}
Delete an existing db record:
err = Handle.Delete(&newDepot)
if err != nil {
t.Errorf("%s", err.Error())
}