ngorm

package module
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2021 License: MIT Imports: 18 Imported by: 0

README

NGORM

The fork of gorm,The fantastic ORM( Object Relational Mapping) library for Golang, that focus on

  • Performance
  • Maintainability
  • Modularity
  • Battle testing
  • Extensibility
  • Safety
  • Developer friendly for real

GoDocCoverage StatusBuild Status

IMPORTANT: This is not meant to replace gorm. For advanced users you might find this library lacking, I advice you use gorm instead.

Overview

  • Full-Featured ORM (almost)
  • Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)
  • Preloading (eager loading)
  • Transactions
  • Composite Primary Key
  • SQL Builder
  • Auto Migrations

Documentation https://godoc.org/github.com/ngorm/ngorm

Database support

  • ql
  • postgresql
  • [WIP} mysql
  • mssql
  • sqlite

Table of contents

Synopsis

Welcome, I have been looking for ways to work with ql database. Since I was familiar with gorm I tried to add ql dialect. A task that proved too hard due to limitation of gorm.

I had to rework internals on gorm to reach my end goal. Along the way I had a vision on how gorm should have looked like if I were to build it today.

The new codebase is in a good shape. One of the benifits is now, you can inspect the expected queries without excuting anything (for some methods), eg db.FIndSQL will return the query for finding an item/items without hitting the database.

With the new code base, it is easy to improve as the building blocks are all visible and well documented. There is also proper error handling. The error handling is consistent with other Go libraries, no exceptions are raised but errors are returned so the application developers can handle them.

Installation

go get -u github.com/ngorm/ngorm

You also need to install the dialects(database drivers)

go get -u github.com/ngorm/ql #ql dialect
go get -u github.com/ngorm/postgres #postgresql dialect

Connecting to a database

NGORM uses a similar API as the one used by database/sql package to connect to a database.

connections to the databases requires importing of the respective driver


import (
	"log"

	// You must import the driver for the database you wish to connect to. In
	// this example I am using the ql and postgresql driver, this should work similar for the
	// other supported databases.

    // driver for postgresql database
	_ "github.com/ngorm/postgres"
    // driver for ql database
	_ "github.com/ngorm/ql"
	"github.com/ngorm/ngorm"
)

func main() {

	// The first argument is the dialect or the name of the database driver that
	// you wish to to connect to, the second argument is connection information
	// please check the appropriate driver for more information on the arguments
	// that are passed to database/sql Open.
	db, err := ngorm.Open("ql-mem", "est.db")
	if err != nil {
		log.Fatal(err)
	}

	// Do something with db
}

The returned ngorm.DB instance is safe. It is a good idea to have only one instance of this object throughout your application life cycle. Make it a global or pass it in context.

Migrations

ngorm support automatic migrations of models. ngorm reuses the gorm logic for loading models so all the valid gorm models are also valid ngorm model.

	type Profile struct {
		model.Model
		Name string
	}
	type User struct {
		model.Model
		Profile   Profile
		ProfileID int64
	}

	db, err := Open("ql-mem", "test.db")
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = db.Close() }()

	// you can inspect expected generated query
	s, err := db.AutomigrateSQL(&User{}, &Profile{})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(s.Q)

	// Or you can execute migrations like so
	_, err = db.Begin().Automigrate(&User{}, &Profile{})
	if err != nil {
		log.Fatal(err)
	}
	//Output:
	// BEGIN TRANSACTION;
	// 	CREATE TABLE users (id int64,created_at time,updated_at time,deleted_at time,profile_id int64 ) ;
	// 	CREATE INDEX idx_users_deleted_at ON users(deleted_at);
	// 	CREATE TABLE profiles (id int64,created_at time,updated_at time,deleted_at time,name string ) ;
	// 	CREATE INDEX idx_profiles_deleted_at ON profiles(deleted_at);
	// COMMIT;

API

ngorm api borrows heavily from gorm.

AddForeignKey

AddIndex

AddUniqueIndex

Assign

Association

Attrs

Automigrate

Count

Returns the number of matched rows for a given query.

You can count the number of all users like this.

var count int64
db.Model(&user).Count(&count)

Which will execute

SELECT count(*) FROM users  

You can build a normal query by chaining methods and call Count at the end, that way the query will be executed and the matched rows will be counted.

CreateTable

Creates a new database table if the table doesn't exist yet. This is useful for doing database migrations

e.g

You have the following model

	type User struct {
		ID       int64
		Name     string
		Password string
		Email    string
	}
db.CreateTable(&User{})

Will execute the following query

BEGIN TRANSACTION; 
	CREATE TABLE users (id int64,name string,password string,email string ) ;
COMMIT;

Checking if the table exists already is handled separately by the dialects.

Delete

Executes DELETE query, which is used to delete rows from a database table.

db.Begin().Delete(&Users{ID: 10})

Will execute

BEGIN TRANSACTION;
	DELETE FROM users  WHERE id = $1;
COMMIT;

Where $1=10

Dialect

Gives you the instance of dialect which is registered in the DB.

DropColumn

Removes columns from database tables by issuing ALTER TABLE.

For instance,

db.Model(&USer{}).DropColumn("password")
//ALTER TABLE users DROP COLUMN password

DropTable

Executes DROP Table query. Use this to get rid of database tables. This is the opposite of CreateTable whatever CreateTable does to the database this undoes it.

DropTableIfExests

This will check if the table exist in the database before dropping it by calling DropTable.

Find

Find is used for looking up things in the database. You can look for one item or a list of items. This works well will the other query building API calls. Something to no note is this is the last call after chaining other API calls. So, you can have something similar to db.Where(...).Find() etc.

This is an example of looking up for all users.

	type User struct {
		ID   int64
		Name string
	}

	db, err := Open("ql-mem", "test.db")
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = db.Close() }()
	_, err = db.Automigrate(&User{})
	if err != nil {
		log.Fatal(err)
	}
	v := []string{"gernest", "kemi", "helen"}
	for _, n := range v {
		err = db.Begin().Save(&User{Name: n})
		if err != nil {
			log.Fatal(err)
		}
	}

	users := []User{}
	err = db.Begin().Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	for _, u := range users {
		fmt.Println(u.Name)
	}

	//Output:
	// helen
	// kemi
	// gernest

First

First fetches the first record and order by primary key.

For instance,

db.Begin().First(&user)

Will execute,

SELECT * FROM users   ORDER BY id ASC LIMIT 1

First user by primary key

db.Begin().First(&user,10)

will execute

SELECT * FROM users  WHERE (id = $1) ORDER BY id ASC LIMIT 1

Whereby $1=10

You can chain other methods as well to build complex queries.

FirstOrCreate

This will first try to find the first record that matches, when there is no match a new record is created.

FirstOrInit

Group

HasTable

Returns true if there is a table for the given value, the value can either be a string representing a table name or a ngorm model.

Having

Builds HAVING SQL

Set

Store temporary values that will be available across db chains. The values are visible at scope leve.

Joins

Add JOIN SQL

Last

Returns the Last row to match the query.

You can gen the last user by

var user User
db.Last(&user)

Which will execute the following query

SELECT * FROM users   ORDER BY id DESC LIMIT 1

Limit

Add LIMIT SQL clause

Model

Sets the value as the scope value for the db instance. value must be a valid ngorm model.

This paves way for chainable query building, since most methods operate on the scoped model value.

By calling db.Model(&user) we are stating that out primary model we want to perate on is &user, now from there we can chain further methods to get what we want. like db.Model(*user).Limit(2).Offset(4).Find(&users)

ModifyColumn

Not

Offset

Add OFFSET SQL clause

Omit

Use this to setup fields from the model to be skipped.

Or

Add OR SQL clause

Order

Add ORDER BY SQL clause

Pluck

Preload

RemoveIndex

Save

Select

Use this to compose SELECT queries. The first argument is the Query and you can pass any positional arguments after it.

eg

db.Select("count(*)")

This will build SELECT count(*)

SingulatTable

SingularTable enables or disables singular tables name. By default this is disabled, meaning table names are in plural.

	Model	| Plural table name
	----------------------------
	Session	| sessions
	User	| users

	Model	| Singular table name
	----------------------------
	Session	| session
	User	| user

To enable singular tables do,

db.SingularTable(true)

To disable singular tables do,

db.SingularTable(false)

Table

This specify manually the database table you want to run operations on. Most operations are built automatically from models.

For instance, to find all users you can do db.Find(&users) which might generate SELECT * FROM users;.

You can select from scary_users instead by,

db.Begin().Table("scary_users").Find(&users)
// SELECT * FROM scary_users

Update

UpdateColumn

UpdateColumns

Updates

Where

This generates WHERE SQL clause.

Using Where with plain SQL

db.Where("name","gernest")

// WHERE (name=$1)
//$1="gernest"

Using Where IN

db.Where(e, "name in (?)", []string{"gernest", "gernest 2"})
// WHERE (name in ($1,$2))
// $1="gernest", $2="gernest 2"

Using Where with LIKE

db.Where(e, "name LIKE ?", "%jin%")
// WHERE (name LIKE $1)
//$1="%jin%"

Documentation

Overview

Package ngorm is a Go Object relation mapper that focus on performance, maintainability, modularity, battle testing, extensibility , safety and developer friendliness.

Installation

You can install with go get

go get -u github.com/akamajoris/ngorm

Supported databases

At the moment the following databases are supported

  • ql
  • postgresql
Example (BelongsTo)
//One to many relationship
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

// Here one user can only have one profile. But one profile can belong
// to multiple users.
type Profile struct {
	model.Model
	Name string
}
type User struct {
	model.Model
	Profile   Profile
	ProfileID int
}
_, err = db.Automigrate(&User{}, &Profile{})
if err != nil {
	log.Fatal(err)
}
u := User{
	Profile: Profile{Name: "gernest"},
}

// Creating the user with the Profile. The relation will
// automatically be created and the user.ProfileID will be set to
// the ID of hte created profile.
err = db.Create(&u)
if err != nil {
	log.Fatal(err)
}
fmt.Println(u.ProfileID == int(u.Profile.ID) && u.ProfileID != 0)
Output:

true
Example (Migration)
type Profile struct {
	model.Model
	Name string
}
type User struct {
	model.Model
	Profile   Profile
	ProfileID int64
}

db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

// you can inspect expected generated query
s, err := db.AutomigrateSQL(&User{}, &Profile{})
if err != nil {
	log.Fatal(err)
}
fmt.Println(s.Q)

// Or you can execute migrations like so
_, err = db.Begin().Automigrate(&User{}, &Profile{})
if err != nil {
	log.Fatal(err)
}
Output:

BEGIN TRANSACTION;
	CREATE TABLE users (id int64,created_at time,updated_at time,deleted_at time,profile_id int64 ) ;
	CREATE INDEX idx_users_deleted_at ON users(deleted_at);
	CREATE TABLE profiles (id int64,created_at time,updated_at time,deleted_at time,name string ) ;
	CREATE INDEX idx_profiles_deleted_at ON profiles(deleted_at);
COMMIT;

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Association

type Association struct {
	// contains filtered or unexported fields
}

Association provides utility functions for dealing with association queries

func (*Association) Append

func (a *Association) Append(values ...interface{}) error

Append append new associations for many2many, has_many, replace current association for has_one, belongs_to

This wraps around Association.Save, verbatim meaning you can have the same effect with Save method.

func (*Association) Count

func (a *Association) Count() (int, error)

Count return the count of current associations

func (*Association) Find

func (a *Association) Find(v interface{}) error

Find find out all related associations

func (*Association) Save

func (a *Association) Save(values ...interface{}) error

Save save passed values as associations. This expects to have a single value for a has_one, belongs_to relationships. You can pass one or more values for many_to_many relationship.

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB provide an API for interacting with SQL databases using Go data structures.

func Open

func Open(dialect string, args ...interface{}) (*DB, error)

Open opens a database connection and returns *DB instance., dialect is the name of the driver that you want to use. The underlying connections are handled by database/sql package. Arguments that are accepted by database/sql Open function are valid here.

Not all databases are supported. There is still an ongoing efforts to add more databases but for now the following are the databases supported by this library,

The drivers for the libraries must be imported inside your application in the same package as you invoke this function.

Example

import _ "github.com/cznic/ql/driver"  // imports ql driver
Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()
fmt.Println(db.Dialect().GetName())
Output:

ql-mem

func OpenWithOpener

func OpenWithOpener(opener Opener, dialect string, args ...interface{}) (*DB, error)

OpenWithOpener uses the opener to initialize the dialects and establish database connection. In fact Open does not do anything by itself, it just calls this function with the default Opener.

Please see Open function for details. The only difference is here you need to pass an Opener. See the Opener interface for details about what the Opener is and what it is used for.

func (*DB) AddForeignKey

func (db *DB) AddForeignKey(field string, dest string, onDelete string, onUpdate string) error

AddForeignKey adds foreign key to an existing table.

func (*DB) AddForeignKeySQL

func (db *DB) AddForeignKeySQL(field string, dest string, onDelete string, onUpdate string) (string, error)

AddForeignKeySQL generates sql to adds foreign key to an existing table.

func (*DB) AddIndex

func (db *DB) AddIndex(indexName string, columns ...string) (sql.Result, error)

AddIndex add index for columns with given name

func (*DB) AddIndexSQL

func (db *DB) AddIndexSQL(indexName string, columns ...string) (*model.Expr, error)

AddIndexSQL generates SQL to add index for columns with given name

func (*DB) AddUniqueIndex

func (db *DB) AddUniqueIndex(indexName string, columns ...string) (sql.Result, error)

AddUniqueIndex add unique index for columns with given name

func (*DB) Assign

func (db *DB) Assign(attrs ...interface{}) *DB

Assign assign result with argument regardless it is found or not

func (*DB) Association

func (db *DB) Association(column string) (*Association, error)

Association returns association object

func (*DB) Attrs

func (db *DB) Attrs(attrs ...interface{}) *DB

Attrs initialize struct with argument if record not found

func (*DB) Automigrate

func (db *DB) Automigrate(models ...interface{}) (sql.Result, error)

Automigrate creates tables that map to models if the tables don't exist yet in the database. This also takes care of situation where the models's fields have been updated(changed)

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

type Bar struct {
	ID  int64
	Say string
}

type Bun struct {
	ID   int64
	Dead bool
}

_, err = db.Automigrate(&Bar{}, &Bun{})
if err != nil {
	log.Fatal(err)
}
var names []string
qdb := db.SQLCommon()
rows, err := qdb.Query("select Name  from __Table ")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = rows.Close() }()
for rows.Next() {
	var n string
	err = rows.Scan(&n)
	if err != nil {
		log.Fatal(err)
		fmt.Println(err)
	}
	names = append(names, n)
}
if err := rows.Err(); err != nil {
	log.Fatal(err)
}
sort.Strings(names)
for _, v := range names {
	fmt.Println(v)
}
Output:

bars
buns

func (*DB) AutomigrateSQL

func (db *DB) AutomigrateSQL(models ...interface{}) (*model.Expr, error)

AutomigrateSQL generates sql query for running migrations on models.

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

type Bar struct {
	ID  int64
	Say string
}

type Bun struct {
	ID   int64
	Dead bool
}

sql, err := db.AutomigrateSQL(&Bar{}, &Bun{})
if err != nil {
	log.Fatal(err)
}
fmt.Println(sql.Q)
Output:

BEGIN TRANSACTION;
	CREATE TABLE bars (id int64,say string ) ;
	CREATE TABLE buns (id int64,dead bool ) ;
COMMIT;

func (*DB) Begin

func (db *DB) Begin() *DB

Begin gives back a fresh copy of DB ready for chaining methods that operates on the same model..

func (*DB) Close

func (db *DB) Close() error

Close closes the database connection and sends Done signal across all goroutines that subscribed to this instance context.

func (*DB) Count

func (db *DB) Count(value interface{}) error

Count get how many records for a model

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

type Foo struct {
	ID    int64
	Stuff string
}
_, err = db.Automigrate(&Foo{})
if err != nil {
	log.Fatal(err)
}

sample := []string{"a", "b", "c", "d"}
for _, v := range sample {
	err := db.Create(&Foo{Stuff: v})
	if err != nil {
		log.Fatal(err)
	}
}
var stuffs int64
err = db.Model(&Foo{}).Count(&stuffs)
if err != nil {
	log.Fatal(err)
}
fmt.Println(stuffs)
Output:

4

func (*DB) Create

func (db *DB) Create(value interface{}) error

Create creates a new record.

You can hijack the execution of the generated SQL by overriding model.HookCreateExec hook.

func (*DB) CreateSQL

func (db *DB) CreateSQL(value interface{}) (*model.Expr, error)

CreateSQL generates SQl query for creating a new record/records for value. The end query is wrapped under for ql dialectTRANSACTION block.

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()
type Bar struct {
	ID  int64
	Say string
}

b := Bar{Say: "hello"}
sql, err := db.CreateSQL(&b)
if err != nil {
	log.Fatal(err)
}
fmt.Println(sql.Q)
fmt.Printf("$1=%v", sql.Args[0])
Output:

BEGIN TRANSACTION;
	INSERT INTO bars (say) VALUES ($1);
COMMIT;
$1=hello
Example (ExtraOptions)
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()
type Bar struct {
	ID  int64
	Say string
}

b := Bar{Say: "hello"}
sql, err := db.Set(model.InsertOptions, "ON CONFLICT").
	CreateSQL(&b)
if err != nil {
	log.Fatal(err)
}
fmt.Println(sql.Q)
fmt.Printf("$1=%v", sql.Args[0])
Output:

BEGIN TRANSACTION;
	INSERT INTO bars (say) VALUES ($1) ON CONFLICT;
COMMIT;
$1=hello

func (*DB) CreateTable

func (db *DB) CreateTable(models ...interface{}) (sql.Result, error)

CreateTable creates new database tables that maps to the models.

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

type User struct {
	ID       int64
	Name     string
	Password string
	Email    string
}
_, err = db.CreateTable(&User{})
if err != nil {
	log.Fatal(err)
}
fmt.Println(db.Dialect().HasTable("users"))
Output:

true

func (*DB) CreateTableSQL

func (db *DB) CreateTableSQL(models ...interface{}) (*model.Expr, error)

CreateTableSQL return the sql query for creating tables for all the given models. The queries are wrapped in a TRANSACTION block.

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()

type User struct {
	ID       int64
	Name     string
	Password string
	Email    string
}
sql, err := db.CreateTableSQL(&User{})
if err != nil {
	log.Fatal(err)
}
e := `
BEGIN TRANSACTION; 
	CREATE TABLE users (id int64,name string,password string,email string ) ;
COMMIT;
`
sql.Q = strings.TrimSpace(sql.Q)
e = strings.TrimSpace(e)
fmt.Println(sql.Q == e)
Output:

true

func (*DB) Delete

func (db *DB) Delete(value interface{}, where ...interface{}) error

Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition

func (*DB) DeleteSQL

func (db *DB) DeleteSQL(value interface{}, where ...interface{}) (*model.Expr, error)

DeleteSQL generates SQL to delete value match given conditions, if the value has primary key, then will including the primary key as condition

func (*DB) Dialect

func (db *DB) Dialect() dialects.Dialect

Dialect return the dialect that is used by DB

func (*DB) DropColumn

func (db *DB) DropColumn(column string) (sql.Result, error)

DropColumn drop a column

func (*DB) DropTable

func (db *DB) DropTable(models ...interface{}) (sql.Result, error)

DropTable drops tables that are mapped to models. You can also pass the name of the table as astring and it will be handled.

func (*DB) DropTableIfExists

func (db *DB) DropTableIfExists(values ...interface{}) error

DropTableIfExists drop table if it is exist

func (*DB) DropTableSQL

func (db *DB) DropTableSQL(models ...interface{}) (*model.Expr, error)

DropTableSQL generates sql query for DROP TABLE. The generated query is wrapped under TRANSACTION block.

func (*DB) ExecTx

func (db *DB) ExecTx(query string, args ...interface{}) (sql.Result, error)

ExecTx wraps the query execution in a Transaction. This ensure all operations are Rolled back in case the execution fails.

func (*DB) Find

func (db *DB) Find(out interface{}, where ...interface{}) error

Find find records that match given conditions

Example
type User struct {
	ID   int64
	Name string
}

db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()
_, err = db.Automigrate(&User{})
if err != nil {
	log.Fatal(err)
}
v := []string{"gernest", "kemi", "helen"}
for _, n := range v {
	err = db.Begin().Save(&User{Name: n})
	if err != nil {
		log.Fatal(err)
	}
}

users := []User{}
err = db.Begin().Find(&users)
if err != nil {
	log.Fatal(err)
}
for _, u := range users {
	fmt.Println(u.Name)
}
Output:

helen
kemi
gernest

func (*DB) FindSQL

func (db *DB) FindSQL(out interface{}, where ...interface{}) (*model.Expr, error)

FindSQL generates SQL query for finding records that match given conditions

func (*DB) First

func (db *DB) First(out interface{}, where ...interface{}) error

First fetches the first record and order by primary key.

func (*DB) FirstOrCreate

func (db *DB) FirstOrCreate(out interface{}, where ...interface{}) error

FirstOrCreate find first matched record or create a new one with given conditions (only works with struct, map conditions)

func (*DB) FirstOrInit

func (db *DB) FirstOrInit(out interface{}, where ...interface{}) error

FirstOrInit find first matched record or initialize a new one with given conditions (only works with struct, map conditions)

func (*DB) FirstSQL

func (db *DB) FirstSQL(out interface{}, where ...interface{}) (*model.Expr, error)

FirstSQL returns SQL query for retrieving the first record ordering by primary key.

func (*DB) Group

func (db *DB) Group(query string) *DB

Group specify the group method on the find

func (*DB) HasTable

func (db *DB) HasTable(value interface{}) bool

HasTable returns true if there is a table for the given value, the value can either be a string representing a table name or a ngorm model.

func (*DB) Having

func (db *DB) Having(query string, values ...interface{}) *DB

Having specify HAVING conditions for GROUP BY

func (*DB) Joins

func (db *DB) Joins(query string, args ...interface{}) *DB

Joins specify Joins conditions

func (*DB) Last

func (db *DB) Last(out interface{}, where ...interface{}) error

Last finds the last record and order by primary key.

func (*DB) LastSQL

func (db *DB) LastSQL(out interface{}, where ...interface{}) (*model.Expr, error)

LastSQL returns SQL query for retrieving the last record ordering by primary key.

func (*DB) Limit

func (db *DB) Limit(limit interface{}) *DB

Limit specify the number of records to be retrieved

func (*DB) Model

func (db *DB) Model(value interface{}) *DB

Model sets value as the database model. This model will be used for future calls on the returned DB e.g

db.Model(&user).Update("name","hero")

You don't have to call db.Begin().Model() since this calls Begin automatically for you. It is safe for chaining.

func (*DB) ModifyColumn

func (db *DB) ModifyColumn(column string, typ string) (sql.Result, error)

ModifyColumn modify column to type

func (*DB) NewEngine

func (db *DB) NewEngine() *engine.Engine

NewEngine returns an initialized engine ready to kick some ass.

func (*DB) Not

func (db *DB) Not(query interface{}, args ...interface{}) *DB

Not filter records that don't match current conditions, similar to `Where`

func (*DB) Offset

func (db *DB) Offset(offset interface{}) *DB

Offset specify the number of records to skip before starting to return the records

func (*DB) Omit

func (db *DB) Omit(columns ...string) *DB

Omit specify fields that you want to ignore when saving to database for creating, updating

func (*DB) Or

func (db *DB) Or(query interface{}, args ...interface{}) *DB

Or filter records that match before conditions or this one, similar to `Where`

func (*DB) Order

func (db *DB) Order(value interface{}, reorder ...bool) *DB

Order specify order when retrieve records from database, set reorder to `true` to overwrite defined conditions

db.Order("name DESC")
db.Order("name DESC", true) // reorder

func (*DB) Ping added in v1.2.0

func (db *DB) Ping() error

Ping checks if you can connect to the database

func (*DB) Pluck

func (db *DB) Pluck(column string, value interface{}) error

Pluck used to query single column from a model as a map

var ages []int64
db.Find(&users).Pluck("age", &ages)

func (*DB) Preload

func (db *DB) Preload(column string, conditions ...interface{}) *DB

Preload preload associations with given conditions

db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)

func (*DB) Related

func (db *DB) Related(value interface{}, foreignKeys ...string) error

Related get related associations

func (*DB) RemoveIndex

func (db *DB) RemoveIndex(indexName string) error

RemoveIndex remove index with name

func (*DB) SQLCommon

func (db *DB) SQLCommon() model.SQLCommon

SQLCommon return SQLCommon used by the DB

func (*DB) Save

func (db *DB) Save(value interface{}) error

Save update value in database, if the value doesn't have primary key, will insert it

func (*DB) SaveSQL

func (db *DB) SaveSQL(value interface{}) (*model.Expr, error)

SaveSQL generates SQL query for saving/updating database record for value.

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()
type Foo struct {
	ID    int64
	Stuff string
}

f := Foo{ID: 10, Stuff: "twenty"}
sql, err := db.SaveSQL(&f)
if err != nil {
	log.Fatal(err)
}
fmt.Println(sql.Q)
fmt.Printf("$1=%v\n", sql.Args[0])
fmt.Printf("$2=%v", sql.Args[1])
Output:

BEGIN TRANSACTION;
	UPDATE foos SET stuff = $1  WHERE id = $2;
COMMIT;
$1=twenty
$2=10

func (*DB) Select

func (db *DB) Select(query interface{}, args ...interface{}) *DB

Select specify fields that you want to retrieve from database when querying, by default, will select all fields; When creating/updating, specify fields that you want to save to database

func (*DB) Set

func (db *DB) Set(key string, value interface{}) *DB

Set sets scope key to value.

func (*DB) SingularTable

func (db *DB) SingularTable(enable bool)

SingularTable enables or disables singular tables name. By default this is disabled, meaning table names are in plural.

Model	| Plural table name
----------------------------
Session	| sessions
User	| users

Model	| Singular table name
----------------------------
Session	| session
User	| user

func (*DB) Table

func (db *DB) Table(name string) *DB

Table specify the table you would like to run db operations

func (*DB) Update

func (db *DB) Update(attrs ...interface{}) error

Update runs UPDATE queries.

func (*DB) UpdateColumn

func (db *DB) UpdateColumn(attrs ...interface{}) error

UpdateColumn update attributes without callbacks

func (*DB) UpdateColumns

func (db *DB) UpdateColumns(values interface{}) error

UpdateColumns update attributes without

func (*DB) UpdateSQL

func (db *DB) UpdateSQL(attrs ...interface{}) (*model.Expr, error)

UpdateSQL generates SQL that will be executed when you use db.Update

Example
db, err := Open("ql-mem", "test.db")
if err != nil {
	log.Fatal(err)
}
defer func() { _ = db.Close() }()
type Foo struct {
	ID    int64
	Stuff string
}

f := Foo{ID: 10, Stuff: "twenty"}
sql, err := db.Model(&f).UpdateSQL("stuff", "hello")
if err != nil {
	log.Fatal(err)
}
fmt.Println(sql.Q)
fmt.Printf("$1=%v\n", sql.Args[0])
fmt.Printf("$2=%v", sql.Args[1])
Output:

BEGIN TRANSACTION;
	UPDATE foos SET stuff = $1  WHERE id = $2;
COMMIT;
$1=hello
$2=10

func (*DB) Updates

func (db *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) error

Updates runs UPDATE query

func (*DB) UpdatesSQL

func (db *DB) UpdatesSQL(values interface{}, ignoreProtectedAttrs ...bool) (*model.Expr, error)

UpdatesSQL generates sql that will be used when you run db.UpdatesSQL

func (*DB) Verbose

func (db *DB) Verbose(b bool)

Verbose prints what is executed on stdout.

DOn't set this to true when in production. It is dog slow, and a security risk. Use this only in development

func (*DB) Where

func (db *DB) Where(query interface{}, args ...interface{}) *DB

Where return a new relation, filter records with given conditions, accepts `map`, `struct` or `string` as conditions

type Opener

type Opener interface {
	Open(dialect string, args ...interface{}) (model.SQLCommon, dialects.Dialect, error)
}

Opener is an interface that is used to open up connection to SQL databases.

Directories

Path Synopsis
Package builder contains functions for SQL building.
Package builder contains functions for SQL building.
Package dialects defines a uniform interface for creating custom support for different SQL databases.
Package dialects defines a uniform interface for creating custom support for different SQL databases.
Package engine defines the core structure that drives the ngorm API.
Package engine defines the core structure that drives the ngorm API.
Package fixture contains all stuctures neesessary for consinstent testing on a wide range of SQL database dialects.
Package fixture contains all stuctures neesessary for consinstent testing on a wide range of SQL database dialects.
Package hooks contains callbacks/hooks used by ngorm.
Package hooks contains callbacks/hooks used by ngorm.
Package model defines structures that are shared through out ngorm.
Package model defines structures that are shared through out ngorm.
Package regexes exposes pre compiled regular expressions that are used by ngorm.
Package regexes exposes pre compiled regular expressions that are used by ngorm.
Package scope defines functions that operates on engine.Engine and enables operating on model values easily.
Package scope defines functions that operates on engine.Engine and enables operating on model values easily.
Package search contains search functions for ngorm.
Package search contains search functions for ngorm.
Package util contains utility functions that are used in dirrent places of the codebase.
Package util contains utility functions that are used in dirrent places of the codebase.

Jump to

Keyboard shortcuts

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