diff --git a/README.md b/README.md index b8c7620b..158f5c11 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Drivers for Go's sql package which currently support database/sql includes: * Add Incr API * Specify Timezone Location -[More changelogs ...](http://xorm.io/docs/intro/change_log.md) +[More changelogs ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-15) # Installation @@ -82,10 +82,12 @@ Or # Cases -* [Gorevel](http://http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel) +* [Docker.cn](https://docker.cn/) * [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs) +* [Gorevel](http://http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel) + * [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker) * [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild) diff --git a/README_CN.md b/README_CN.md index d3f29fb7..5def1c38 100644 --- a/README_CN.md +++ b/README_CN.md @@ -55,7 +55,7 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作 * 添加 Incr API * 指定时区位置 -[更多更新日志...](http://xorm.io/docs/intro/change_log.md) +[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16) ## 安装 @@ -78,6 +78,8 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作 ## 案例 +* [Docker.cn](https://docker.cn/) + * [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs) * [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker) diff --git a/engine.go b/engine.go index fe08ec80..700f46a1 100644 --- a/engine.go +++ b/engine.go @@ -565,6 +565,13 @@ func (engine *Engine) Table(tableNameOrBean interface{}) *Session { return session.Table(tableNameOrBean) } +// set the table alias +func (engine *Engine) Alias(alias string) *Session { + session := engine.NewSession() + session.IsAutoClose = true + return session.Alias(alias) +} + // This method will generate "LIMIT start, limit" func (engine *Engine) Limit(limit int, start ...int) *Session { session := engine.NewSession() @@ -600,7 +607,7 @@ func (engine *Engine) OrderBy(order string) *Session { } // The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN -func (engine *Engine) Join(join_operator, tablename, condition string) *Session { +func (engine *Engine) Join(join_operator string, tablename interface{}, condition string) *Session { session := engine.NewSession() session.IsAutoClose = true return session.Join(join_operator, tablename, condition) @@ -1251,6 +1258,13 @@ func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice [ return session.Query(sql, paramStr...) } +// Exec a raw sql and return records as []map[string]string +func (engine *Engine) Q(sql string, paramStr ...interface{}) (resultsSlice []map[string]string, err error) { + session := engine.NewSession() + defer session.Close() + return session.Q(sql, paramStr...) +} + // Insert one or more records func (engine *Engine) Insert(beans ...interface{}) (int64, error) { session := engine.NewSession() diff --git a/session.go b/session.go index 6df62211..5487eeb0 100644 --- a/session.go +++ b/session.go @@ -134,6 +134,12 @@ func (session *Session) Table(tableNameOrBean interface{}) *Session { return session } +// set the table alias +func (session *Session) Alias(alias string) *Session { + session.Statement.Alias(alias) + return session +} + // Method In provides a query string like "id in (1, 2, 3)" func (session *Session) In(column string, args ...interface{}) *Session { session.Statement.In(column, args...) @@ -257,7 +263,7 @@ func (session *Session) NoCache() *Session { } //The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN -func (session *Session) Join(join_operator, tablename, condition string) *Session { +func (session *Session) Join(join_operator string, tablename interface{}, condition string) *Session { session.Statement.Join(join_operator, tablename, condition) return session } diff --git a/statement.go b/statement.go index 12006128..141d49c5 100644 --- a/statement.go +++ b/statement.go @@ -55,6 +55,7 @@ type Statement struct { UseCache bool UseAutoTime bool IsDistinct bool + TableAlias string allUseBool bool checkVersion bool unscoped bool @@ -88,6 +89,7 @@ func (statement *Statement) Init() { statement.UseCache = true statement.UseAutoTime = true statement.IsDistinct = false + statement.TableAlias = "" statement.allUseBool = false statement.useAllCols = false statement.mustColumnMap = make(map[string]bool) @@ -105,6 +107,12 @@ func (statement *Statement) Sql(querystring string, args ...interface{}) *Statem return statement } +// set the table alias +func (statement *Statement) Alias(alias string) *Statement { + statement.TableAlias = alias + return statement +} + // add Where statment func (statement *Statement) Where(querystring string, args ...interface{}) *Statement { if !strings.Contains(querystring, statement.Engine.dialect.EqStr()) { @@ -145,6 +153,9 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement { t := v.Type() if t.Kind() == reflect.String { statement.AltTableName = tableNameOrBean.(string) + if statement.AltTableName[0] == '~' { + statement.AltTableName = statement.Engine.TableMapper.TableName(statement.AltTableName[1:]) + } } else if t.Kind() == reflect.Struct { statement.RefTable = statement.Engine.autoMapType(v) } @@ -912,13 +923,61 @@ func (statement *Statement) Asc(colNames ...string) *Statement { } //The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN -func (statement *Statement) Join(join_operator, tablename, condition string) *Statement { +func (statement *Statement) Join(join_operator string, tablename interface{}, condition string) *Statement { + var joinTable string + switch tablename.(type) { + case []string: + t := tablename.([]string) + l := len(t) + if l > 1 { + table := t[0] + if table[0] == '~' { + table = statement.Engine.TableMapper.TableName(table[1:]) + } + joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(t[1]) + } else if l == 1 { + table := t[0] + if table[0] == '~' { + table = statement.Engine.TableMapper.TableName(table[1:]) + } + joinTable = statement.Engine.Quote(table) + } + case []interface{}: + t := tablename.([]interface{}) + l := len(t) + table := "" + if l > 0 { + f := t[0] + v := rValue(f) + t := v.Type() + if t.Kind() == reflect.String { + table = f.(string) + if table[0] == '~' { + table = statement.Engine.TableMapper.TableName(table[1:]) + } + } else if t.Kind() == reflect.Struct { + r := statement.Engine.autoMapType(v) + table = r.Name + } + } + if l > 1 { + joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(fmt.Sprintf("%v", t[1])) + } else if l == 1 { + joinTable = statement.Engine.Quote(table) + } + default: + t := fmt.Sprintf("%v", tablename) + if t[0] == '~' { + t = statement.Engine.TableMapper.TableName(t[1:]) + } + joinTable = statement.Engine.Quote(t) + } if statement.JoinStr != "" { statement.JoinStr = statement.JoinStr + fmt.Sprintf(" %v JOIN %v ON %v", join_operator, - statement.Engine.Quote(tablename), condition) + joinTable, condition) } else { statement.JoinStr = fmt.Sprintf("%v JOIN %v ON %v", join_operator, - statement.Engine.Quote(tablename), condition) + joinTable, condition) } return statement } @@ -955,16 +1014,22 @@ func (statement *Statement) genColumnStr() string { } if statement.JoinStr != "" { - name := statement.Engine.Quote(statement.TableName()) + "." + statement.Engine.Quote(col.Name) + var name string + if statement.TableAlias != "" { + name = statement.Engine.Quote(statement.TableAlias) + } else { + name = statement.Engine.Quote(statement.TableName()) + } + name += "." + statement.Engine.Quote(col.Name) if col.IsPrimaryKey && statement.Engine.Dialect().DBType() == "ql" { - colNames = append(colNames, "id() as "+name) + colNames = append(colNames, "id() AS "+name) } else { colNames = append(colNames, name) } } else { name := statement.Engine.Quote(col.Name) if col.IsPrimaryKey && statement.Engine.Dialect().DBType() == "ql" { - colNames = append(colNames, "id() as "+name) + colNames = append(colNames, "id() AS "+name) } else { colNames = append(colNames, name) } @@ -1134,6 +1199,9 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) { whereStr = fmt.Sprintf(" WHERE %v", statement.ConditionStr) } var fromStr string = " FROM " + statement.Engine.Quote(statement.TableName()) + if statement.TableAlias != "" { + fromStr += " AS " + statement.Engine.Quote(statement.TableAlias) + } if statement.JoinStr != "" { fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr) }