Add clause, DB API, model definition
This commit is contained in:
		
							parent
							
								
									8eae7e4ab9
								
							
						
					
					
						commit
						b9cce2be6a
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| TODO | ||||
| TODO* | ||||
| documents | ||||
| coverage.txt | ||||
| _book | ||||
|  | ||||
							
								
								
									
										5
									
								
								association.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								association.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| package gorm | ||||
| 
 | ||||
| // Association Mode contains some helper methods to handle relationship things easily.
 | ||||
| type Association struct { | ||||
| } | ||||
							
								
								
									
										138
									
								
								chainable_api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								chainable_api.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,138 @@ | ||||
| package gorm | ||||
| 
 | ||||
| // Model specify the model you would like to run db operations
 | ||||
| //    // update all users's name to `hello`
 | ||||
| //    db.Model(&User{}).Update("name", "hello")
 | ||||
| //    // if user's primary key is non-blank, will use it as condition, then will only update the user's name to `hello`
 | ||||
| //    db.Model(&user).Update("name", "hello")
 | ||||
| func (db *DB) Model(value interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Table specify the table you would like to run db operations
 | ||||
| func (db *DB) Table(name string) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Select specify fields that you want when querying, creating, updating
 | ||||
| func (db *DB) Select(query interface{}, args ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Omit specify fields that you want to ignore when creating, updating and querying
 | ||||
| func (db *DB) Omit(columns ...string) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Where(query interface{}, args ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Not add NOT condition
 | ||||
| func (db *DB) Not(query interface{}, args ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Or add OR conditions
 | ||||
| func (db *DB) Or(query interface{}, args ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Joins specify Joins conditions
 | ||||
| //     db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Find(&user)
 | ||||
| func (db *DB) Joins(query string, args ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Group specify the group method on the find
 | ||||
| func (db *DB) Group(column string) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Having specify HAVING conditions for GROUP BY
 | ||||
| func (db *DB) Having(query interface{}, args ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Order specify order when retrieve records from database
 | ||||
| //     db.Order("name DESC")
 | ||||
| //     db.Order(gorm.Expr("name = ? DESC", "first")) // sql expression
 | ||||
| func (db *DB) Order(value interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Limit specify the number of records to be retrieved
 | ||||
| func (db *DB) Limit(limit int64) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Offset specify the number of records to skip before starting to return the records
 | ||||
| func (db *DB) Offset(offset int64) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically
 | ||||
| //     func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
 | ||||
| //         return db.Where("amount > ?", 1000)
 | ||||
| //     }
 | ||||
| //
 | ||||
| //     func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
 | ||||
| //         return func (db *gorm.DB) *gorm.DB {
 | ||||
| //             return db.Scopes(AmountGreaterThan1000).Where("status in (?)", status)
 | ||||
| //         }
 | ||||
| //     }
 | ||||
| //
 | ||||
| //     db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
 | ||||
| // Refer https://jinzhu.github.io/gorm/crud.html#scopes
 | ||||
| func (db *DB) Scopes(funcs ...func(*DB) *DB) (tx *DB) { | ||||
| 	for _, f := range funcs { | ||||
| 		db = f(db) | ||||
| 	} | ||||
| 	return db | ||||
| } | ||||
| 
 | ||||
| //Preloads only preloads relations, don`t touch out
 | ||||
| func (db *DB) Preloads(out interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Preload preload associations with given conditions
 | ||||
| //    db.Preload("Orders", "state NOT IN (?)", "cancelled").Find(&users)
 | ||||
| func (db *DB) Preload(column string, conditions ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Assign(attrs ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Attrs(attrs ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Unscoped() (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Raw(sql string, values ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										53
									
								
								clause/clause.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								clause/clause.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| package clause | ||||
| 
 | ||||
| // Builder builder interface
 | ||||
| type BuilderInterface interface { | ||||
| 	Write(sql ...string) error | ||||
| 	WriteQuoted(field interface{}) error | ||||
| 	AddVar(vars ...interface{}) string | ||||
| 	Quote(field interface{}) string | ||||
| } | ||||
| 
 | ||||
| // Interface clause interface
 | ||||
| type Interface interface { | ||||
| 	Name() string | ||||
| 	Build(builder BuilderInterface) | ||||
| } | ||||
| 
 | ||||
| // NegationBuilder negation condition builder
 | ||||
| type NegationBuilder interface { | ||||
| 	NegationBuild(builder BuilderInterface) | ||||
| } | ||||
| 
 | ||||
| // Where where clause
 | ||||
| type Where struct { | ||||
| } | ||||
| 
 | ||||
| // Select select attrs when querying, updating, creating
 | ||||
| type Select struct { | ||||
| 	Omit bool | ||||
| } | ||||
| 
 | ||||
| // Join join clause
 | ||||
| type Join struct { | ||||
| } | ||||
| 
 | ||||
| // GroupBy group by clause
 | ||||
| type GroupBy struct { | ||||
| } | ||||
| 
 | ||||
| // Having having clause
 | ||||
| type Having struct { | ||||
| } | ||||
| 
 | ||||
| // Order order clause
 | ||||
| type Order struct { | ||||
| } | ||||
| 
 | ||||
| // Limit limit clause
 | ||||
| type Limit struct { | ||||
| } | ||||
| 
 | ||||
| // Offset offset clause
 | ||||
| type Offset struct { | ||||
| } | ||||
							
								
								
									
										19
									
								
								clause/expr.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								clause/expr.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| package clause | ||||
| 
 | ||||
| type ExprInterface interface { | ||||
| } | ||||
| 
 | ||||
| type Expr struct { | ||||
| } | ||||
| 
 | ||||
| type Average struct { | ||||
| } | ||||
| 
 | ||||
| type Minimum struct { | ||||
| } | ||||
| 
 | ||||
| type Maximum struct { | ||||
| } | ||||
| 
 | ||||
| type Sum struct { | ||||
| } | ||||
							
								
								
									
										195
									
								
								clause/operators.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								clause/operators.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,195 @@ | ||||
| package clause | ||||
| 
 | ||||
| import "strings" | ||||
| 
 | ||||
| type AddConditions []Interface | ||||
| 
 | ||||
| func (cs AddConditions) Build(builder BuilderInterface) { | ||||
| 	for idx, c := range cs { | ||||
| 		if idx > 0 { | ||||
| 			builder.Write(" AND ") | ||||
| 		} | ||||
| 		c.Build(builder) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type ORConditions []Interface | ||||
| 
 | ||||
| func (cs ORConditions) Build(builder BuilderInterface) { | ||||
| 	for idx, c := range cs { | ||||
| 		if idx > 0 { | ||||
| 			builder.Write(" OR ") | ||||
| 		} | ||||
| 		c.Build(builder) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type NotConditions []Interface | ||||
| 
 | ||||
| func (cs NotConditions) Build(builder BuilderInterface) { | ||||
| 	for idx, c := range cs { | ||||
| 		if idx > 0 { | ||||
| 			builder.Write(" AND ") | ||||
| 		} | ||||
| 
 | ||||
| 		if negationBuilder, ok := c.(NegationBuilder); ok { | ||||
| 			negationBuilder.NegationBuild(builder) | ||||
| 		} else { | ||||
| 			builder.Write(" NOT ") | ||||
| 			c.Build(builder) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Raw raw sql for where
 | ||||
| type Raw struct { | ||||
| 	SQL    string | ||||
| 	Values []interface{} | ||||
| } | ||||
| 
 | ||||
| func (raw Raw) Build(builder BuilderInterface) { | ||||
| 	sql := raw.SQL | ||||
| 	for _, v := range raw.Values { | ||||
| 		sql = strings.Replace(sql, " ? ", " "+builder.AddVar(v)+" ", 1) | ||||
| 	} | ||||
| 	builder.Write(sql) | ||||
| } | ||||
| 
 | ||||
| // IN Whether a value is within a set of values
 | ||||
| type IN struct { | ||||
| 	Column interface{} | ||||
| 	Values []interface{} | ||||
| } | ||||
| 
 | ||||
| func (in IN) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(in.Column) | ||||
| 
 | ||||
| 	if len(in.Values) == 0 { | ||||
| 		builder.Write(" IN (NULL)") | ||||
| 	} else { | ||||
| 		builder.Write(" IN (", builder.AddVar(in.Values...), ")") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (in IN) NegationBuild(builder BuilderInterface) { | ||||
| 	if len(in.Values) != 0 { | ||||
| 		builder.WriteQuoted(in.Column) | ||||
| 		builder.Write(" NOT IN (", builder.AddVar(in.Values...), ")") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Eq equal to for where
 | ||||
| type Eq struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (eq Eq) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(eq.Column) | ||||
| 
 | ||||
| 	if eq.Value == nil { | ||||
| 		builder.Write(" IS NULL") | ||||
| 	} else { | ||||
| 		builder.Write(" = ", builder.AddVar(eq.Value)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (eq Eq) NegationBuild(builder BuilderInterface) { | ||||
| 	Neq{eq.Column, eq.Value}.Build(builder) | ||||
| } | ||||
| 
 | ||||
| // Neq not equal to for where
 | ||||
| type Neq struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (neq Neq) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(neq.Column) | ||||
| 
 | ||||
| 	if neq.Value == nil { | ||||
| 		builder.Write(" IS NOT NULL") | ||||
| 	} else { | ||||
| 		builder.Write(" <> ", builder.AddVar(neq.Value)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (neq Neq) NegationBuild(builder BuilderInterface) { | ||||
| 	Eq{neq.Column, neq.Value}.Build(builder) | ||||
| } | ||||
| 
 | ||||
| // Gt greater than for where
 | ||||
| type Gt struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (gt Gt) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(gt.Column) | ||||
| 	builder.Write(" > ", builder.AddVar(gt.Value)) | ||||
| } | ||||
| 
 | ||||
| func (gt Gt) NegationBuild(builder BuilderInterface) { | ||||
| 	Lte{gt.Column, gt.Value}.Build(builder) | ||||
| } | ||||
| 
 | ||||
| // Gte greater than or equal to for where
 | ||||
| type Gte struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (gte Gte) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(gte.Column) | ||||
| 	builder.Write(" >= ", builder.AddVar(gte.Value)) | ||||
| } | ||||
| 
 | ||||
| func (gte Gte) NegationBuild(builder BuilderInterface) { | ||||
| 	Lt{gte.Column, gte.Value}.Build(builder) | ||||
| } | ||||
| 
 | ||||
| // Lt less than for where
 | ||||
| type Lt struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (lt Lt) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(lt.Column) | ||||
| 	builder.Write(" < ", builder.AddVar(lt.Value)) | ||||
| } | ||||
| 
 | ||||
| func (lt Lt) NegationBuild(builder BuilderInterface) { | ||||
| 	Gte{lt.Column, lt.Value}.Build(builder) | ||||
| } | ||||
| 
 | ||||
| // Lte less than or equal to for where
 | ||||
| type Lte struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (lte Lte) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(lte.Column) | ||||
| 	builder.Write(" <= ", builder.AddVar(lte.Value)) | ||||
| } | ||||
| 
 | ||||
| func (lte Lte) NegationBuild(builder BuilderInterface) { | ||||
| 	Gt{lte.Column, lte.Value}.Build(builder) | ||||
| } | ||||
| 
 | ||||
| // Like whether string matches regular expression
 | ||||
| type Like struct { | ||||
| 	Column interface{} | ||||
| 	Value  interface{} | ||||
| } | ||||
| 
 | ||||
| func (like Like) Build(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(like.Column) | ||||
| 	builder.Write(" LIKE ", builder.AddVar(like.Value)) | ||||
| } | ||||
| 
 | ||||
| func (like Like) NegationBuild(builder BuilderInterface) { | ||||
| 	builder.WriteQuoted(like.Column) | ||||
| 	builder.Write(" NOT LIKE ", builder.AddVar(like.Value)) | ||||
| } | ||||
							
								
								
									
										154
									
								
								finisher_api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								finisher_api.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| package gorm | ||||
| 
 | ||||
| import ( | ||||
| 	"database/sql" | ||||
| ) | ||||
| 
 | ||||
| func (db *DB) Count(sql string, values ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // First find first record that match given conditions, order by primary key
 | ||||
| func (db *DB) First(out interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Take return a record that match given conditions, the order will depend on the database implementation
 | ||||
| func (db *DB) Take(out interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Last find last record that match given conditions, order by primary key
 | ||||
| func (db *DB) Last(out interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Find find records that match given conditions
 | ||||
| func (db *DB) Find(out interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Scan scan value to a struct
 | ||||
| 
 | ||||
| func (db *DB) Row() *sql.Row { | ||||
| 	// TODO
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Rows() (*sql.Rows, error) { | ||||
| 	// TODO
 | ||||
| 	return nil, nil | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Scan(dest interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) ScanRows(rows *sql.Rows, result interface{}) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Create insert the value into database
 | ||||
| func (db *DB) Create(value interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Save update value in database, if the value doesn't have primary key, will insert it
 | ||||
| func (db *DB) Save(value interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Update update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
 | ||||
| func (db *DB) Update(column string, value interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Updates update attributes with callbacks, refer: https://jinzhu.github.io/gorm/crud.html#update
 | ||||
| func (db *DB) Updates(values interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) UpdateColumn(attrs ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) UpdateColumns(values interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) FirstOrCreate(out interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) FirstOrInit(out interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Delete delete value match given conditions, if the value has primary key, then will including the primary key as condition
 | ||||
| func (db *DB) Delete(value interface{}, where ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Related(value interface{}, foreignKeys ...string) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err error) { | ||||
| 	panicked := true | ||||
| 	tx := db.Begin(opts...) | ||||
| 	defer func() { | ||||
| 		// Make sure to rollback when panic, Block error or Commit error
 | ||||
| 		if panicked || err != nil { | ||||
| 			tx.Rollback() | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	err = fc(tx) | ||||
| 
 | ||||
| 	if err == nil { | ||||
| 		err = tx.Commit().Error | ||||
| 	} | ||||
| 
 | ||||
| 	panicked = false | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Begin(opts ...*sql.TxOptions) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Commit() (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Rollback() (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Exec(sql string, values ...interface{}) (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Association(column string) *Association { | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										62
									
								
								gorm.go
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								gorm.go
									
									
									
									
									
								
							| @ -1,8 +1,10 @@ | ||||
| package gorm | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/jinzhu/gorm/clause" | ||||
| 	"github.com/jinzhu/gorm/logger" | ||||
| ) | ||||
| 
 | ||||
| @ -38,9 +40,69 @@ type Model struct { | ||||
| // Dialector GORM database dialector
 | ||||
| type Dialector interface { | ||||
| 	Migrator() Migrator | ||||
| 	BindVar(stmt Statement, v interface{}) string | ||||
| } | ||||
| 
 | ||||
| // Result
 | ||||
| type Result struct { | ||||
| 	Error        error | ||||
| 	RowsAffected int64 | ||||
| 	Statement    *Statement | ||||
| } | ||||
| 
 | ||||
| // DB GORM DB definition
 | ||||
| type DB struct { | ||||
| 	*Config | ||||
| 	Dialector | ||||
| 	Result | ||||
| 	Context context.Context | ||||
| } | ||||
| 
 | ||||
| // WithContext change current instance db's context to ctx
 | ||||
| func (db *DB) WithContext(ctx context.Context) *DB { | ||||
| 	tx := db.getInstance() | ||||
| 	tx.Context = ctx | ||||
| 	return tx | ||||
| } | ||||
| 
 | ||||
| // Set store value with key into current db instance's context
 | ||||
| func (db *DB) Set(key string, value interface{}) *DB { | ||||
| 	tx := db.getInstance() | ||||
| 	tx.Statement.Settings.Store(key, value) | ||||
| 	return tx | ||||
| } | ||||
| 
 | ||||
| // Get get value with key from current db instance's context
 | ||||
| func (db *DB) Get(key string) (interface{}, bool) { | ||||
| 	if db.Statement != nil { | ||||
| 		return db.Statement.Settings.Load(key) | ||||
| 	} | ||||
| 	return nil, false | ||||
| } | ||||
| 
 | ||||
| func (db *DB) Close() *DB { | ||||
| 	// TODO
 | ||||
| 	return db | ||||
| } | ||||
| 
 | ||||
| func (db *DB) getInstance() *DB { | ||||
| 	// db.Result.Statement == nil means root DB
 | ||||
| 	if db.Result.Statement == nil { | ||||
| 		return &DB{ | ||||
| 			Config:    db.Config, | ||||
| 			Dialector: db.Dialector, | ||||
| 			Context:   context.Background(), | ||||
| 			Result: Result{ | ||||
| 				Statement: &Statement{DB: db, Clauses: map[string][]clause.Interface{}}, | ||||
| 			}, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return db | ||||
| } | ||||
| 
 | ||||
| // Debug start debug mode
 | ||||
| func (db *DB) Debug() (tx *DB) { | ||||
| 	tx = db.getInstance() | ||||
| 	return | ||||
| } | ||||
|  | ||||
							
								
								
									
										37
									
								
								model/model.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								model/model.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| package model | ||||
| 
 | ||||
| import ( | ||||
| 	"reflect" | ||||
| ) | ||||
| 
 | ||||
| type Model struct { | ||||
| 	ModelType               reflect.Type | ||||
| 	Table                   string | ||||
| 	PrioritizedPrimaryField *Field | ||||
| 	PrimaryFields           []*Field | ||||
| 	Fields                  []*Field | ||||
| 	FieldsByName            map[string]*Field | ||||
| 	FieldsByDBName          map[string]*Field | ||||
| 	Relationships           Relationships | ||||
| } | ||||
| 
 | ||||
| type Field struct { | ||||
| 	Name            string | ||||
| 	DBName          string | ||||
| 	DataType        reflect.Type | ||||
| 	DBDataType      string | ||||
| 	Tag             reflect.StructTag | ||||
| 	TagSettings     map[string]string | ||||
| 	PrimaryKey      bool | ||||
| 	AutoIncrement   bool | ||||
| 	Creatable       bool | ||||
| 	Updatable       bool | ||||
| 	Nullable        bool | ||||
| 	Unique          bool | ||||
| 	Precision       int | ||||
| 	Size            int | ||||
| 	HasDefaultValue bool | ||||
| 	DefaultValue    string | ||||
| 	StructField     reflect.StructField | ||||
| 	Model           *Model | ||||
| } | ||||
							
								
								
									
										37
									
								
								model/relationship.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								model/relationship.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| package model | ||||
| 
 | ||||
| // RelationshipType relationship type
 | ||||
| type RelationshipType string | ||||
| 
 | ||||
| const ( | ||||
| 	HasOneRel    RelationshipType = "has_one"      // HasOneRel has one relationship
 | ||||
| 	HasManyRel   RelationshipType = "has_many"     // HasManyRel has many relationship
 | ||||
| 	BelongsToRel RelationshipType = "belongs_to"   // BelongsToRel belongs to relationship
 | ||||
| 	Many2ManyRel RelationshipType = "many_to_many" // Many2ManyRel many to many relationship
 | ||||
| ) | ||||
| 
 | ||||
| type Relationships struct { | ||||
| 	HasOne    map[string]*Relationship | ||||
| 	BelongsTo map[string]*Relationship | ||||
| 	HasMany   map[string]*Relationship | ||||
| 	Many2Many map[string]*Relationship | ||||
| } | ||||
| 
 | ||||
| type Relationship struct { | ||||
| 	Type                   RelationshipType | ||||
| 	ForeignKeys            []*RelationField // self
 | ||||
| 	AssociationForeignKeys []*RelationField // association
 | ||||
| 	JoinTable              *JoinTable | ||||
| } | ||||
| 
 | ||||
| type RelationField struct { | ||||
| 	*Field | ||||
| 	PolymorphicField *Field | ||||
| 	PolymorphicValue string | ||||
| } | ||||
| 
 | ||||
| type JoinTable struct { | ||||
| 	Table                  string | ||||
| 	ForeignKeys            []*RelationField | ||||
| 	AssociationForeignKeys []*RelationField | ||||
| } | ||||
							
								
								
									
										68
									
								
								statement.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								statement.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| package gorm | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"database/sql" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/jinzhu/gorm/clause" | ||||
| ) | ||||
| 
 | ||||
| // Statement statement
 | ||||
| type Statement struct { | ||||
| 	Dest     interface{} | ||||
| 	Table    interface{} | ||||
| 	Clauses  map[string][]clause.Interface | ||||
| 	Settings sync.Map | ||||
| 	Context  context.Context | ||||
| 	DB       *DB | ||||
| 	StatementBuilder | ||||
| } | ||||
| 
 | ||||
| // StatementBuilder statement builder
 | ||||
| type StatementBuilder struct { | ||||
| 	SQL       bytes.Buffer | ||||
| 	Vars      []interface{} | ||||
| 	NamedVars []sql.NamedArg | ||||
| } | ||||
| 
 | ||||
| // Write write string
 | ||||
| func (stmt Statement) Write(sql ...string) (err error) { | ||||
| 	for _, s := range sql { | ||||
| 		_, err = stmt.SQL.WriteString(s) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // WriteQuoted write quoted field
 | ||||
| func (stmt Statement) WriteQuoted(field interface{}) (err error) { | ||||
| 	_, err = stmt.SQL.WriteString(stmt.Quote(field)) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Write write string
 | ||||
| func (stmt Statement) AddVar(vars ...interface{}) string { | ||||
| 	var placeholders []string | ||||
| 	for _, v := range vars { | ||||
| 		if namedArg, ok := v.(sql.NamedArg); ok && len(namedArg.Name) > 0 { | ||||
| 			stmt.NamedVars = append(stmt.NamedVars, namedArg) | ||||
| 			placeholders = append(placeholders, "@"+namedArg.Name) | ||||
| 		} else { | ||||
| 			placeholders = append(placeholders, stmt.DB.Dialector.BindVar(stmt, v)) | ||||
| 		} | ||||
| 	} | ||||
| 	return strings.Join(placeholders, ",") | ||||
| } | ||||
| 
 | ||||
| // Quote returns quoted value
 | ||||
| func (stmt Statement) Quote(field interface{}) (str string) { | ||||
| 	return fmt.Sprint(field) | ||||
| } | ||||
| 
 | ||||
| // AddClause add clause
 | ||||
| func (s Statement) AddClause(clause clause.Interface) { | ||||
| 	s.Clauses[clause.Name()] = append(s.Clauses[clause.Name()], clause) | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu