improved docs & delete or private codes

This commit is contained in:
Lunny Xiao 2013-11-22 10:26:01 +08:00
parent 65d079fc2c
commit e1644f7c98
6 changed files with 106 additions and 86 deletions

34
doc.go
View File

@ -13,10 +13,34 @@ First, we should new a engine for a database
Method NewEngine's parameters is the same as sql.Open. It depends
drivers' implementation. Generally, one engine is enough.
engine.Get(...)
engine.Insert(...)
engine.Find(...)
engine.Iterate(...)
engine.Delete(...)
There are 7 major methods and many helpful methods to use to operate database.
1. Insert one or multipe records to database
engine.Insert(...)
2. Query one record from database
engine.Get(...)
3. Query multiple records from database
engine.Find(...)
4. Query multiple records and record by record handle
engine.Iterate(...)
5. Update one or more records
engine.Update(...)
6. Delete one or more records
engine.Delete(...)
7. Count records
engine.Count(...)
*/
package xorm

View File

@ -391,6 +391,9 @@ Having的参数字符串
* NoAutoTime()
如果此方法执行则此次生成的语句中Created和Updated字段将不自动赋值为当前时间
* NoCache()
如果此方法执行,则此次生成的语句则在非缓存模式下执行
* UseBool(...string)
当从一个struct来生成查询条件或更新字段时xorm会判断struct的field是否为0,"",nil如果为以上则不当做查询条件或者更新内容。因为bool类型只有true和false两种值因此默认所有bool类型不会作为查询条件或者更新字段。如果可以使用此方法如果默认不传参数则所有的bool字段都将会被使用如果参数不为空则参数中指定的为字段名则这些字段对应的bool值将被使用。

View File

@ -37,6 +37,8 @@ type dialect interface {
GetIndexes(tableName string) (map[string]*Index, error)
}
// Engine is the major struct of xorm, it means a database manager.
// Commonly, an application only need one engine
type Engine struct {
Mapper IMapper
TagIdentifier string
@ -122,7 +124,7 @@ func (engine *Engine) NoCache() *Session {
// Set a table use a special cacher
func (engine *Engine) MapCacher(bean interface{}, cacher Cacher) {
t := rType(bean)
engine.AutoMapType(t)
engine.autoMapType(t)
engine.Tables[t].Cacher = cacher
}
@ -143,11 +145,6 @@ func (engine *Engine) Close() error {
return engine.Pool.Close(engine)
}
// Test method is deprecated, use Ping() method.
func (engine *Engine) Test() error {
return engine.Ping()
}
// Ping tests if database is alive.
func (engine *Engine) Ping() error {
session := engine.NewSession()
@ -184,20 +181,29 @@ func (engine *Engine) LogWarn(contents ...interface{}) {
}
}
// execute sql
// Sql method let's you manualy write raw sql and operate
// For example:
//
// engine.Sql("select * from user").Find(&users)
//
// This code will execute "select * from user" and set the records to users
//
func (engine *Engine) Sql(querystring string, args ...interface{}) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Sql(querystring, args...)
}
// Default if your struct has "created" or "updated" filed tag, the fields
// will automatically be filled with current time when Insert or Update
// invoked. Call NoAutoTime if you dont' want to fill automatically.
func (engine *Engine) NoAutoTime() *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.NoAutoTime()
}
// retrieve all tables, columns, indexes' informations from database.
// Retrieve all tables, columns, indexes' informations from database.
func (engine *Engine) DBMetas() ([]*Table, error) {
tables, err := engine.dialect.GetTables()
if err != nil {
@ -266,60 +272,82 @@ func (engine *Engine) StoreEngine(storeEngine string) *Session {
return session.StoreEngine(storeEngine)
}
// use for distinct columns. Caution: when you are using cache,
// distinct will not be cached because cache system need id,
// but distinct will not provide id
func (engine *Engine) Distinct(columns ...string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Distinct(columns...)
}
// only use the paramters as select or update columns
func (engine *Engine) Cols(columns ...string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Cols(columns...)
}
// Xorm automatically retrieve condition according struct, but
// if struct has bool field, it will ignore them. So use UseBool
// to tell system to do not ignore them.
// If no paramters, it will use all the bool field of struct, or
// it will use paramters's columns
func (engine *Engine) UseBool(columns ...string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.UseBool(columns...)
}
// Only not use the paramters as select or update columns
func (engine *Engine) Omit(columns ...string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Omit(columns...)
}
// This method will generate "column IN (?, ?)"
func (engine *Engine) In(column string, args ...interface{}) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.In(column, args...)
}
// Temporarily change the Get, Find, Update's table
func (engine *Engine) Table(tableNameOrBean interface{}) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Table(tableNameOrBean)
}
// This method will generate "LIMIT start, limit"
func (engine *Engine) Limit(limit int, start ...int) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Limit(limit, start...)
}
// Method Desc will generate "ORDER BY column1 DESC, column2 DESC"
// This will
func (engine *Engine) Desc(colNames ...string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Desc(colNames...)
}
// Method Asc will generate "ORDER BY column1 DESC, column2 Asc"
// This method can chainable use.
//
// engine.Desc("name").Asc("age").Find(&users)
// // SELECT * FROM user ORDER BY name DESC, age ASC
//
func (engine *Engine) Asc(colNames ...string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
return session.Asc(colNames...)
}
// Method OrderBy will generate "ORDER BY order"
func (engine *Engine) OrderBy(order string) *Session {
session := engine.NewSession()
session.IsAutoClose = true
@ -345,21 +373,20 @@ func (engine *Engine) Having(conditions string) *Session {
return session.Having(conditions)
}
//
func (engine *Engine) AutoMapType(t reflect.Type) *Table {
func (engine *Engine) autoMapType(t reflect.Type) *Table {
engine.mutex.Lock()
defer engine.mutex.Unlock()
table, ok := engine.Tables[t]
if !ok {
table = engine.MapType(t)
table = engine.mapType(t)
engine.Tables[t] = table
}
return table
}
func (engine *Engine) AutoMap(bean interface{}) *Table {
func (engine *Engine) autoMap(bean interface{}) *Table {
t := rType(bean)
return engine.AutoMapType(t)
return engine.autoMapType(t)
}
func (engine *Engine) newTable() *Table {
@ -371,7 +398,7 @@ func (engine *Engine) newTable() *Table {
return table
}
func (engine *Engine) MapType(t reflect.Type) *Table {
func (engine *Engine) mapType(t reflect.Type) *Table {
table := engine.newTable()
table.Name = engine.Mapper.Obj2Table(t.Name())
table.Type = t
@ -395,7 +422,7 @@ func (engine *Engine) MapType(t reflect.Type) *Table {
}
if (strings.ToUpper(tags[0]) == "EXTENDS") &&
(fieldType.Kind() == reflect.Struct) {
parentTable := engine.MapType(fieldType)
parentTable := engine.mapType(fieldType)
for name, col := range parentTable.Columns {
col.FieldName = fmt.Sprintf("%v.%v", fieldType.Name(), col.FieldName)
table.Columns[name] = col
@ -540,36 +567,36 @@ func (engine *Engine) MapType(t reflect.Type) *Table {
}
// Map a struct to a table
func (engine *Engine) Map(beans ...interface{}) (e error) {
func (engine *Engine) mapping(beans ...interface{}) (e error) {
engine.mutex.Lock()
defer engine.mutex.Unlock()
for _, bean := range beans {
t := rType(bean)
engine.Tables[t] = engine.MapType(t)
engine.Tables[t] = engine.mapType(t)
}
return
}
// Is a table has any reocrd
// If a table has any reocrd
func (engine *Engine) IsTableEmpty(bean interface{}) (bool, error) {
t := rType(bean)
if t.Kind() != reflect.Struct {
return false, errors.New("bean should be a struct or struct's point")
}
engine.AutoMapType(t)
engine.autoMapType(t)
session := engine.NewSession()
defer session.Close()
rows, err := session.Count(bean)
return rows > 0, err
}
// Is a table is exist
// If a table is exist
func (engine *Engine) IsTableExist(bean interface{}) (bool, error) {
t := rType(bean)
if t.Kind() != reflect.Struct {
return false, errors.New("bean should be a struct or struct's point")
}
table := engine.AutoMapType(t)
table := engine.autoMapType(t)
session := engine.NewSession()
defer session.Close()
has, err := session.isTableExist(table.Name)
@ -596,7 +623,7 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id int64) error {
if t.Kind() != reflect.Struct {
return errors.New("error params")
}
table := engine.AutoMap(bean)
table := engine.autoMap(bean)
if table.Cacher != nil {
table.Cacher.ClearIds(table.Name)
table.Cacher.DelBean(table.Name, id)
@ -611,7 +638,7 @@ func (engine *Engine) ClearCache(beans ...interface{}) error {
if t.Kind() != reflect.Struct {
return errors.New("error params")
}
table := engine.AutoMap(bean)
table := engine.autoMap(bean)
if table.Cacher != nil {
table.Cacher.ClearIds(table.Name)
table.Cacher.ClearBeans(table.Name)
@ -620,12 +647,12 @@ func (engine *Engine) ClearCache(beans ...interface{}) error {
return nil
}
// Sync the new struct change to database, this method will automatically add
// Sync the new struct changes to database, this method will automatically add
// table, column, index, unique. but will not delete or change anything.
// If you change some field, you should change the database manually.
func (engine *Engine) Sync(beans ...interface{}) error {
for _, bean := range beans {
table := engine.AutoMap(bean)
table := engine.autoMap(bean)
s := engine.NewSession()
defer s.Close()
@ -715,7 +742,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
return nil
}
func (engine *Engine) UnMap(beans ...interface{}) (e error) {
func (engine *Engine) unMap(beans ...interface{}) (e error) {
engine.mutex.Lock()
defer engine.mutex.Unlock()
for _, bean := range beans {
@ -728,7 +755,7 @@ func (engine *Engine) UnMap(beans ...interface{}) (e error) {
}
// Drop all mapped table
func (engine *Engine) DropAll() error {
func (engine *Engine) dropAll() error {
session := engine.NewSession()
defer session.Close()
@ -781,7 +808,7 @@ func (engine *Engine) DropTables(beans ...interface{}) error {
return session.Commit()
}
func (engine *Engine) CreateAll() error {
func (engine *Engine) createAll() error {
session := engine.NewSession()
defer session.Close()
return session.CreateAll()
@ -823,6 +850,7 @@ func (engine *Engine) Delete(bean interface{}) (int64, error) {
return session.Delete(bean)
}
// Get retrieve one record from table
func (engine *Engine) Get(bean interface{}) (bool, error) {
session := engine.NewSession()
defer session.Close()

View File

@ -1,35 +0,0 @@
package xorm
import (
"database/sql"
)
type Iterator struct {
session *Session
startId int
rows *sql.Rows
}
func (iter *Iterator) IsValid() bool {
return iter.session != nil && iter.rows != nil
}
/*
func (iter *Iterator) Next(bean interface{}) (bool, error) {
if !iter.IsValid() {
return errors.New("iterator is not valied.")
}
if iter.rows.Next() {
iter.rows.Scan(...)
}
}*/
// close the iterator
func (iter *Iterator) Close() {
if iter.rows != nil {
iter.rows.Close()
}
if iter.session != nil && iter.session.IsAutoClose {
iter.session.Close()
}
}

View File

@ -248,7 +248,7 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b
return errors.New("Expected a pointer to a struct")
}
table := session.Engine.AutoMapType(rType(obj))
table := session.Engine.autoMapType(rType(obj))
for key, data := range objMap {
if _, ok := table.Columns[key]; !ok {
@ -329,7 +329,7 @@ func (session *Session) Exec(sql string, args ...interface{}) (sql.Result, error
// this function create a table according a bean
func (session *Session) CreateTable(bean interface{}) error {
session.Statement.RefTable = session.Engine.AutoMap(bean)
session.Statement.RefTable = session.Engine.autoMap(bean)
err := session.newDb()
if err != nil {
@ -344,7 +344,7 @@ func (session *Session) CreateTable(bean interface{}) error {
}
func (session *Session) CreateIndexes(bean interface{}) error {
session.Statement.RefTable = session.Engine.AutoMap(bean)
session.Statement.RefTable = session.Engine.autoMap(bean)
err := session.newDb()
if err != nil {
@ -366,7 +366,7 @@ func (session *Session) CreateIndexes(bean interface{}) error {
}
func (session *Session) CreateUniques(bean interface{}) error {
session.Statement.RefTable = session.Engine.AutoMap(bean)
session.Statement.RefTable = session.Engine.autoMap(bean)
err := session.newDb()
if err != nil {
@ -450,7 +450,7 @@ func (session *Session) DropTable(bean interface{}) error {
if t.Kind() == reflect.String {
session.Statement.AltTableName = bean.(string)
} else if t.Kind() == reflect.Struct {
session.Statement.RefTable = session.Engine.AutoMap(bean)
session.Statement.RefTable = session.Engine.autoMap(bean)
} else {
return errors.New("Unsupported type")
}
@ -715,7 +715,7 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
var sql string
var args []interface{}
session.Statement.RefTable = session.Engine.AutoMap(bean)
session.Statement.RefTable = session.Engine.autoMap(bean)
if session.Statement.RawSQL == "" {
sql, args = session.Statement.genGetSql(bean)
} else {
@ -780,7 +780,7 @@ func (session *Session) Get(bean interface{}) (bool, error) {
session.Statement.Limit(1)
var sql string
var args []interface{}
session.Statement.RefTable = session.Engine.AutoMap(bean)
session.Statement.RefTable = session.Engine.autoMap(bean)
if session.Statement.RawSQL == "" {
sql, args = session.Statement.genGetSql(bean)
} else {
@ -871,12 +871,12 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
if session.Statement.RefTable == nil {
if sliceElementType.Kind() == reflect.Ptr {
if sliceElementType.Elem().Kind() == reflect.Struct {
table = session.Engine.AutoMapType(sliceElementType.Elem())
table = session.Engine.autoMapType(sliceElementType.Elem())
} else {
return errors.New("slice type")
}
} else if sliceElementType.Kind() == reflect.Struct {
table = session.Engine.AutoMapType(sliceElementType)
table = session.Engine.autoMapType(sliceElementType)
} else {
return errors.New("slice type")
}
@ -1306,7 +1306,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
bean := sliceValue.Index(0).Interface()
sliceElementType := rType(bean)
table := session.Engine.AutoMapType(sliceElementType)
table := session.Engine.autoMapType(sliceElementType)
session.Statement.RefTable = table
size := sliceValue.Len()
@ -1538,7 +1538,7 @@ func (session *Session) bytes2Value(col *Column, fieldValue *reflect.Value, data
v = x
fieldValue.Set(reflect.ValueOf(v))
} else if session.Statement.UseCascade {
table := session.Engine.AutoMapType(fieldValue.Type())
table := session.Engine.autoMapType(fieldValue.Type())
if table != nil {
x, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
@ -1656,7 +1656,7 @@ func (session *Session) value2Interface(col *Column, fieldValue reflect.Value) (
}
func (session *Session) innerInsert(bean interface{}) (int64, error) {
table := session.Engine.AutoMap(bean)
table := session.Engine.autoMap(bean)
session.Statement.RefTable = table
colNames, args, err := table.genCols(session, bean, false, false)
@ -1931,7 +1931,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
var table *Table
if t.Kind() == reflect.Struct {
table = session.Engine.AutoMap(bean)
table = session.Engine.autoMap(bean)
session.Statement.RefTable = table
if session.Statement.ColumnStr == "" {
@ -2078,7 +2078,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
defer session.Close()
}
table := session.Engine.AutoMap(bean)
table := session.Engine.autoMap(bean)
session.Statement.RefTable = table
colNames, args := buildConditions(session.Engine, table, bean, true,
session.Statement.allUseBool, session.Statement.boolColumnMap)

View File

@ -98,7 +98,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) {
if t.Kind() == reflect.String {
statement.AltTableName = tableNameOrBean.(string)
} else if t.Kind() == reflect.Struct {
statement.RefTable = statement.Engine.AutoMapType(t)
statement.RefTable = statement.Engine.autoMapType(t)
}
}
@ -166,7 +166,7 @@ func buildConditions(engine *Engine, table *Table, bean interface{}, includeVers
val = t
}
} else {
engine.AutoMapType(fieldValue.Type())
engine.autoMapType(fieldValue.Type())
if table, ok := engine.Tables[fieldValue.Type()]; ok {
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumn().FieldName)
if pkField.Int() != 0 {
@ -431,7 +431,7 @@ func (s *Statement) genDropSQL() string {
}
func (statement Statement) genGetSql(bean interface{}) (string, []interface{}) {
table := statement.Engine.AutoMap(bean)
table := statement.Engine.autoMap(bean)
statement.RefTable = table
colNames, args := buildConditions(statement.Engine, table, bean, true,
@ -469,7 +469,7 @@ func (s *Statement) genAddUniqueStr(uqeName string, cols []string) (string, []in
}
func (statement Statement) genCountSql(bean interface{}) (string, []interface{}) {
table := statement.Engine.AutoMap(bean)
table := statement.Engine.autoMap(bean)
statement.RefTable = table
colNames, args := buildConditions(statement.Engine, table, bean, true, statement.allUseBool, statement.boolColumnMap)