Added all required dependencies
This commit is contained in:
parent
78f86abba4
commit
1ebb35b988
660 changed files with 502447 additions and 0 deletions
49
vendor/github.com/go-xorm/xorm/CONTRIBUTING.md
generated
vendored
Normal file
49
vendor/github.com/go-xorm/xorm/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
## Contributing to xorm
|
||||
|
||||
`xorm` has a backlog of [pull requests](https://help.github.com/articles/using-pull-requests), but contributions are still very
|
||||
much welcome. You can help with patch review, submitting bug reports,
|
||||
or adding new functionality. There is no formal style guide, but
|
||||
please conform to the style of existing code and general Go formatting
|
||||
conventions when submitting patches.
|
||||
|
||||
* [fork a repo](https://help.github.com/articles/fork-a-repo)
|
||||
* [creating a pull request ](https://help.github.com/articles/creating-a-pull-request)
|
||||
|
||||
### Language
|
||||
|
||||
Since `xorm` is a world-wide open source project, please describe your issues or code changes in English as soon as possible.
|
||||
|
||||
### Sign your codes with comments
|
||||
```
|
||||
// !<you github id>! your comments
|
||||
|
||||
e.g.,
|
||||
|
||||
// !lunny! this is comments made by lunny
|
||||
```
|
||||
|
||||
### Patch review
|
||||
|
||||
Help review existing open [pull requests](https://help.github.com/articles/using-pull-requests) by commenting on the code or
|
||||
proposed functionality.
|
||||
|
||||
### Bug reports
|
||||
|
||||
We appreciate any bug reports, but especially ones with self-contained
|
||||
(doesn't depend on code outside of xorm), minimal (can't be simplified
|
||||
further) test cases. It's especially helpful if you can submit a pull
|
||||
request with just the failing test case (you'll probably want to
|
||||
pattern it after the tests in
|
||||
[base.go](https://github.com/go-xorm/tests/blob/master/base.go) AND
|
||||
[benchmark.go](https://github.com/go-xorm/tests/blob/master/benchmark.go).
|
||||
|
||||
If you implements a new database interface, you maybe need to add a <databasename>_test.go file.
|
||||
For example, [mysql_test.go](https://github.com/go-xorm/tests/blob/master/mysql/mysql_test.go)
|
||||
|
||||
### New functionality
|
||||
|
||||
There are a number of pending patches for new functionality, so
|
||||
additional feature patches will take a while to merge. Still, patches
|
||||
are generally reviewed based on usefulness and complexity in addition
|
||||
to time-in-queue, so if you have a knockout idea, take a shot. Feel
|
||||
free to open an issue discussion your proposed patch beforehand.
|
27
vendor/github.com/go-xorm/xorm/LICENSE
generated
vendored
Normal file
27
vendor/github.com/go-xorm/xorm/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2013 - 2015 The Xorm Authors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the {organization} nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
289
vendor/github.com/go-xorm/xorm/README.md
generated
vendored
Normal file
289
vendor/github.com/go-xorm/xorm/README.md
generated
vendored
Normal file
|
@ -0,0 +1,289 @@
|
|||
[中文](https://github.com/go-xorm/xorm/blob/master/README_CN.md)
|
||||
|
||||
Xorm is a simple and powerful ORM for Go.
|
||||
|
||||
[](https://gitter.im/go-xorm/xorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
[](https://drone.io/github.com/go-xorm/tests/latest)
|
||||
|
||||
# Notice
|
||||
|
||||
The last master version is not backwards compatible. You should use `engine.ShowSQL()` and `engine.Logger().SetLevel()` instead of `engine.ShowSQL = `, `engine.ShowInfo = ` and so on.
|
||||
|
||||
# Features
|
||||
|
||||
* Struct <-> Table Mapping Support
|
||||
|
||||
* Chainable APIs
|
||||
|
||||
* Transaction Support
|
||||
|
||||
* Both ORM and raw SQL operation Support
|
||||
|
||||
* Sync database schema Support
|
||||
|
||||
* Query Cache speed up
|
||||
|
||||
* Database Reverse support, See [Xorm Tool README](https://github.com/go-xorm/cmd/blob/master/README.md)
|
||||
|
||||
* Simple cascade loading support
|
||||
|
||||
* Optimistic Locking support
|
||||
|
||||
* SQL Builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder)
|
||||
|
||||
# Drivers Support
|
||||
|
||||
Drivers for Go's sql package which currently support database/sql includes:
|
||||
|
||||
* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||
|
||||
* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
|
||||
|
||||
* Postgres: [github.com/lib/pq](https://github.com/lib/pq)
|
||||
|
||||
* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
|
||||
* MsSql: [github.com/lunny/godbc](https://github.com/lunny/godbc)
|
||||
|
||||
* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment)
|
||||
|
||||
# Changelog
|
||||
|
||||
* **v0.6.0**
|
||||
* remove support for ql
|
||||
* add query condition builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder), so `Where`, `And`, `Or`
|
||||
methods can use `builder.Cond` as parameter
|
||||
* add Sum, SumInt, SumInt64 and NotIn methods
|
||||
* some bugs fixed
|
||||
|
||||
* **v0.5.0**
|
||||
* logging interface changed
|
||||
* some bugs fixed
|
||||
|
||||
* **v0.4.5**
|
||||
* many bugs fixed
|
||||
* extends support unlimited deepth
|
||||
* Delete Limit support
|
||||
|
||||
* **v0.4.4**
|
||||
* ql database expriment support
|
||||
* tidb database expriment support
|
||||
* sql.NullString and etc. field support
|
||||
* select ForUpdate support
|
||||
* many bugs fixed
|
||||
|
||||
[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16)
|
||||
|
||||
# Installation
|
||||
|
||||
If you have [gopm](https://github.com/gpmgo/gopm) installed,
|
||||
|
||||
gopm get github.com/go-xorm/xorm
|
||||
|
||||
Or
|
||||
|
||||
go get github.com/go-xorm/xorm
|
||||
|
||||
# Documents
|
||||
|
||||
* [Manual](http://xorm.io/docs)
|
||||
|
||||
* [GoDoc](http://godoc.org/github.com/go-xorm/xorm)
|
||||
|
||||
* [GoWalker](http://gowalker.org/github.com/go-xorm/xorm)
|
||||
|
||||
# Quick Start
|
||||
|
||||
* Create Engine
|
||||
|
||||
```Go
|
||||
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||
```
|
||||
|
||||
* Define a struct and Sync2 table struct to database
|
||||
|
||||
```Go
|
||||
type User struct {
|
||||
Id int64
|
||||
Name string
|
||||
Salt string
|
||||
Age int
|
||||
Passwd string `xorm:"varchar(200)"`
|
||||
Created time.Time `xorm:"created"`
|
||||
Updated time.Time `xorm:"updated"`
|
||||
}
|
||||
|
||||
err := engine.Sync2(new(User))
|
||||
```
|
||||
|
||||
* Query a SQL string, the returned results is []map[string][]byte
|
||||
|
||||
```Go
|
||||
results, err := engine.Query("select * from user")
|
||||
```
|
||||
|
||||
* Execute a SQL string, the returned results
|
||||
|
||||
```Go
|
||||
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
|
||||
```
|
||||
|
||||
* Insert one or multiple records to database
|
||||
|
||||
```Go
|
||||
affected, err := engine.Insert(&user)
|
||||
// INSERT INTO struct () values ()
|
||||
affected, err := engine.Insert(&user1, &user2)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values ()
|
||||
affected, err := engine.Insert(&users)
|
||||
// INSERT INTO struct () values (),(),()
|
||||
affected, err := engine.Insert(&user1, &users)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values (),(),()
|
||||
```
|
||||
|
||||
* Query one record from database
|
||||
|
||||
```Go
|
||||
has, err := engine.Get(&user)
|
||||
// SELECT * FROM user LIMIT 1
|
||||
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
||||
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||
```
|
||||
|
||||
* Query multiple records from database, also you can use join and extends
|
||||
|
||||
```Go
|
||||
var users []User
|
||||
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
|
||||
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
|
||||
|
||||
type Detail struct {
|
||||
Id int64
|
||||
UserId int64 `xorm:"index"`
|
||||
}
|
||||
|
||||
type UserDetail struct {
|
||||
User `xorm:"extends"`
|
||||
Detail `xorm:"extends"`
|
||||
}
|
||||
|
||||
var users []UserDetail
|
||||
err := engine.Table("user").Select("user.*, detail.*")
|
||||
Join("INNER", "detail", "detail.user_id = user.id").
|
||||
Where("user.name = ?", name).Limit(10, 0).
|
||||
Find(&users)
|
||||
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
|
||||
```
|
||||
|
||||
* Query multiple records and record by record handle, there are two methods Iterate and Rows
|
||||
|
||||
```Go
|
||||
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
|
||||
user := bean.(*User)
|
||||
return nil
|
||||
})
|
||||
// SELECT * FROM user
|
||||
|
||||
rows, err := engine.Rows(&User{Name:name})
|
||||
// SELECT * FROM user
|
||||
defer rows.Close()
|
||||
bean := new(Struct)
|
||||
for rows.Next() {
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
```
|
||||
|
||||
* Update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on.
|
||||
|
||||
```Go
|
||||
affected, err := engine.Id(1).Update(&user)
|
||||
// UPDATE user SET ... Where id = ?
|
||||
|
||||
affected, err := engine.Update(&user, &User{Name:name})
|
||||
// UPDATE user SET ... Where name = ?
|
||||
|
||||
var ids = []int64{1, 2, 3}
|
||||
affected, err := engine.In("id", ids).Update(&user)
|
||||
// UPDATE user SET ... Where id IN (?, ?, ?)
|
||||
|
||||
// force update indicated columns by Cols
|
||||
affected, err := engine.Id(1).Cols("age").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
// force NOT update indicated columns by Omit
|
||||
affected, err := engine.Id(1).Omit("name").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
affected, err := engine.Id(1).AllCols().Update(&user)
|
||||
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
|
||||
```
|
||||
|
||||
* Delete one or more records, Delete MUST have condition
|
||||
|
||||
```Go
|
||||
affected, err := engine.Where(...).Delete(&user)
|
||||
// DELETE FROM user Where ...
|
||||
affected, err := engine.Id(2).Delete(&user)
|
||||
```
|
||||
|
||||
* Count records
|
||||
|
||||
```Go
|
||||
counts, err := engine.Count(&user)
|
||||
// SELECT count(*) AS total FROM user
|
||||
```
|
||||
|
||||
* Query conditions builder
|
||||
|
||||
```Go
|
||||
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
|
||||
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
|
||||
```
|
||||
|
||||
# Cases
|
||||
|
||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [Docker.cn](https://docker.cn/)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
|
||||
* [Gorevel](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)
|
||||
|
||||
* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress)
|
||||
|
||||
* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily)
|
||||
|
||||
* [YouGam](http://www.yougam.com/)
|
||||
|
||||
* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS)
|
||||
|
||||
* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/)
|
||||
|
||||
* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog)
|
||||
|
||||
# Discuss
|
||||
|
||||
Please visit [Xorm on Google Groups](https://groups.google.com/forum/#!forum/xorm)
|
||||
|
||||
# Contributing
|
||||
|
||||
If you want to pull request, please see [CONTRIBUTING](https://github.com/go-xorm/xorm/blob/master/CONTRIBUTING.md)
|
||||
|
||||
# LICENSE
|
||||
|
||||
BSD License
|
||||
[http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
|
288
vendor/github.com/go-xorm/xorm/README_CN.md
generated
vendored
Normal file
288
vendor/github.com/go-xorm/xorm/README_CN.md
generated
vendored
Normal file
|
@ -0,0 +1,288 @@
|
|||
# xorm
|
||||
|
||||
[English](https://github.com/go-xorm/xorm/blob/master/README.md)
|
||||
|
||||
xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。
|
||||
|
||||
[](https://gitter.im/go-xorm/xorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
[](https://drone.io/github.com/go-xorm/tests/latest) [](http://gowalker.org/github.com/go-xorm/xorm)
|
||||
|
||||
# 注意
|
||||
|
||||
最新的版本有不兼容的更新,您必须使用 `engine.ShowSQL()` 和 `engine.Logger().SetLevel()` 来替代 `engine.ShowSQL = `, `engine.ShowInfo = ` 等等。
|
||||
|
||||
## 特性
|
||||
|
||||
* 支持Struct和数据库表之间的灵活映射,并支持自动同步
|
||||
|
||||
* 事务支持
|
||||
|
||||
* 同时支持原始SQL语句和ORM操作的混合执行
|
||||
|
||||
* 使用连写来简化调用
|
||||
|
||||
* 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函数和结构体等方式作为条件
|
||||
|
||||
* 支持级联加载Struct
|
||||
|
||||
* 支持缓存
|
||||
|
||||
* 支持根据数据库自动生成xorm的结构体
|
||||
|
||||
* 支持记录版本(即乐观锁)
|
||||
|
||||
* 内置SQL Builder支持
|
||||
|
||||
## 驱动支持
|
||||
|
||||
目前支持的Go数据库驱动和对应的数据库如下:
|
||||
|
||||
* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)
|
||||
|
||||
* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
|
||||
|
||||
* Postgres: [github.com/lib/pq](https://github.com/lib/pq)
|
||||
|
||||
* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
|
||||
* MsSql: [github.com/lunny/godbc](https://github.com/lunny/godbc)
|
||||
|
||||
* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持)
|
||||
|
||||
## 更新日志
|
||||
|
||||
* **v0.6.0**
|
||||
* 去除对 ql 的支持
|
||||
* 新增条件查询分析器 [github.com/go-xorm/builder](https://github.com/go-xorm/builder), 从因此 `Where, And, Or` 函数
|
||||
将可以用 `builder.Cond` 作为条件组合
|
||||
* 新增 Sum, SumInt, SumInt64 和 NotIn 函数
|
||||
* Bug修正
|
||||
|
||||
* **v0.5.0**
|
||||
* logging接口进行不兼容改变
|
||||
* Bug修正
|
||||
|
||||
* **v0.4.5**
|
||||
* bug修正
|
||||
* extends 支持无限级
|
||||
* Delete Limit 支持
|
||||
|
||||
* **v0.4.4**
|
||||
* Tidb 数据库支持
|
||||
* QL 试验性支持
|
||||
* sql.NullString支持
|
||||
* ForUpdate 支持
|
||||
* bug修正
|
||||
|
||||
[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16)
|
||||
|
||||
## 安装
|
||||
|
||||
推荐使用 [gopm](https://github.com/gpmgo/gopm) 进行安装:
|
||||
|
||||
gopm get github.com/go-xorm/xorm
|
||||
|
||||
或者您也可以使用go工具进行安装:
|
||||
|
||||
go get github.com/go-xorm/xorm
|
||||
|
||||
## 文档
|
||||
|
||||
* [操作指南](http://xorm.io/docs)
|
||||
|
||||
* [GoWalker代码文档](http://gowalker.org/github.com/go-xorm/xorm)
|
||||
|
||||
* [Godoc代码文档](http://godoc.org/github.com/go-xorm/xorm)
|
||||
|
||||
# 快速开始
|
||||
|
||||
* 第一步创建引擎,driverName, dataSourceName和database/sql接口相同
|
||||
|
||||
```Go
|
||||
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||
```
|
||||
|
||||
* 定义一个和表同步的结构体,并且自动同步结构体到数据库
|
||||
|
||||
```Go
|
||||
type User struct {
|
||||
Id int64
|
||||
Name string
|
||||
Salt string
|
||||
Age int
|
||||
Passwd string `xorm:"varchar(200)"`
|
||||
Created time.Time `xorm:"created"`
|
||||
Updated time.Time `xorm:"updated"`
|
||||
}
|
||||
|
||||
err := engine.Sync2(new(User))
|
||||
```
|
||||
|
||||
* 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte
|
||||
|
||||
```Go
|
||||
results, err := engine.Query("select * from user")
|
||||
```
|
||||
|
||||
* 执行一个SQL语句
|
||||
|
||||
```Go
|
||||
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
|
||||
```
|
||||
|
||||
* 插入一条或者多条记录
|
||||
|
||||
```Go
|
||||
affected, err := engine.Insert(&user)
|
||||
// INSERT INTO struct () values ()
|
||||
affected, err := engine.Insert(&user1, &user2)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values ()
|
||||
affected, err := engine.Insert(&users)
|
||||
// INSERT INTO struct () values (),(),()
|
||||
affected, err := engine.Insert(&user1, &users)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values (),(),()
|
||||
```
|
||||
|
||||
* 查询单条记录
|
||||
|
||||
```Go
|
||||
has, err := engine.Get(&user)
|
||||
// SELECT * FROM user LIMIT 1
|
||||
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
||||
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||
```
|
||||
|
||||
* 查询多条记录,当然可以使用Join和extends来组合使用
|
||||
|
||||
```Go
|
||||
var users []User
|
||||
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
|
||||
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
|
||||
|
||||
type Detail struct {
|
||||
Id int64
|
||||
UserId int64 `xorm:"index"`
|
||||
}
|
||||
|
||||
type UserDetail struct {
|
||||
User `xorm:"extends"`
|
||||
Detail `xorm:"extends"`
|
||||
}
|
||||
|
||||
var users []UserDetail
|
||||
err := engine.Table("user").Select("user.*, detail.*")
|
||||
Join("INNER", "detail", "detail.user_id = user.id").
|
||||
Where("user.name = ?", name).Limit(10, 0).
|
||||
Find(&users)
|
||||
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
|
||||
```
|
||||
|
||||
* 根据条件遍历数据库,可以有两种方式: Iterate and Rows
|
||||
|
||||
```Go
|
||||
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
|
||||
user := bean.(*User)
|
||||
return nil
|
||||
})
|
||||
// SELECT * FROM user
|
||||
|
||||
rows, err := engine.Rows(&User{Name:name})
|
||||
// SELECT * FROM user
|
||||
defer rows.Close()
|
||||
bean := new(Struct)
|
||||
for rows.Next() {
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
```
|
||||
|
||||
* 更新数据,除非使用Cols,AllCols函数指明,默认只更新非空和非0的字段
|
||||
|
||||
```Go
|
||||
affected, err := engine.Id(1).Update(&user)
|
||||
// UPDATE user SET ... Where id = ?
|
||||
|
||||
affected, err := engine.Update(&user, &User{Name:name})
|
||||
// UPDATE user SET ... Where name = ?
|
||||
|
||||
var ids = []int64{1, 2, 3}
|
||||
affected, err := engine.In(ids).Update(&user)
|
||||
// UPDATE user SET ... Where id IN (?, ?, ?)
|
||||
|
||||
// force update indicated columns by Cols
|
||||
affected, err := engine.Id(1).Cols("age").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
// force NOT update indicated columns by Omit
|
||||
affected, err := engine.Id(1).Omit("name").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
affected, err := engine.Id(1).AllCols().Update(&user)
|
||||
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
|
||||
```
|
||||
|
||||
* 删除记录,需要注意,删除必须至少有一个条件,否则会报错。要清空数据库可以用EmptyTable
|
||||
|
||||
```Go
|
||||
affected, err := engine.Where(...).Delete(&user)
|
||||
// DELETE FROM user Where ...
|
||||
```
|
||||
|
||||
* 获取记录条数
|
||||
|
||||
```Go
|
||||
counts, err := engine.Count(&user)
|
||||
// SELECT count(*) AS total FROM user
|
||||
```
|
||||
|
||||
* 条件编辑器
|
||||
|
||||
```Go
|
||||
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
|
||||
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
|
||||
```
|
||||
|
||||
# 案例
|
||||
|
||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [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)
|
||||
|
||||
* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild)
|
||||
|
||||
* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress)
|
||||
|
||||
* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily)
|
||||
|
||||
* [YouGam](http://www.yougam.com/)
|
||||
|
||||
* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS)
|
||||
|
||||
* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/)
|
||||
|
||||
* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog)
|
||||
|
||||
## 讨论
|
||||
|
||||
请加入QQ群:280360085 进行讨论。
|
||||
|
||||
## 贡献
|
||||
|
||||
如果您也想为Xorm贡献您的力量,请查看 [CONTRIBUTING](https://github.com/go-xorm/xorm/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## LICENSE
|
||||
|
||||
BSD License
|
||||
[http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)
|
1
vendor/github.com/go-xorm/xorm/VERSION
generated
vendored
Normal file
1
vendor/github.com/go-xorm/xorm/VERSION
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
xorm v0.6.0.1022
|
158
vendor/github.com/go-xorm/xorm/doc.go
generated
vendored
Normal file
158
vendor/github.com/go-xorm/xorm/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
// Copyright 2013 - 2016 The XORM Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
|
||||
Package xorm is a simple and powerful ORM for Go.
|
||||
|
||||
Installation
|
||||
|
||||
Make sure you have installed Go 1.1+ and then:
|
||||
|
||||
go get github.com/go-xorm/xorm
|
||||
|
||||
Create Engine
|
||||
|
||||
Firstly, we should new an engine for a database
|
||||
|
||||
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||
|
||||
Method NewEngine's parameters is the same as sql.Open. It depends
|
||||
drivers' implementation.
|
||||
Generally, one engine for an application is enough. You can set it as package variable.
|
||||
|
||||
Raw Methods
|
||||
|
||||
Xorm also support raw sql execution:
|
||||
|
||||
1. query a SQL string, the returned results is []map[string][]byte
|
||||
|
||||
results, err := engine.Query("select * from user")
|
||||
|
||||
2. execute a SQL string, the returned results
|
||||
|
||||
affected, err := engine.Exec("update user set .... where ...")
|
||||
|
||||
ORM Methods
|
||||
|
||||
There are 7 major ORM methods and many helpful methods to use to operate database.
|
||||
|
||||
1. Insert one or multipe records to database
|
||||
|
||||
affected, err := engine.Insert(&struct)
|
||||
// INSERT INTO struct () values ()
|
||||
affected, err := engine.Insert(&struct1, &struct2)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values ()
|
||||
affected, err := engine.Insert(&sliceOfStruct)
|
||||
// INSERT INTO struct () values (),(),()
|
||||
affected, err := engine.Insert(&struct1, &sliceOfStruct2)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values (),(),()
|
||||
|
||||
2. Query one record from database
|
||||
|
||||
has, err := engine.Get(&user)
|
||||
// SELECT * FROM user LIMIT 1
|
||||
|
||||
3. Query multiple records from database
|
||||
|
||||
sliceOfStructs := new(Struct)
|
||||
err := engine.Find(sliceOfStructs)
|
||||
// SELECT * FROM user
|
||||
|
||||
4. Query multiple records and record by record handle, there two methods, one is Iterate,
|
||||
another is Rows
|
||||
|
||||
err := engine.Iterate(...)
|
||||
// SELECT * FROM user
|
||||
|
||||
rows, err := engine.Rows(...)
|
||||
// SELECT * FROM user
|
||||
defer rows.Close()
|
||||
bean := new(Struct)
|
||||
for rows.Next() {
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
|
||||
5. Update one or more records
|
||||
|
||||
affected, err := engine.Id(...).Update(&user)
|
||||
// UPDATE user SET ...
|
||||
|
||||
6. Delete one or more records, Delete MUST has conditon
|
||||
|
||||
affected, err := engine.Where(...).Delete(&user)
|
||||
// DELETE FROM user Where ...
|
||||
|
||||
7. Count records
|
||||
|
||||
counts, err := engine.Count(&user)
|
||||
// SELECT count(*) AS total FROM user
|
||||
|
||||
Conditions
|
||||
|
||||
The above 7 methods could use with condition methods chainable.
|
||||
Attention: the above 7 methods should be the last chainable method.
|
||||
|
||||
1. Id, In
|
||||
|
||||
engine.Id(1).Get(&user) // for single primary key
|
||||
// SELECT * FROM user WHERE id = 1
|
||||
engine.Id(core.PK{1, 2}).Get(&user) // for composite primary keys
|
||||
// SELECT * FROM user WHERE id1 = 1 AND id2 = 2
|
||||
engine.In("id", 1, 2, 3).Find(&users)
|
||||
// SELECT * FROM user WHERE id IN (1, 2, 3)
|
||||
engine.In("id", []int{1, 2, 3})
|
||||
// SELECT * FROM user WHERE id IN (1, 2, 3)
|
||||
|
||||
2. Where, And, Or
|
||||
|
||||
engine.Where().And().Or().Find()
|
||||
// SELECT * FROM user WHERE (.. AND ..) OR ...
|
||||
|
||||
3. OrderBy, Asc, Desc
|
||||
|
||||
engine.Asc().Desc().Find()
|
||||
// SELECT * FROM user ORDER BY .. ASC, .. DESC
|
||||
engine.OrderBy().Find()
|
||||
// SELECT * FROM user ORDER BY ..
|
||||
|
||||
4. Limit, Top
|
||||
|
||||
engine.Limit().Find()
|
||||
// SELECT * FROM user LIMIT .. OFFSET ..
|
||||
engine.Top(5).Find()
|
||||
// SELECT TOP 5 * FROM user // for mssql
|
||||
// SELECT * FROM user LIMIT .. OFFSET 0 //for other databases
|
||||
|
||||
5. Sql, let you custom SQL
|
||||
|
||||
var users []User
|
||||
engine.Sql("select * from user").Find(&users)
|
||||
|
||||
6. Cols, Omit, Distinct
|
||||
|
||||
var users []*User
|
||||
engine.Cols("col1, col2").Find(&users)
|
||||
// SELECT col1, col2 FROM user
|
||||
engine.Cols("col1", "col2").Where().Update(user)
|
||||
// UPDATE user set col1 = ?, col2 = ? Where ...
|
||||
engine.Omit("col1").Find(&users)
|
||||
// SELECT col2, col3 FROM user
|
||||
engine.Omit("col1").Insert(&user)
|
||||
// INSERT INTO table (non-col1) VALUES ()
|
||||
engine.Distinct("col1").Find(&users)
|
||||
// SELECT DISTINCT col1 FROM user
|
||||
|
||||
7. Join, GroupBy, Having
|
||||
|
||||
engine.GroupBy("name").Having("name='xlw'").Find(&users)
|
||||
//SELECT * FROM user GROUP BY name HAVING name='xlw'
|
||||
engine.Join("LEFT", "userdetail", "user.id=userdetail.id").Find(&users)
|
||||
//SELECT * FROM user LEFT JOIN userdetail ON user.id=userdetail.id
|
||||
|
||||
More usage, please visit http://xorm.io/docs
|
||||
*/
|
||||
package xorm
|
1689
vendor/github.com/go-xorm/xorm/engine.go
generated
vendored
Normal file
1689
vendor/github.com/go-xorm/xorm/engine.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
19
vendor/github.com/go-xorm/xorm/error.go
generated
vendored
Normal file
19
vendor/github.com/go-xorm/xorm/error.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrParamsType error = errors.New("Params type error")
|
||||
ErrTableNotFound error = errors.New("Not found table")
|
||||
ErrUnSupportedType error = errors.New("Unsupported type error")
|
||||
ErrNotExist error = errors.New("Not exist error")
|
||||
ErrCacheFailed error = errors.New("Cache failed")
|
||||
ErrNeedDeletedCond error = errors.New("Delete need at least one condition")
|
||||
ErrNotImplemented error = errors.New("Not implemented.")
|
||||
)
|
6
vendor/github.com/go-xorm/xorm/gen_reserved.sh
generated
vendored
Executable file
6
vendor/github.com/go-xorm/xorm/gen_reserved.sh
generated
vendored
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
if [ -f $1 ];then
|
||||
cat $1| awk '{printf("\""$1"\":true,\n")}'
|
||||
else
|
||||
echo "argument $1 if not a file!"
|
||||
fi
|
42
vendor/github.com/go-xorm/xorm/goracle_driver.go
generated
vendored
Normal file
42
vendor/github.com/go-xorm/xorm/goracle_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// func init() {
|
||||
// core.RegisterDriver("goracle", &goracleDriver{})
|
||||
// }
|
||||
|
||||
type goracleDriver struct {
|
||||
}
|
||||
|
||||
func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.ORACLE}
|
||||
dsnPattern := regexp.MustCompile(
|
||||
`^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
|
||||
`(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
|
||||
`\/(?P<dbname>.*?)` + // /dbname
|
||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
||||
names := dsnPattern.SubexpNames()
|
||||
|
||||
for i, match := range matches {
|
||||
switch names[i] {
|
||||
case "dbname":
|
||||
db.DbName = match
|
||||
}
|
||||
}
|
||||
if db.DbName == "" {
|
||||
return nil, errors.New("dbname is empty")
|
||||
}
|
||||
return db, nil
|
||||
}
|
580
vendor/github.com/go-xorm/xorm/helpers.go
generated
vendored
Normal file
580
vendor/github.com/go-xorm/xorm/helpers.go
generated
vendored
Normal file
|
@ -0,0 +1,580 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// str2PK convert string value to primary key value according to tp
|
||||
func str2PK(s string, tp reflect.Type) (interface{}, error) {
|
||||
var err error
|
||||
var result interface{}
|
||||
switch tp.Kind() {
|
||||
case reflect.Int:
|
||||
result, err = strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as int: " + err.Error())
|
||||
}
|
||||
case reflect.Int8:
|
||||
x, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as int16: " + err.Error())
|
||||
}
|
||||
result = int8(x)
|
||||
case reflect.Int16:
|
||||
x, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as int16: " + err.Error())
|
||||
}
|
||||
result = int16(x)
|
||||
case reflect.Int32:
|
||||
x, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as int32: " + err.Error())
|
||||
}
|
||||
result = int32(x)
|
||||
case reflect.Int64:
|
||||
result, err = strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as int64: " + err.Error())
|
||||
}
|
||||
case reflect.Uint:
|
||||
x, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as uint: " + err.Error())
|
||||
}
|
||||
result = uint(x)
|
||||
case reflect.Uint8:
|
||||
x, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as uint8: " + err.Error())
|
||||
}
|
||||
result = uint8(x)
|
||||
case reflect.Uint16:
|
||||
x, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as uint16: " + err.Error())
|
||||
}
|
||||
result = uint16(x)
|
||||
case reflect.Uint32:
|
||||
x, err := strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as uint32: " + err.Error())
|
||||
}
|
||||
result = uint32(x)
|
||||
case reflect.Uint64:
|
||||
result, err = strconv.ParseUint(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.New("convert " + s + " as uint64: " + err.Error())
|
||||
}
|
||||
case reflect.String:
|
||||
result = s
|
||||
default:
|
||||
panic("unsupported convert type")
|
||||
}
|
||||
result = reflect.ValueOf(result).Convert(tp).Interface()
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func splitTag(tag string) (tags []string) {
|
||||
tag = strings.TrimSpace(tag)
|
||||
var hasQuote = false
|
||||
var lastIdx = 0
|
||||
for i, t := range tag {
|
||||
if t == '\'' {
|
||||
hasQuote = !hasQuote
|
||||
} else if t == ' ' {
|
||||
if lastIdx < i && !hasQuote {
|
||||
tags = append(tags, strings.TrimSpace(tag[lastIdx:i]))
|
||||
lastIdx = i + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if lastIdx < len(tag) {
|
||||
tags = append(tags, strings.TrimSpace(tag[lastIdx:len(tag)]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type zeroable interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func isZero(k interface{}) bool {
|
||||
switch k.(type) {
|
||||
case int:
|
||||
return k.(int) == 0
|
||||
case int8:
|
||||
return k.(int8) == 0
|
||||
case int16:
|
||||
return k.(int16) == 0
|
||||
case int32:
|
||||
return k.(int32) == 0
|
||||
case int64:
|
||||
return k.(int64) == 0
|
||||
case uint:
|
||||
return k.(uint) == 0
|
||||
case uint8:
|
||||
return k.(uint8) == 0
|
||||
case uint16:
|
||||
return k.(uint16) == 0
|
||||
case uint32:
|
||||
return k.(uint32) == 0
|
||||
case uint64:
|
||||
return k.(uint64) == 0
|
||||
case float32:
|
||||
return k.(float32) == 0
|
||||
case float64:
|
||||
return k.(float64) == 0
|
||||
case bool:
|
||||
return k.(bool) == false
|
||||
case string:
|
||||
return k.(string) == ""
|
||||
case zeroable:
|
||||
return k.(zeroable).IsZero()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isStructZero(v reflect.Value) bool {
|
||||
if !v.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
switch field.Kind() {
|
||||
case reflect.Ptr:
|
||||
field = field.Elem()
|
||||
fallthrough
|
||||
case reflect.Struct:
|
||||
if !isStructZero(field) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if field.CanInterface() && !isZero(field.Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func int64ToIntValue(id int64, tp reflect.Type) reflect.Value {
|
||||
var v interface{}
|
||||
switch tp.Kind() {
|
||||
case reflect.Int16:
|
||||
v = int16(id)
|
||||
case reflect.Int32:
|
||||
v = int32(id)
|
||||
case reflect.Int:
|
||||
v = int(id)
|
||||
case reflect.Int64:
|
||||
v = id
|
||||
case reflect.Uint16:
|
||||
v = uint16(id)
|
||||
case reflect.Uint32:
|
||||
v = uint32(id)
|
||||
case reflect.Uint64:
|
||||
v = uint64(id)
|
||||
case reflect.Uint:
|
||||
v = uint(id)
|
||||
}
|
||||
return reflect.ValueOf(v).Convert(tp)
|
||||
}
|
||||
|
||||
func int64ToInt(id int64, tp reflect.Type) interface{} {
|
||||
return int64ToIntValue(id, tp).Interface()
|
||||
}
|
||||
|
||||
func isPKZero(pk core.PK) bool {
|
||||
for _, k := range pk {
|
||||
if isZero(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func indexNoCase(s, sep string) int {
|
||||
return strings.Index(strings.ToLower(s), strings.ToLower(sep))
|
||||
}
|
||||
|
||||
func splitNoCase(s, sep string) []string {
|
||||
idx := indexNoCase(s, sep)
|
||||
if idx < 0 {
|
||||
return []string{s}
|
||||
}
|
||||
return strings.Split(s, s[idx:idx+len(sep)])
|
||||
}
|
||||
|
||||
func splitNNoCase(s, sep string, n int) []string {
|
||||
idx := indexNoCase(s, sep)
|
||||
if idx < 0 {
|
||||
return []string{s}
|
||||
}
|
||||
return strings.SplitN(s, s[idx:idx+len(sep)], n)
|
||||
}
|
||||
|
||||
func makeArray(elem string, count int) []string {
|
||||
res := make([]string, count)
|
||||
for i := 0; i < count; i++ {
|
||||
res[i] = elem
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func rValue(bean interface{}) reflect.Value {
|
||||
return reflect.Indirect(reflect.ValueOf(bean))
|
||||
}
|
||||
|
||||
func rType(bean interface{}) reflect.Type {
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
//return reflect.TypeOf(sliceValue.Interface())
|
||||
return sliceValue.Type()
|
||||
}
|
||||
|
||||
func structName(v reflect.Type) string {
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
return v.Name()
|
||||
}
|
||||
|
||||
func col2NewCols(columns ...string) []string {
|
||||
newColumns := make([]string, 0, len(columns))
|
||||
for _, col := range columns {
|
||||
col = strings.Replace(col, "`", "", -1)
|
||||
col = strings.Replace(col, `"`, "", -1)
|
||||
ccols := strings.Split(col, ",")
|
||||
for _, c := range ccols {
|
||||
newColumns = append(newColumns, strings.TrimSpace(c))
|
||||
}
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
|
||||
func sliceEq(left, right []string) bool {
|
||||
if len(left) != len(right) {
|
||||
return false
|
||||
}
|
||||
sort.Sort(sort.StringSlice(left))
|
||||
sort.Sort(sort.StringSlice(right))
|
||||
for i := 0; i < len(left); i++ {
|
||||
if left[i] != right[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func reflect2value(rawValue *reflect.Value) (str string, err error) {
|
||||
aa := reflect.TypeOf((*rawValue).Interface())
|
||||
vv := reflect.ValueOf((*rawValue).Interface())
|
||||
switch aa.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
str = strconv.FormatInt(vv.Int(), 10)
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
str = strconv.FormatUint(vv.Uint(), 10)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
|
||||
case reflect.String:
|
||||
str = vv.String()
|
||||
case reflect.Array, reflect.Slice:
|
||||
switch aa.Elem().Kind() {
|
||||
case reflect.Uint8:
|
||||
data := rawValue.Interface().([]byte)
|
||||
str = string(data)
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
// time type
|
||||
case reflect.Struct:
|
||||
if aa.ConvertibleTo(core.TimeType) {
|
||||
str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
|
||||
} else {
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
case reflect.Bool:
|
||||
str = strconv.FormatBool(vv.Bool())
|
||||
case reflect.Complex128, reflect.Complex64:
|
||||
str = fmt.Sprintf("%v", vv.Complex())
|
||||
/* TODO: unsupported types below
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.Uintptr:
|
||||
case reflect.UnsafePointer:
|
||||
case reflect.Chan, reflect.Func, reflect.Interface:
|
||||
*/
|
||||
default:
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func value2Bytes(rawValue *reflect.Value) (data []byte, err error) {
|
||||
var str string
|
||||
str, err = reflect2value(rawValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
data = []byte(str)
|
||||
return
|
||||
}
|
||||
|
||||
func value2String(rawValue *reflect.Value) (data string, err error) {
|
||||
data, err = reflect2value(rawValue)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func rows2Strings(rows *core.Rows) (resultsSlice []map[string]string, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
result, err := row2mapStr(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, result)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
|
||||
fields, err := rows.Columns()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
result, err := row2map(rows, fields)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resultsSlice = append(resultsSlice, result)
|
||||
}
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
|
||||
result := make(map[string][]byte)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
|
||||
result := make(map[string]string)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2String(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) {
|
||||
rows, err := tx.Query(sqlStr, params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func query2(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) {
|
||||
s, err := db.Prepare(sqlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.Close()
|
||||
rows, err := s.Query(params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func setColumnInt(bean interface{}, col *core.Column, t int64) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t)
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setColumnTime(bean interface{}, col *core.Column, t time.Time) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
v.Set(reflect.ValueOf(t).Convert(v.Type()))
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t.Unix())
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t.Unix()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, includeQuote bool) ([]string, []interface{}, error) {
|
||||
colNames := make([]string, 0, len(table.ColumnsSeq()))
|
||||
args := make([]interface{}, 0, len(table.ColumnsSeq()))
|
||||
|
||||
for _, col := range table.Columns() {
|
||||
lColName := strings.ToLower(col.Name)
|
||||
if useCol && !col.IsVersion && !col.IsCreated && !col.IsUpdated {
|
||||
if _, ok := session.Statement.columnMap[lColName]; !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if col.MapType == core.ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
fieldValue := *fieldValuePtr
|
||||
|
||||
if col.IsAutoIncrement {
|
||||
switch fieldValue.Type().Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
|
||||
if fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
|
||||
if fieldValue.Uint() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.String:
|
||||
if len(fieldValue.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
|
||||
if session.Statement.ColumnStr != "" {
|
||||
if _, ok := session.Statement.columnMap[lColName]; !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if session.Statement.OmitStr != "" {
|
||||
if _, ok := session.Statement.columnMap[lColName]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := session.Statement.nullableMap[lColName]; ok {
|
||||
if col.Nullable && isZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsCreated || col.IsUpdated) && session.Statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t := session.Engine.NowTime2(col.SQLType.Name)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.Statement.checkVersion {
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
arg, err := session.value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
}
|
||||
args = append(args, arg)
|
||||
}
|
||||
|
||||
if includeQuote {
|
||||
colNames = append(colNames, session.Engine.Quote(col.Name)+" = ?")
|
||||
} else {
|
||||
colNames = append(colNames, col.Name)
|
||||
}
|
||||
}
|
||||
return colNames, args, nil
|
||||
}
|
||||
|
||||
func indexName(tableName, idxName string) string {
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
|
||||
}
|
162
vendor/github.com/go-xorm/xorm/logger.go
generated
vendored
Normal file
162
vendor/github.com/go-xorm/xorm/logger.go
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
const (
|
||||
DEFAULT_LOG_PREFIX = "[xorm]"
|
||||
DEFAULT_LOG_FLAG = log.Ldate | log.Lmicroseconds
|
||||
DEFAULT_LOG_LEVEL = core.LOG_DEBUG
|
||||
)
|
||||
|
||||
var _ core.ILogger = DiscardLogger{}
|
||||
|
||||
type DiscardLogger struct{}
|
||||
|
||||
func (DiscardLogger) Debug(v ...interface{}) {}
|
||||
func (DiscardLogger) Debugf(format string, v ...interface{}) {}
|
||||
func (DiscardLogger) Error(v ...interface{}) {}
|
||||
func (DiscardLogger) Errorf(format string, v ...interface{}) {}
|
||||
func (DiscardLogger) Info(v ...interface{}) {}
|
||||
func (DiscardLogger) Infof(format string, v ...interface{}) {}
|
||||
func (DiscardLogger) Warn(v ...interface{}) {}
|
||||
func (DiscardLogger) Warnf(format string, v ...interface{}) {}
|
||||
func (DiscardLogger) Level() core.LogLevel {
|
||||
return core.LOG_UNKNOWN
|
||||
}
|
||||
func (DiscardLogger) SetLevel(l core.LogLevel) {}
|
||||
func (DiscardLogger) ShowSQL(show ...bool) {}
|
||||
func (DiscardLogger) IsShowSQL() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SimpleLogger is the default implment of core.ILogger
|
||||
type SimpleLogger struct {
|
||||
DEBUG *log.Logger
|
||||
ERR *log.Logger
|
||||
INFO *log.Logger
|
||||
WARN *log.Logger
|
||||
level core.LogLevel
|
||||
showSQL bool
|
||||
}
|
||||
|
||||
var _ core.ILogger = &SimpleLogger{}
|
||||
|
||||
// NewSimpleLogger use a special io.Writer as logger output
|
||||
func NewSimpleLogger(out io.Writer) *SimpleLogger {
|
||||
return NewSimpleLogger2(out, DEFAULT_LOG_PREFIX, DEFAULT_LOG_FLAG)
|
||||
}
|
||||
|
||||
// NewSimpleLogger2 let you customrize your logger prefix and flag
|
||||
func NewSimpleLogger2(out io.Writer, prefix string, flag int) *SimpleLogger {
|
||||
return NewSimpleLogger3(out, prefix, flag, DEFAULT_LOG_LEVEL)
|
||||
}
|
||||
|
||||
// NewSimpleLogger3 let you customrize your logger prefix and flag and logLevel
|
||||
func NewSimpleLogger3(out io.Writer, prefix string, flag int, l core.LogLevel) *SimpleLogger {
|
||||
return &SimpleLogger{
|
||||
DEBUG: log.New(out, fmt.Sprintf("%s [debug] ", prefix), flag),
|
||||
ERR: log.New(out, fmt.Sprintf("%s [error] ", prefix), flag),
|
||||
INFO: log.New(out, fmt.Sprintf("%s [info] ", prefix), flag),
|
||||
WARN: log.New(out, fmt.Sprintf("%s [warn] ", prefix), flag),
|
||||
level: l,
|
||||
}
|
||||
}
|
||||
|
||||
// Error implement core.ILogger
|
||||
func (s *SimpleLogger) Error(v ...interface{}) {
|
||||
if s.level <= core.LOG_ERR {
|
||||
s.ERR.Output(2, fmt.Sprint(v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Errorf implement core.ILogger
|
||||
func (s *SimpleLogger) Errorf(format string, v ...interface{}) {
|
||||
if s.level <= core.LOG_ERR {
|
||||
s.ERR.Output(2, fmt.Sprintf(format, v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Debug implement core.ILogger
|
||||
func (s *SimpleLogger) Debug(v ...interface{}) {
|
||||
if s.level <= core.LOG_DEBUG {
|
||||
s.DEBUG.Output(2, fmt.Sprint(v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Debugf implement core.ILogger
|
||||
func (s *SimpleLogger) Debugf(format string, v ...interface{}) {
|
||||
if s.level <= core.LOG_DEBUG {
|
||||
s.DEBUG.Output(2, fmt.Sprintf(format, v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Info implement core.ILogger
|
||||
func (s *SimpleLogger) Info(v ...interface{}) {
|
||||
if s.level <= core.LOG_INFO {
|
||||
s.INFO.Output(2, fmt.Sprint(v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Infof implement core.ILogger
|
||||
func (s *SimpleLogger) Infof(format string, v ...interface{}) {
|
||||
if s.level <= core.LOG_INFO {
|
||||
s.INFO.Output(2, fmt.Sprintf(format, v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Warn implement core.ILogger
|
||||
func (s *SimpleLogger) Warn(v ...interface{}) {
|
||||
if s.level <= core.LOG_WARNING {
|
||||
s.WARN.Output(2, fmt.Sprint(v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Warnf implement core.ILogger
|
||||
func (s *SimpleLogger) Warnf(format string, v ...interface{}) {
|
||||
if s.level <= core.LOG_WARNING {
|
||||
s.WARN.Output(2, fmt.Sprintf(format, v...))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Level implement core.ILogger
|
||||
func (s *SimpleLogger) Level() core.LogLevel {
|
||||
return s.level
|
||||
}
|
||||
|
||||
// SetLevel implement core.ILogger
|
||||
func (s *SimpleLogger) SetLevel(l core.LogLevel) {
|
||||
s.level = l
|
||||
return
|
||||
}
|
||||
|
||||
// ShowSQL implement core.ILogger
|
||||
func (s *SimpleLogger) ShowSQL(show ...bool) {
|
||||
if len(show) == 0 {
|
||||
s.showSQL = true
|
||||
return
|
||||
}
|
||||
s.showSQL = show[0]
|
||||
}
|
||||
|
||||
// IsShowSQL implement core.ILogger
|
||||
func (s *SimpleLogger) IsShowSQL() bool {
|
||||
return s.showSQL
|
||||
}
|
289
vendor/github.com/go-xorm/xorm/lru_cacher.go
generated
vendored
Normal file
289
vendor/github.com/go-xorm/xorm/lru_cacher.go
generated
vendored
Normal file
|
@ -0,0 +1,289 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type LRUCacher struct {
|
||||
idList *list.List
|
||||
sqlList *list.List
|
||||
idIndex map[string]map[string]*list.Element
|
||||
sqlIndex map[string]map[string]*list.Element
|
||||
store core.CacheStore
|
||||
mutex sync.Mutex
|
||||
// maxSize int
|
||||
MaxElementSize int
|
||||
Expired time.Duration
|
||||
GcInterval time.Duration
|
||||
}
|
||||
|
||||
func NewLRUCacher(store core.CacheStore, maxElementSize int) *LRUCacher {
|
||||
return NewLRUCacher2(store, 3600*time.Second, maxElementSize)
|
||||
}
|
||||
|
||||
func NewLRUCacher2(store core.CacheStore, expired time.Duration, maxElementSize int) *LRUCacher {
|
||||
cacher := &LRUCacher{store: store, idList: list.New(),
|
||||
sqlList: list.New(), Expired: expired,
|
||||
GcInterval: core.CacheGcInterval, MaxElementSize: maxElementSize,
|
||||
sqlIndex: make(map[string]map[string]*list.Element),
|
||||
idIndex: make(map[string]map[string]*list.Element),
|
||||
}
|
||||
cacher.RunGC()
|
||||
return cacher
|
||||
}
|
||||
|
||||
//func NewLRUCacher3(store CacheStore, expired time.Duration, maxSize int) *LRUCacher {
|
||||
// return newLRUCacher(store, expired, maxSize, 0)
|
||||
//}
|
||||
|
||||
// RunGC run once every m.GcInterval
|
||||
func (m *LRUCacher) RunGC() {
|
||||
time.AfterFunc(m.GcInterval, func() {
|
||||
m.RunGC()
|
||||
m.GC()
|
||||
})
|
||||
}
|
||||
|
||||
// GC check ids lit and sql list to remove all element expired
|
||||
func (m *LRUCacher) GC() {
|
||||
//fmt.Println("begin gc ...")
|
||||
//defer fmt.Println("end gc ...")
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
var removedNum int
|
||||
for e := m.idList.Front(); e != nil; {
|
||||
if removedNum <= core.CacheGcMaxRemoved &&
|
||||
time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
|
||||
removedNum++
|
||||
next := e.Next()
|
||||
//fmt.Println("removing ...", e.Value)
|
||||
node := e.Value.(*idNode)
|
||||
m.delBean(node.tbName, node.id)
|
||||
e = next
|
||||
} else {
|
||||
//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.idList.Len())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
removedNum = 0
|
||||
for e := m.sqlList.Front(); e != nil; {
|
||||
if removedNum <= core.CacheGcMaxRemoved &&
|
||||
time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
|
||||
removedNum++
|
||||
next := e.Next()
|
||||
//fmt.Println("removing ...", e.Value)
|
||||
node := e.Value.(*sqlNode)
|
||||
m.delIds(node.tbName, node.sql)
|
||||
e = next
|
||||
} else {
|
||||
//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.sqlList.Len())
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all bean's ids according to sql and parameter from cache
|
||||
func (m *LRUCacher) GetIds(tableName, sql string) interface{} {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
if _, ok := m.sqlIndex[tableName]; !ok {
|
||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
||||
}
|
||||
if v, err := m.store.Get(sql); err == nil {
|
||||
if el, ok := m.sqlIndex[tableName][sql]; !ok {
|
||||
el = m.sqlList.PushBack(newSqlNode(tableName, sql))
|
||||
m.sqlIndex[tableName][sql] = el
|
||||
} else {
|
||||
lastTime := el.Value.(*sqlNode).lastVisit
|
||||
// if expired, remove the node and return nil
|
||||
if time.Now().Sub(lastTime) > m.Expired {
|
||||
m.delIds(tableName, sql)
|
||||
return nil
|
||||
}
|
||||
m.sqlList.MoveToBack(el)
|
||||
el.Value.(*sqlNode).lastVisit = time.Now()
|
||||
}
|
||||
return v
|
||||
} else {
|
||||
m.delIds(tableName, sql)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get bean according tableName and id from cache
|
||||
func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
if _, ok := m.idIndex[tableName]; !ok {
|
||||
m.idIndex[tableName] = make(map[string]*list.Element)
|
||||
}
|
||||
tid := genId(tableName, id)
|
||||
if v, err := m.store.Get(tid); err == nil {
|
||||
if el, ok := m.idIndex[tableName][id]; ok {
|
||||
lastTime := el.Value.(*idNode).lastVisit
|
||||
// if expired, remove the node and return nil
|
||||
if time.Now().Sub(lastTime) > m.Expired {
|
||||
m.delBean(tableName, id)
|
||||
//m.clearIds(tableName)
|
||||
return nil
|
||||
}
|
||||
m.idList.MoveToBack(el)
|
||||
el.Value.(*idNode).lastVisit = time.Now()
|
||||
} else {
|
||||
el = m.idList.PushBack(newIdNode(tableName, id))
|
||||
m.idIndex[tableName][id] = el
|
||||
}
|
||||
return v
|
||||
} else {
|
||||
// store bean is not exist, then remove memory's index
|
||||
m.delBean(tableName, id)
|
||||
//m.clearIds(tableName)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Clear all sql-ids mapping on table tableName from cache
|
||||
func (m *LRUCacher) clearIds(tableName string) {
|
||||
if tis, ok := m.sqlIndex[tableName]; ok {
|
||||
for sql, v := range tis {
|
||||
m.sqlList.Remove(v)
|
||||
m.store.Del(sql)
|
||||
}
|
||||
}
|
||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) ClearIds(tableName string) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
m.clearIds(tableName)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) clearBeans(tableName string) {
|
||||
if tis, ok := m.idIndex[tableName]; ok {
|
||||
for id, v := range tis {
|
||||
m.idList.Remove(v)
|
||||
tid := genId(tableName, id)
|
||||
m.store.Del(tid)
|
||||
}
|
||||
}
|
||||
m.idIndex[tableName] = make(map[string]*list.Element)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) ClearBeans(tableName string) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
m.clearBeans(tableName)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
if _, ok := m.sqlIndex[tableName]; !ok {
|
||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
||||
}
|
||||
if el, ok := m.sqlIndex[tableName][sql]; !ok {
|
||||
el = m.sqlList.PushBack(newSqlNode(tableName, sql))
|
||||
m.sqlIndex[tableName][sql] = el
|
||||
} else {
|
||||
el.Value.(*sqlNode).lastVisit = time.Now()
|
||||
}
|
||||
m.store.Put(sql, ids)
|
||||
if m.sqlList.Len() > m.MaxElementSize {
|
||||
e := m.sqlList.Front()
|
||||
node := e.Value.(*sqlNode)
|
||||
m.delIds(node.tbName, node.sql)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
var el *list.Element
|
||||
var ok bool
|
||||
|
||||
if el, ok = m.idIndex[tableName][id]; !ok {
|
||||
el = m.idList.PushBack(newIdNode(tableName, id))
|
||||
m.idIndex[tableName][id] = el
|
||||
} else {
|
||||
el.Value.(*idNode).lastVisit = time.Now()
|
||||
}
|
||||
|
||||
m.store.Put(genId(tableName, id), obj)
|
||||
if m.idList.Len() > m.MaxElementSize {
|
||||
e := m.idList.Front()
|
||||
node := e.Value.(*idNode)
|
||||
m.delBean(node.tbName, node.id)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *LRUCacher) delIds(tableName, sql string) {
|
||||
if _, ok := m.sqlIndex[tableName]; ok {
|
||||
if el, ok := m.sqlIndex[tableName][sql]; ok {
|
||||
delete(m.sqlIndex[tableName], sql)
|
||||
m.sqlList.Remove(el)
|
||||
}
|
||||
}
|
||||
m.store.Del(sql)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) DelIds(tableName, sql string) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
m.delIds(tableName, sql)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) delBean(tableName string, id string) {
|
||||
tid := genId(tableName, id)
|
||||
if el, ok := m.idIndex[tableName][id]; ok {
|
||||
delete(m.idIndex[tableName], id)
|
||||
m.idList.Remove(el)
|
||||
m.clearIds(tableName)
|
||||
}
|
||||
m.store.Del(tid)
|
||||
}
|
||||
|
||||
func (m *LRUCacher) DelBean(tableName string, id string) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
m.delBean(tableName, id)
|
||||
}
|
||||
|
||||
type idNode struct {
|
||||
tbName string
|
||||
id string
|
||||
lastVisit time.Time
|
||||
}
|
||||
|
||||
type sqlNode struct {
|
||||
tbName string
|
||||
sql string
|
||||
lastVisit time.Time
|
||||
}
|
||||
|
||||
func genSqlKey(sql string, args interface{}) string {
|
||||
return fmt.Sprintf("%v-%v", sql, args)
|
||||
}
|
||||
|
||||
func genId(prefix string, id string) string {
|
||||
return fmt.Sprintf("%v-%v", prefix, id)
|
||||
}
|
||||
|
||||
func newIdNode(tbName string, id string) *idNode {
|
||||
return &idNode{tbName, id, time.Now()}
|
||||
}
|
||||
|
||||
func newSqlNode(tbName, sql string) *sqlNode {
|
||||
return &sqlNode{tbName, sql, time.Now()}
|
||||
}
|
47
vendor/github.com/go-xorm/xorm/memory_store.go
generated
vendored
Normal file
47
vendor/github.com/go-xorm/xorm/memory_store.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var _ core.CacheStore = NewMemoryStore()
|
||||
|
||||
// memory store
|
||||
type MemoryStore struct {
|
||||
store map[interface{}]interface{}
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMemoryStore() *MemoryStore {
|
||||
return &MemoryStore{store: make(map[interface{}]interface{})}
|
||||
}
|
||||
|
||||
func (s *MemoryStore) Put(key string, value interface{}) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
s.store[key] = value
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemoryStore) Get(key string) (interface{}, error) {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
if v, ok := s.store[key]; ok {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return nil, ErrNotExist
|
||||
}
|
||||
|
||||
func (s *MemoryStore) Del(key string) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
delete(s.store, key)
|
||||
return nil
|
||||
}
|
529
vendor/github.com/go-xorm/xorm/mssql_dialect.go
generated
vendored
Normal file
529
vendor/github.com/go-xorm/xorm/mssql_dialect.go
generated
vendored
Normal file
|
@ -0,0 +1,529 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var (
|
||||
mssqlReservedWords = map[string]bool{
|
||||
"ADD": true,
|
||||
"EXTERNAL": true,
|
||||
"PROCEDURE": true,
|
||||
"ALL": true,
|
||||
"FETCH": true,
|
||||
"PUBLIC": true,
|
||||
"ALTER": true,
|
||||
"FILE": true,
|
||||
"RAISERROR": true,
|
||||
"AND": true,
|
||||
"FILLFACTOR": true,
|
||||
"READ": true,
|
||||
"ANY": true,
|
||||
"FOR": true,
|
||||
"READTEXT": true,
|
||||
"AS": true,
|
||||
"FOREIGN": true,
|
||||
"RECONFIGURE": true,
|
||||
"ASC": true,
|
||||
"FREETEXT": true,
|
||||
"REFERENCES": true,
|
||||
"AUTHORIZATION": true,
|
||||
"FREETEXTTABLE": true,
|
||||
"REPLICATION": true,
|
||||
"BACKUP": true,
|
||||
"FROM": true,
|
||||
"RESTORE": true,
|
||||
"BEGIN": true,
|
||||
"FULL": true,
|
||||
"RESTRICT": true,
|
||||
"BETWEEN": true,
|
||||
"FUNCTION": true,
|
||||
"RETURN": true,
|
||||
"BREAK": true,
|
||||
"GOTO": true,
|
||||
"REVERT": true,
|
||||
"BROWSE": true,
|
||||
"GRANT": true,
|
||||
"REVOKE": true,
|
||||
"BULK": true,
|
||||
"GROUP": true,
|
||||
"RIGHT": true,
|
||||
"BY": true,
|
||||
"HAVING": true,
|
||||
"ROLLBACK": true,
|
||||
"CASCADE": true,
|
||||
"HOLDLOCK": true,
|
||||
"ROWCOUNT": true,
|
||||
"CASE": true,
|
||||
"IDENTITY": true,
|
||||
"ROWGUIDCOL": true,
|
||||
"CHECK": true,
|
||||
"IDENTITY_INSERT": true,
|
||||
"RULE": true,
|
||||
"CHECKPOINT": true,
|
||||
"IDENTITYCOL": true,
|
||||
"SAVE": true,
|
||||
"CLOSE": true,
|
||||
"IF": true,
|
||||
"SCHEMA": true,
|
||||
"CLUSTERED": true,
|
||||
"IN": true,
|
||||
"SECURITYAUDIT": true,
|
||||
"COALESCE": true,
|
||||
"INDEX": true,
|
||||
"SELECT": true,
|
||||
"COLLATE": true,
|
||||
"INNER": true,
|
||||
"SEMANTICKEYPHRASETABLE": true,
|
||||
"COLUMN": true,
|
||||
"INSERT": true,
|
||||
"SEMANTICSIMILARITYDETAILSTABLE": true,
|
||||
"COMMIT": true,
|
||||
"INTERSECT": true,
|
||||
"SEMANTICSIMILARITYTABLE": true,
|
||||
"COMPUTE": true,
|
||||
"INTO": true,
|
||||
"SESSION_USER": true,
|
||||
"CONSTRAINT": true,
|
||||
"IS": true,
|
||||
"SET": true,
|
||||
"CONTAINS": true,
|
||||
"JOIN": true,
|
||||
"SETUSER": true,
|
||||
"CONTAINSTABLE": true,
|
||||
"KEY": true,
|
||||
"SHUTDOWN": true,
|
||||
"CONTINUE": true,
|
||||
"KILL": true,
|
||||
"SOME": true,
|
||||
"CONVERT": true,
|
||||
"LEFT": true,
|
||||
"STATISTICS": true,
|
||||
"CREATE": true,
|
||||
"LIKE": true,
|
||||
"SYSTEM_USER": true,
|
||||
"CROSS": true,
|
||||
"LINENO": true,
|
||||
"TABLE": true,
|
||||
"CURRENT": true,
|
||||
"LOAD": true,
|
||||
"TABLESAMPLE": true,
|
||||
"CURRENT_DATE": true,
|
||||
"MERGE": true,
|
||||
"TEXTSIZE": true,
|
||||
"CURRENT_TIME": true,
|
||||
"NATIONAL": true,
|
||||
"THEN": true,
|
||||
"CURRENT_TIMESTAMP": true,
|
||||
"NOCHECK": true,
|
||||
"TO": true,
|
||||
"CURRENT_USER": true,
|
||||
"NONCLUSTERED": true,
|
||||
"TOP": true,
|
||||
"CURSOR": true,
|
||||
"NOT": true,
|
||||
"TRAN": true,
|
||||
"DATABASE": true,
|
||||
"NULL": true,
|
||||
"TRANSACTION": true,
|
||||
"DBCC": true,
|
||||
"NULLIF": true,
|
||||
"TRIGGER": true,
|
||||
"DEALLOCATE": true,
|
||||
"OF": true,
|
||||
"TRUNCATE": true,
|
||||
"DECLARE": true,
|
||||
"OFF": true,
|
||||
"TRY_CONVERT": true,
|
||||
"DEFAULT": true,
|
||||
"OFFSETS": true,
|
||||
"TSEQUAL": true,
|
||||
"DELETE": true,
|
||||
"ON": true,
|
||||
"UNION": true,
|
||||
"DENY": true,
|
||||
"OPEN": true,
|
||||
"UNIQUE": true,
|
||||
"DESC": true,
|
||||
"OPENDATASOURCE": true,
|
||||
"UNPIVOT": true,
|
||||
"DISK": true,
|
||||
"OPENQUERY": true,
|
||||
"UPDATE": true,
|
||||
"DISTINCT": true,
|
||||
"OPENROWSET": true,
|
||||
"UPDATETEXT": true,
|
||||
"DISTRIBUTED": true,
|
||||
"OPENXML": true,
|
||||
"USE": true,
|
||||
"DOUBLE": true,
|
||||
"OPTION": true,
|
||||
"USER": true,
|
||||
"DROP": true,
|
||||
"OR": true,
|
||||
"VALUES": true,
|
||||
"DUMP": true,
|
||||
"ORDER": true,
|
||||
"VARYING": true,
|
||||
"ELSE": true,
|
||||
"OUTER": true,
|
||||
"VIEW": true,
|
||||
"END": true,
|
||||
"OVER": true,
|
||||
"WAITFOR": true,
|
||||
"ERRLVL": true,
|
||||
"PERCENT": true,
|
||||
"WHEN": true,
|
||||
"ESCAPE": true,
|
||||
"PIVOT": true,
|
||||
"WHERE": true,
|
||||
"EXCEPT": true,
|
||||
"PLAN": true,
|
||||
"WHILE": true,
|
||||
"EXEC": true,
|
||||
"PRECISION": true,
|
||||
"WITH": true,
|
||||
"EXECUTE": true,
|
||||
"PRIMARY": true,
|
||||
"WITHIN": true,
|
||||
"EXISTS": true,
|
||||
"PRINT": true,
|
||||
"WRITETEXT": true,
|
||||
"EXIT": true,
|
||||
"PROC": true,
|
||||
}
|
||||
)
|
||||
|
||||
type mssql struct {
|
||||
core.Base
|
||||
}
|
||||
|
||||
func (db *mssql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
||||
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
}
|
||||
|
||||
func (db *mssql) SqlType(c *core.Column) string {
|
||||
var res string
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bool:
|
||||
res = core.TinyInt
|
||||
if c.Default == "true" {
|
||||
c.Default = "1"
|
||||
} else if c.Default == "false" {
|
||||
c.Default = "0"
|
||||
}
|
||||
case core.Serial:
|
||||
c.IsAutoIncrement = true
|
||||
c.IsPrimaryKey = true
|
||||
c.Nullable = false
|
||||
res = core.Int
|
||||
case core.BigSerial:
|
||||
c.IsAutoIncrement = true
|
||||
c.IsPrimaryKey = true
|
||||
c.Nullable = false
|
||||
res = core.BigInt
|
||||
case core.Bytea, core.Blob, core.Binary, core.TinyBlob, core.MediumBlob, core.LongBlob:
|
||||
res = core.VarBinary
|
||||
if c.Length == 0 {
|
||||
c.Length = 50
|
||||
}
|
||||
case core.TimeStamp:
|
||||
res = core.DateTime
|
||||
case core.TimeStampz:
|
||||
res = "DATETIMEOFFSET"
|
||||
c.Length = 7
|
||||
case core.MediumInt:
|
||||
res = core.Int
|
||||
case core.MediumText, core.TinyText, core.LongText, core.Json:
|
||||
res = core.Text
|
||||
case core.Double:
|
||||
res = core.Real
|
||||
case core.Uuid:
|
||||
res = core.Varchar
|
||||
c.Length = 40
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
|
||||
if res == core.Int {
|
||||
return core.Int
|
||||
}
|
||||
|
||||
var hasLen1 bool = (c.Length > 0)
|
||||
var hasLen2 bool = (c.Length2 > 0)
|
||||
if hasLen2 {
|
||||
res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")"
|
||||
} else if hasLen1 {
|
||||
res += "(" + strconv.Itoa(c.Length) + ")"
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (db *mssql) SupportInsertMany() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *mssql) IsReserved(name string) bool {
|
||||
_, ok := mssqlReservedWords[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (db *mssql) Quote(name string) string {
|
||||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *mssql) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (db *mssql) SupportEngine() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *mssql) AutoIncrStr() string {
|
||||
return "IDENTITY"
|
||||
}
|
||||
|
||||
func (db *mssql) DropTableSql(tableName string) string {
|
||||
return fmt.Sprintf("IF EXISTS (SELECT * FROM sysobjects WHERE id = "+
|
||||
"object_id(N'%s') and OBJECTPROPERTY(id, N'IsUserTable') = 1) "+
|
||||
"DROP TABLE \"%s\"", tableName, tableName)
|
||||
}
|
||||
|
||||
func (db *mssql) SupportCharset() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *mssql) IndexOnTable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *mssql) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
||||
args := []interface{}{idxName}
|
||||
sql := "select name from sysindexes where id=object_id('" + tableName + "') and name=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
/*func (db *mssql) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, colName}
|
||||
sql := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?`
|
||||
return sql, args
|
||||
}*/
|
||||
|
||||
func (db *mssql) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
query := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?`
|
||||
|
||||
return db.HasRecords(query, tableName, colName)
|
||||
}
|
||||
|
||||
func (db *mssql) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{}
|
||||
sql := "select * from sysobjects where id = object_id(N'" + tableName + "') and OBJECTPROPERTY(id, N'IsUserTable') = 1"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
func (db *mssql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
args := []interface{}{}
|
||||
s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable,
|
||||
replace(replace(isnull(c.text,''),'(',''),')','') as vdefault
|
||||
from sys.columns a left join sys.types b on a.user_type_id=b.user_type_id
|
||||
left join sys.syscomments c on a.default_object_id=c.id
|
||||
where a.object_id=object_id('` + tableName + `')`
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
cols := make(map[string]*core.Column)
|
||||
colSeq := make([]string, 0)
|
||||
for rows.Next() {
|
||||
var name, ctype, vdefault string
|
||||
var maxLen, precision, scale int
|
||||
var nullable bool
|
||||
err = rows.Scan(&name, &ctype, &maxLen, &precision, &scale, &nullable, &vdefault)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]int)
|
||||
col.Name = strings.Trim(name, "` ")
|
||||
col.Nullable = nullable
|
||||
col.Default = vdefault
|
||||
ct := strings.ToUpper(ctype)
|
||||
if ct == "DECIMAL" {
|
||||
col.Length = precision
|
||||
col.Length2 = scale
|
||||
} else {
|
||||
col.Length = maxLen
|
||||
}
|
||||
switch ct {
|
||||
case "DATETIMEOFFSET":
|
||||
col.SQLType = core.SQLType{core.TimeStampz, 0, 0}
|
||||
case "NVARCHAR":
|
||||
col.SQLType = core.SQLType{core.NVarchar, 0, 0}
|
||||
case "IMAGE":
|
||||
col.SQLType = core.SQLType{core.VarBinary, 0, 0}
|
||||
default:
|
||||
if _, ok := core.SqlTypes[ct]; ok {
|
||||
col.SQLType = core.SQLType{ct, 0, 0}
|
||||
} else {
|
||||
return nil, nil, errors.New(fmt.Sprintf("unknow colType %v for %v - %v",
|
||||
ct, tableName, col.Name))
|
||||
}
|
||||
}
|
||||
|
||||
if col.SQLType.IsText() || col.SQLType.IsTime() {
|
||||
if col.Default != "" {
|
||||
col.Default = "'" + col.Default + "'"
|
||||
} else {
|
||||
if col.DefaultIsEmpty {
|
||||
col.Default = "''"
|
||||
}
|
||||
}
|
||||
}
|
||||
cols[col.Name] = col
|
||||
colSeq = append(colSeq, col.Name)
|
||||
}
|
||||
return colSeq, cols, nil
|
||||
}
|
||||
|
||||
func (db *mssql) GetTables() ([]*core.Table, error) {
|
||||
args := []interface{}{}
|
||||
s := `select name from sysobjects where xtype ='U'`
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
tables := make([]*core.Table, 0)
|
||||
for rows.Next() {
|
||||
table := core.NewEmptyTable()
|
||||
var name string
|
||||
err = rows.Scan(&name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
table.Name = strings.Trim(name, "` ")
|
||||
tables = append(tables, table)
|
||||
}
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
func (db *mssql) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
args := []interface{}{tableName}
|
||||
s := `SELECT
|
||||
IXS.NAME AS [INDEX_NAME],
|
||||
C.NAME AS [COLUMN_NAME],
|
||||
IXS.is_unique AS [IS_UNIQUE]
|
||||
FROM SYS.INDEXES IXS
|
||||
INNER JOIN SYS.INDEX_COLUMNS IXCS
|
||||
ON IXS.OBJECT_ID=IXCS.OBJECT_ID AND IXS.INDEX_ID = IXCS.INDEX_ID
|
||||
INNER JOIN SYS.COLUMNS C ON IXS.OBJECT_ID=C.OBJECT_ID
|
||||
AND IXCS.COLUMN_ID=C.COLUMN_ID
|
||||
WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =?
|
||||
`
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
indexes := make(map[string]*core.Index, 0)
|
||||
for rows.Next() {
|
||||
var indexType int
|
||||
var indexName, colName, isUnique string
|
||||
|
||||
err = rows.Scan(&indexName, &colName, &isUnique)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i, err := strconv.ParseBool(isUnique)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if i {
|
||||
indexType = core.UniqueType
|
||||
} else {
|
||||
indexType = core.IndexType
|
||||
}
|
||||
|
||||
colName = strings.Trim(colName, "` ")
|
||||
|
||||
if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
|
||||
indexName = indexName[5+len(tableName):]
|
||||
}
|
||||
|
||||
var index *core.Index
|
||||
var ok bool
|
||||
if index, ok = indexes[indexName]; !ok {
|
||||
index = new(core.Index)
|
||||
index.Type = indexType
|
||||
index.Name = indexName
|
||||
indexes[indexName] = index
|
||||
}
|
||||
index.AddColumn(colName)
|
||||
}
|
||||
return indexes, nil
|
||||
}
|
||||
|
||||
func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string {
|
||||
var sql string
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
|
||||
|
||||
sql += db.QuoteStr() + tableName + db.QuoteStr() + " ("
|
||||
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
if col.IsPrimaryKey && len(pkList) == 1 {
|
||||
sql += col.String(db)
|
||||
} else {
|
||||
sql += col.StringNoPk(db)
|
||||
}
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += strings.Join(pkList, ",")
|
||||
sql += " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2] + ")"
|
||||
sql += ";"
|
||||
return sql
|
||||
}
|
||||
|
||||
func (db *mssql) ForUpdateSql(query string) string {
|
||||
return query
|
||||
}
|
||||
|
||||
func (db *mssql) Filters() []core.Filter {
|
||||
return []core.Filter{&core.IdFilter{}, &core.QuoteFilter{}}
|
||||
}
|
65
vendor/github.com/go-xorm/xorm/mymysql_driver.go
generated
vendored
Normal file
65
vendor/github.com/go-xorm/xorm/mymysql_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type mymysqlDriver struct {
|
||||
}
|
||||
|
||||
func (p *mymysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.MYSQL}
|
||||
|
||||
pd := strings.SplitN(dataSourceName, "*", 2)
|
||||
if len(pd) == 2 {
|
||||
// Parse protocol part of URI
|
||||
p := strings.SplitN(pd[0], ":", 2)
|
||||
if len(p) != 2 {
|
||||
return nil, errors.New("Wrong protocol part of URI")
|
||||
}
|
||||
db.Proto = p[0]
|
||||
options := strings.Split(p[1], ",")
|
||||
db.Raddr = options[0]
|
||||
for _, o := range options[1:] {
|
||||
kv := strings.SplitN(o, "=", 2)
|
||||
var k, v string
|
||||
if len(kv) == 2 {
|
||||
k, v = kv[0], kv[1]
|
||||
} else {
|
||||
k, v = o, "true"
|
||||
}
|
||||
switch k {
|
||||
case "laddr":
|
||||
db.Laddr = v
|
||||
case "timeout":
|
||||
to, err := time.ParseDuration(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db.Timeout = to
|
||||
default:
|
||||
return nil, errors.New("Unknown option: " + k)
|
||||
}
|
||||
}
|
||||
// Remove protocol part
|
||||
pd = pd[1:]
|
||||
}
|
||||
// Parse database part of URI
|
||||
dup := strings.SplitN(pd[0], "/", 3)
|
||||
if len(dup) != 3 {
|
||||
return nil, errors.New("Wrong database part of URI")
|
||||
}
|
||||
db.DbName = dup[0]
|
||||
db.User = dup[1]
|
||||
db.Passwd = dup[2]
|
||||
|
||||
return db, nil
|
||||
}
|
489
vendor/github.com/go-xorm/xorm/mysql_dialect.go
generated
vendored
Normal file
489
vendor/github.com/go-xorm/xorm/mysql_dialect.go
generated
vendored
Normal file
|
@ -0,0 +1,489 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var (
|
||||
mysqlReservedWords = map[string]bool{
|
||||
"ADD": true,
|
||||
"ALL": true,
|
||||
"ALTER": true,
|
||||
"ANALYZE": true,
|
||||
"AND": true,
|
||||
"AS": true,
|
||||
"ASC": true,
|
||||
"ASENSITIVE": true,
|
||||
"BEFORE": true,
|
||||
"BETWEEN": true,
|
||||
"BIGINT": true,
|
||||
"BINARY": true,
|
||||
"BLOB": true,
|
||||
"BOTH": true,
|
||||
"BY": true,
|
||||
"CALL": true,
|
||||
"CASCADE": true,
|
||||
"CASE": true,
|
||||
"CHANGE": true,
|
||||
"CHAR": true,
|
||||
"CHARACTER": true,
|
||||
"CHECK": true,
|
||||
"COLLATE": true,
|
||||
"COLUMN": true,
|
||||
"CONDITION": true,
|
||||
"CONNECTION": true,
|
||||
"CONSTRAINT": true,
|
||||
"CONTINUE": true,
|
||||
"CONVERT": true,
|
||||
"CREATE": true,
|
||||
"CROSS": true,
|
||||
"CURRENT_DATE": true,
|
||||
"CURRENT_TIME": true,
|
||||
"CURRENT_TIMESTAMP": true,
|
||||
"CURRENT_USER": true,
|
||||
"CURSOR": true,
|
||||
"DATABASE": true,
|
||||
"DATABASES": true,
|
||||
"DAY_HOUR": true,
|
||||
"DAY_MICROSECOND": true,
|
||||
"DAY_MINUTE": true,
|
||||
"DAY_SECOND": true,
|
||||
"DEC": true,
|
||||
"DECIMAL": true,
|
||||
"DECLARE": true,
|
||||
"DEFAULT": true,
|
||||
"DELAYED": true,
|
||||
"DELETE": true,
|
||||
"DESC": true,
|
||||
"DESCRIBE": true,
|
||||
"DETERMINISTIC": true,
|
||||
"DISTINCT": true,
|
||||
"DISTINCTROW": true,
|
||||
"DIV": true,
|
||||
"DOUBLE": true,
|
||||
"DROP": true,
|
||||
"DUAL": true,
|
||||
"EACH": true,
|
||||
"ELSE": true,
|
||||
"ELSEIF": true,
|
||||
"ENCLOSED": true,
|
||||
"ESCAPED": true,
|
||||
"EXISTS": true,
|
||||
"EXIT": true,
|
||||
"EXPLAIN": true,
|
||||
"FALSE": true,
|
||||
"FETCH": true,
|
||||
"FLOAT": true,
|
||||
"FLOAT4": true,
|
||||
"FLOAT8": true,
|
||||
"FOR": true,
|
||||
"FORCE": true,
|
||||
"FOREIGN": true,
|
||||
"FROM": true,
|
||||
"FULLTEXT": true,
|
||||
"GOTO": true,
|
||||
"GRANT": true,
|
||||
"GROUP": true,
|
||||
"HAVING": true,
|
||||
"HIGH_PRIORITY": true,
|
||||
"HOUR_MICROSECOND": true,
|
||||
"HOUR_MINUTE": true,
|
||||
"HOUR_SECOND": true,
|
||||
"IF": true,
|
||||
"IGNORE": true,
|
||||
"IN": true, "INDEX": true,
|
||||
"INFILE": true, "INNER": true, "INOUT": true,
|
||||
"INSENSITIVE": true, "INSERT": true, "INT": true,
|
||||
"INT1": true, "INT2": true, "INT3": true,
|
||||
"INT4": true, "INT8": true, "INTEGER": true,
|
||||
"INTERVAL": true, "INTO": true, "IS": true,
|
||||
"ITERATE": true, "JOIN": true, "KEY": true,
|
||||
"KEYS": true, "KILL": true, "LABEL": true,
|
||||
"LEADING": true, "LEAVE": true, "LEFT": true,
|
||||
"LIKE": true, "LIMIT": true, "LINEAR": true,
|
||||
"LINES": true, "LOAD": true, "LOCALTIME": true,
|
||||
"LOCALTIMESTAMP": true, "LOCK": true, "LONG": true,
|
||||
"LONGBLOB": true, "LONGTEXT": true, "LOOP": true,
|
||||
"LOW_PRIORITY": true, "MATCH": true, "MEDIUMBLOB": true,
|
||||
"MEDIUMINT": true, "MEDIUMTEXT": true, "MIDDLEINT": true,
|
||||
"MINUTE_MICROSECOND": true, "MINUTE_SECOND": true, "MOD": true,
|
||||
"MODIFIES": true, "NATURAL": true, "NOT": true,
|
||||
"NO_WRITE_TO_BINLOG": true, "NULL": true, "NUMERIC": true,
|
||||
"ON OPTIMIZE": true, "OPTION": true,
|
||||
"OPTIONALLY": true, "OR": true, "ORDER": true,
|
||||
"OUT": true, "OUTER": true, "OUTFILE": true,
|
||||
"PRECISION": true, "PRIMARY": true, "PROCEDURE": true,
|
||||
"PURGE": true, "RAID0": true, "RANGE": true,
|
||||
"READ": true, "READS": true, "REAL": true,
|
||||
"REFERENCES": true, "REGEXP": true, "RELEASE": true,
|
||||
"RENAME": true, "REPEAT": true, "REPLACE": true,
|
||||
"REQUIRE": true, "RESTRICT": true, "RETURN": true,
|
||||
"REVOKE": true, "RIGHT": true, "RLIKE": true,
|
||||
"SCHEMA": true, "SCHEMAS": true, "SECOND_MICROSECOND": true,
|
||||
"SELECT": true, "SENSITIVE": true, "SEPARATOR": true,
|
||||
"SET": true, "SHOW": true, "SMALLINT": true,
|
||||
"SPATIAL": true, "SPECIFIC": true, "SQL": true,
|
||||
"SQLEXCEPTION": true, "SQLSTATE": true, "SQLWARNING": true,
|
||||
"SQL_BIG_RESULT": true, "SQL_CALC_FOUND_ROWS": true, "SQL_SMALL_RESULT": true,
|
||||
"SSL": true, "STARTING": true, "STRAIGHT_JOIN": true,
|
||||
"TABLE": true, "TERMINATED": true, "THEN": true,
|
||||
"TINYBLOB": true, "TINYINT": true, "TINYTEXT": true,
|
||||
"TO": true, "TRAILING": true, "TRIGGER": true,
|
||||
"TRUE": true, "UNDO": true, "UNION": true,
|
||||
"UNIQUE": true, "UNLOCK": true, "UNSIGNED": true,
|
||||
"UPDATE": true, "USAGE": true, "USE": true,
|
||||
"USING": true, "UTC_DATE": true, "UTC_TIME": true,
|
||||
"UTC_TIMESTAMP": true, "VALUES": true, "VARBINARY": true,
|
||||
"VARCHAR": true,
|
||||
"VARCHARACTER": true,
|
||||
"VARYING": true,
|
||||
"WHEN": true,
|
||||
"WHERE": true,
|
||||
"WHILE": true,
|
||||
"WITH": true,
|
||||
"WRITE": true,
|
||||
"X509": true,
|
||||
"XOR": true,
|
||||
"YEAR_MONTH": true,
|
||||
"ZEROFILL": true,
|
||||
}
|
||||
)
|
||||
|
||||
type mysql struct {
|
||||
core.Base
|
||||
net string
|
||||
addr string
|
||||
params map[string]string
|
||||
loc *time.Location
|
||||
timeout time.Duration
|
||||
tls *tls.Config
|
||||
allowAllFiles bool
|
||||
allowOldPasswords bool
|
||||
clientFoundRows bool
|
||||
}
|
||||
|
||||
func (db *mysql) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
||||
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
}
|
||||
|
||||
func (db *mysql) SqlType(c *core.Column) string {
|
||||
var res string
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bool:
|
||||
res = core.TinyInt
|
||||
c.Length = 1
|
||||
case core.Serial:
|
||||
c.IsAutoIncrement = true
|
||||
c.IsPrimaryKey = true
|
||||
c.Nullable = false
|
||||
res = core.Int
|
||||
case core.BigSerial:
|
||||
c.IsAutoIncrement = true
|
||||
c.IsPrimaryKey = true
|
||||
c.Nullable = false
|
||||
res = core.BigInt
|
||||
case core.Bytea:
|
||||
res = core.Blob
|
||||
case core.TimeStampz:
|
||||
res = core.Char
|
||||
c.Length = 64
|
||||
case core.Enum: //mysql enum
|
||||
res = core.Enum
|
||||
res += "("
|
||||
opts := ""
|
||||
for v, _ := range c.EnumOptions {
|
||||
opts += fmt.Sprintf(",'%v'", v)
|
||||
}
|
||||
res += strings.TrimLeft(opts, ",")
|
||||
res += ")"
|
||||
case core.Set: //mysql set
|
||||
res = core.Set
|
||||
res += "("
|
||||
opts := ""
|
||||
for v, _ := range c.SetOptions {
|
||||
opts += fmt.Sprintf(",'%v'", v)
|
||||
}
|
||||
res += strings.TrimLeft(opts, ",")
|
||||
res += ")"
|
||||
case core.NVarchar:
|
||||
res = core.Varchar
|
||||
case core.Uuid:
|
||||
res = core.Varchar
|
||||
c.Length = 40
|
||||
case core.Json:
|
||||
res = core.Text
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
|
||||
var hasLen1 bool = (c.Length > 0)
|
||||
var hasLen2 bool = (c.Length2 > 0)
|
||||
|
||||
if res == core.BigInt && !hasLen1 && !hasLen2 {
|
||||
c.Length = 20
|
||||
hasLen1 = true
|
||||
}
|
||||
|
||||
if hasLen2 {
|
||||
res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")"
|
||||
} else if hasLen1 {
|
||||
res += "(" + strconv.Itoa(c.Length) + ")"
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (db *mysql) SupportInsertMany() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *mysql) IsReserved(name string) bool {
|
||||
_, ok := mysqlReservedWords[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (db *mysql) Quote(name string) string {
|
||||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *mysql) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *mysql) SupportEngine() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *mysql) AutoIncrStr() string {
|
||||
return "AUTO_INCREMENT"
|
||||
}
|
||||
|
||||
func (db *mysql) SupportCharset() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *mysql) IndexOnTable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *mysql) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
||||
args := []interface{}{db.DbName, tableName, idxName}
|
||||
sql := "SELECT `INDEX_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS`"
|
||||
sql += " WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `INDEX_NAME`=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
/*func (db *mysql) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
args := []interface{}{db.DbName, tableName, colName}
|
||||
sql := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
|
||||
return sql, args
|
||||
}*/
|
||||
|
||||
func (db *mysql) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{db.DbName, tableName}
|
||||
sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?"
|
||||
return sql, args
|
||||
}
|
||||
|
||||
func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
args := []interface{}{db.DbName, tableName}
|
||||
s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," +
|
||||
" `COLUMN_KEY`, `EXTRA` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
cols := make(map[string]*core.Column)
|
||||
colSeq := make([]string, 0)
|
||||
for rows.Next() {
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]int)
|
||||
|
||||
var columnName, isNullable, colType, colKey, extra string
|
||||
var colDefault *string
|
||||
err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
col.Name = strings.Trim(columnName, "` ")
|
||||
if "YES" == isNullable {
|
||||
col.Nullable = true
|
||||
}
|
||||
|
||||
if colDefault != nil {
|
||||
col.Default = *colDefault
|
||||
if col.Default == "" {
|
||||
col.DefaultIsEmpty = true
|
||||
}
|
||||
}
|
||||
|
||||
cts := strings.Split(colType, "(")
|
||||
colName := cts[0]
|
||||
colType = strings.ToUpper(colName)
|
||||
var len1, len2 int
|
||||
if len(cts) == 2 {
|
||||
idx := strings.Index(cts[1], ")")
|
||||
if colType == core.Enum && cts[1][0] == '\'' { //enum
|
||||
options := strings.Split(cts[1][0:idx], ",")
|
||||
col.EnumOptions = make(map[string]int)
|
||||
for k, v := range options {
|
||||
v = strings.TrimSpace(v)
|
||||
v = strings.Trim(v, "'")
|
||||
col.EnumOptions[v] = k
|
||||
}
|
||||
} else if colType == core.Set && cts[1][0] == '\'' {
|
||||
options := strings.Split(cts[1][0:idx], ",")
|
||||
col.SetOptions = make(map[string]int)
|
||||
for k, v := range options {
|
||||
v = strings.TrimSpace(v)
|
||||
v = strings.Trim(v, "'")
|
||||
col.SetOptions[v] = k
|
||||
}
|
||||
} else {
|
||||
lens := strings.Split(cts[1][0:idx], ",")
|
||||
len1, err = strconv.Atoi(strings.TrimSpace(lens[0]))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if len(lens) == 2 {
|
||||
len2, err = strconv.Atoi(lens[1])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if colType == "FLOAT UNSIGNED" {
|
||||
colType = "FLOAT"
|
||||
}
|
||||
col.Length = len1
|
||||
col.Length2 = len2
|
||||
if _, ok := core.SqlTypes[colType]; ok {
|
||||
col.SQLType = core.SQLType{colType, len1, len2}
|
||||
} else {
|
||||
return nil, nil, errors.New(fmt.Sprintf("unkonw colType %v", colType))
|
||||
}
|
||||
|
||||
if colKey == "PRI" {
|
||||
col.IsPrimaryKey = true
|
||||
}
|
||||
if colKey == "UNI" {
|
||||
//col.is
|
||||
}
|
||||
|
||||
if extra == "auto_increment" {
|
||||
col.IsAutoIncrement = true
|
||||
}
|
||||
|
||||
if col.SQLType.IsText() || col.SQLType.IsTime() {
|
||||
if col.Default != "" {
|
||||
col.Default = "'" + col.Default + "'"
|
||||
} else {
|
||||
if col.DefaultIsEmpty {
|
||||
col.Default = "''"
|
||||
}
|
||||
}
|
||||
}
|
||||
cols[col.Name] = col
|
||||
colSeq = append(colSeq, col.Name)
|
||||
}
|
||||
return colSeq, cols, nil
|
||||
}
|
||||
|
||||
func (db *mysql) GetTables() ([]*core.Table, error) {
|
||||
args := []interface{}{db.DbName}
|
||||
s := "SELECT `TABLE_NAME`, `ENGINE`, `TABLE_ROWS`, `AUTO_INCREMENT` from " +
|
||||
"`INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? AND (`ENGINE`='MyISAM' OR `ENGINE` = 'InnoDB' OR `ENGINE` = 'TokuDB')"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
tables := make([]*core.Table, 0)
|
||||
for rows.Next() {
|
||||
table := core.NewEmptyTable()
|
||||
var name, engine, tableRows string
|
||||
var autoIncr *string
|
||||
err = rows.Scan(&name, &engine, &tableRows, &autoIncr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
table.Name = name
|
||||
table.StoreEngine = engine
|
||||
tables = append(tables, table)
|
||||
}
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
func (db *mysql) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
args := []interface{}{db.DbName, tableName}
|
||||
s := "SELECT `INDEX_NAME`, `NON_UNIQUE`, `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
indexes := make(map[string]*core.Index, 0)
|
||||
for rows.Next() {
|
||||
var indexType int
|
||||
var indexName, colName, nonUnique string
|
||||
err = rows.Scan(&indexName, &nonUnique, &colName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if indexName == "PRIMARY" {
|
||||
continue
|
||||
}
|
||||
|
||||
if "YES" == nonUnique || nonUnique == "1" {
|
||||
indexType = core.IndexType
|
||||
} else {
|
||||
indexType = core.UniqueType
|
||||
}
|
||||
|
||||
colName = strings.Trim(colName, "` ")
|
||||
var isRegular bool
|
||||
if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
|
||||
indexName = indexName[5+len(tableName) : len(indexName)]
|
||||
isRegular = true
|
||||
}
|
||||
|
||||
var index *core.Index
|
||||
var ok bool
|
||||
if index, ok = indexes[indexName]; !ok {
|
||||
index = new(core.Index)
|
||||
index.IsRegular = isRegular
|
||||
index.Type = indexType
|
||||
index.Name = indexName
|
||||
indexes[indexName] = index
|
||||
}
|
||||
index.AddColumn(colName)
|
||||
}
|
||||
return indexes, nil
|
||||
}
|
||||
|
||||
func (db *mysql) Filters() []core.Filter {
|
||||
return []core.Filter{&core.IdFilter{}}
|
||||
}
|
50
vendor/github.com/go-xorm/xorm/mysql_driver.go
generated
vendored
Normal file
50
vendor/github.com/go-xorm/xorm/mysql_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type mysqlDriver struct {
|
||||
}
|
||||
|
||||
func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
dsnPattern := regexp.MustCompile(
|
||||
`^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
|
||||
`(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
|
||||
`\/(?P<dbname>.*?)` + // /dbname
|
||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
||||
names := dsnPattern.SubexpNames()
|
||||
|
||||
uri := &core.Uri{DbType: core.MYSQL}
|
||||
|
||||
for i, match := range matches {
|
||||
switch names[i] {
|
||||
case "dbname":
|
||||
uri.DbName = match
|
||||
case "params":
|
||||
if len(match) > 0 {
|
||||
kvs := strings.Split(match, "&")
|
||||
for _, kv := range kvs {
|
||||
splits := strings.Split(kv, "=")
|
||||
if len(splits) == 2 {
|
||||
switch splits[0] {
|
||||
case "charset":
|
||||
uri.Charset = splits[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return uri, nil
|
||||
}
|
37
vendor/github.com/go-xorm/xorm/oci8_driver.go
generated
vendored
Normal file
37
vendor/github.com/go-xorm/xorm/oci8_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type oci8Driver struct {
|
||||
}
|
||||
|
||||
//dataSourceName=user/password@ipv4:port/dbname
|
||||
//dataSourceName=user/password@[ipv6]:port/dbname
|
||||
func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.ORACLE}
|
||||
dsnPattern := regexp.MustCompile(
|
||||
`^(?P<user>.*)\/(?P<password>.*)@` + // user:password@
|
||||
`(?P<net>.*)` + // ip:port
|
||||
`\/(?P<dbname>.*)`) // dbname
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
names := dsnPattern.SubexpNames()
|
||||
for i, match := range matches {
|
||||
switch names[i] {
|
||||
case "dbname":
|
||||
db.DbName = match
|
||||
}
|
||||
}
|
||||
if db.DbName == "" {
|
||||
return nil, errors.New("dbname is empty")
|
||||
}
|
||||
return db, nil
|
||||
}
|
34
vendor/github.com/go-xorm/xorm/odbc_driver.go
generated
vendored
Normal file
34
vendor/github.com/go-xorm/xorm/odbc_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type odbcDriver struct {
|
||||
}
|
||||
|
||||
func (p *odbcDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
kv := strings.Split(dataSourceName, ";")
|
||||
var dbName string
|
||||
|
||||
for _, c := range kv {
|
||||
vv := strings.Split(strings.TrimSpace(c), "=")
|
||||
if len(vv) == 2 {
|
||||
switch strings.ToLower(vv[0]) {
|
||||
case "database":
|
||||
dbName = vv[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
if dbName == "" {
|
||||
return nil, errors.New("no db name provided")
|
||||
}
|
||||
return &core.Uri{DbName: dbName, DbType: core.MSSQL}, nil
|
||||
}
|
846
vendor/github.com/go-xorm/xorm/oracle_dialect.go
generated
vendored
Normal file
846
vendor/github.com/go-xorm/xorm/oracle_dialect.go
generated
vendored
Normal file
|
@ -0,0 +1,846 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var (
|
||||
oracleReservedWords = map[string]bool{
|
||||
"ACCESS": true,
|
||||
"ACCOUNT": true,
|
||||
"ACTIVATE": true,
|
||||
"ADD": true,
|
||||
"ADMIN": true,
|
||||
"ADVISE": true,
|
||||
"AFTER": true,
|
||||
"ALL": true,
|
||||
"ALL_ROWS": true,
|
||||
"ALLOCATE": true,
|
||||
"ALTER": true,
|
||||
"ANALYZE": true,
|
||||
"AND": true,
|
||||
"ANY": true,
|
||||
"ARCHIVE": true,
|
||||
"ARCHIVELOG": true,
|
||||
"ARRAY": true,
|
||||
"AS": true,
|
||||
"ASC": true,
|
||||
"AT": true,
|
||||
"AUDIT": true,
|
||||
"AUTHENTICATED": true,
|
||||
"AUTHORIZATION": true,
|
||||
"AUTOEXTEND": true,
|
||||
"AUTOMATIC": true,
|
||||
"BACKUP": true,
|
||||
"BECOME": true,
|
||||
"BEFORE": true,
|
||||
"BEGIN": true,
|
||||
"BETWEEN": true,
|
||||
"BFILE": true,
|
||||
"BITMAP": true,
|
||||
"BLOB": true,
|
||||
"BLOCK": true,
|
||||
"BODY": true,
|
||||
"BY": true,
|
||||
"CACHE": true,
|
||||
"CACHE_INSTANCES": true,
|
||||
"CANCEL": true,
|
||||
"CASCADE": true,
|
||||
"CAST": true,
|
||||
"CFILE": true,
|
||||
"CHAINED": true,
|
||||
"CHANGE": true,
|
||||
"CHAR": true,
|
||||
"CHAR_CS": true,
|
||||
"CHARACTER": true,
|
||||
"CHECK": true,
|
||||
"CHECKPOINT": true,
|
||||
"CHOOSE": true,
|
||||
"CHUNK": true,
|
||||
"CLEAR": true,
|
||||
"CLOB": true,
|
||||
"CLONE": true,
|
||||
"CLOSE": true,
|
||||
"CLOSE_CACHED_OPEN_CURSORS": true,
|
||||
"CLUSTER": true,
|
||||
"COALESCE": true,
|
||||
"COLUMN": true,
|
||||
"COLUMNS": true,
|
||||
"COMMENT": true,
|
||||
"COMMIT": true,
|
||||
"COMMITTED": true,
|
||||
"COMPATIBILITY": true,
|
||||
"COMPILE": true,
|
||||
"COMPLETE": true,
|
||||
"COMPOSITE_LIMIT": true,
|
||||
"COMPRESS": true,
|
||||
"COMPUTE": true,
|
||||
"CONNECT": true,
|
||||
"CONNECT_TIME": true,
|
||||
"CONSTRAINT": true,
|
||||
"CONSTRAINTS": true,
|
||||
"CONTENTS": true,
|
||||
"CONTINUE": true,
|
||||
"CONTROLFILE": true,
|
||||
"CONVERT": true,
|
||||
"COST": true,
|
||||
"CPU_PER_CALL": true,
|
||||
"CPU_PER_SESSION": true,
|
||||
"CREATE": true,
|
||||
"CURRENT": true,
|
||||
"CURRENT_SCHEMA": true,
|
||||
"CURREN_USER": true,
|
||||
"CURSOR": true,
|
||||
"CYCLE": true,
|
||||
"DANGLING": true,
|
||||
"DATABASE": true,
|
||||
"DATAFILE": true,
|
||||
"DATAFILES": true,
|
||||
"DATAOBJNO": true,
|
||||
"DATE": true,
|
||||
"DBA": true,
|
||||
"DBHIGH": true,
|
||||
"DBLOW": true,
|
||||
"DBMAC": true,
|
||||
"DEALLOCATE": true,
|
||||
"DEBUG": true,
|
||||
"DEC": true,
|
||||
"DECIMAL": true,
|
||||
"DECLARE": true,
|
||||
"DEFAULT": true,
|
||||
"DEFERRABLE": true,
|
||||
"DEFERRED": true,
|
||||
"DEGREE": true,
|
||||
"DELETE": true,
|
||||
"DEREF": true,
|
||||
"DESC": true,
|
||||
"DIRECTORY": true,
|
||||
"DISABLE": true,
|
||||
"DISCONNECT": true,
|
||||
"DISMOUNT": true,
|
||||
"DISTINCT": true,
|
||||
"DISTRIBUTED": true,
|
||||
"DML": true,
|
||||
"DOUBLE": true,
|
||||
"DROP": true,
|
||||
"DUMP": true,
|
||||
"EACH": true,
|
||||
"ELSE": true,
|
||||
"ENABLE": true,
|
||||
"END": true,
|
||||
"ENFORCE": true,
|
||||
"ENTRY": true,
|
||||
"ESCAPE": true,
|
||||
"EXCEPT": true,
|
||||
"EXCEPTIONS": true,
|
||||
"EXCHANGE": true,
|
||||
"EXCLUDING": true,
|
||||
"EXCLUSIVE": true,
|
||||
"EXECUTE": true,
|
||||
"EXISTS": true,
|
||||
"EXPIRE": true,
|
||||
"EXPLAIN": true,
|
||||
"EXTENT": true,
|
||||
"EXTENTS": true,
|
||||
"EXTERNALLY": true,
|
||||
"FAILED_LOGIN_ATTEMPTS": true,
|
||||
"FALSE": true,
|
||||
"FAST": true,
|
||||
"FILE": true,
|
||||
"FIRST_ROWS": true,
|
||||
"FLAGGER": true,
|
||||
"FLOAT": true,
|
||||
"FLOB": true,
|
||||
"FLUSH": true,
|
||||
"FOR": true,
|
||||
"FORCE": true,
|
||||
"FOREIGN": true,
|
||||
"FREELIST": true,
|
||||
"FREELISTS": true,
|
||||
"FROM": true,
|
||||
"FULL": true,
|
||||
"FUNCTION": true,
|
||||
"GLOBAL": true,
|
||||
"GLOBALLY": true,
|
||||
"GLOBAL_NAME": true,
|
||||
"GRANT": true,
|
||||
"GROUP": true,
|
||||
"GROUPS": true,
|
||||
"HASH": true,
|
||||
"HASHKEYS": true,
|
||||
"HAVING": true,
|
||||
"HEADER": true,
|
||||
"HEAP": true,
|
||||
"IDENTIFIED": true,
|
||||
"IDGENERATORS": true,
|
||||
"IDLE_TIME": true,
|
||||
"IF": true,
|
||||
"IMMEDIATE": true,
|
||||
"IN": true,
|
||||
"INCLUDING": true,
|
||||
"INCREMENT": true,
|
||||
"INDEX": true,
|
||||
"INDEXED": true,
|
||||
"INDEXES": true,
|
||||
"INDICATOR": true,
|
||||
"IND_PARTITION": true,
|
||||
"INITIAL": true,
|
||||
"INITIALLY": true,
|
||||
"INITRANS": true,
|
||||
"INSERT": true,
|
||||
"INSTANCE": true,
|
||||
"INSTANCES": true,
|
||||
"INSTEAD": true,
|
||||
"INT": true,
|
||||
"INTEGER": true,
|
||||
"INTERMEDIATE": true,
|
||||
"INTERSECT": true,
|
||||
"INTO": true,
|
||||
"IS": true,
|
||||
"ISOLATION": true,
|
||||
"ISOLATION_LEVEL": true,
|
||||
"KEEP": true,
|
||||
"KEY": true,
|
||||
"KILL": true,
|
||||
"LABEL": true,
|
||||
"LAYER": true,
|
||||
"LESS": true,
|
||||
"LEVEL": true,
|
||||
"LIBRARY": true,
|
||||
"LIKE": true,
|
||||
"LIMIT": true,
|
||||
"LINK": true,
|
||||
"LIST": true,
|
||||
"LOB": true,
|
||||
"LOCAL": true,
|
||||
"LOCK": true,
|
||||
"LOCKED": true,
|
||||
"LOG": true,
|
||||
"LOGFILE": true,
|
||||
"LOGGING": true,
|
||||
"LOGICAL_READS_PER_CALL": true,
|
||||
"LOGICAL_READS_PER_SESSION": true,
|
||||
"LONG": true,
|
||||
"MANAGE": true,
|
||||
"MASTER": true,
|
||||
"MAX": true,
|
||||
"MAXARCHLOGS": true,
|
||||
"MAXDATAFILES": true,
|
||||
"MAXEXTENTS": true,
|
||||
"MAXINSTANCES": true,
|
||||
"MAXLOGFILES": true,
|
||||
"MAXLOGHISTORY": true,
|
||||
"MAXLOGMEMBERS": true,
|
||||
"MAXSIZE": true,
|
||||
"MAXTRANS": true,
|
||||
"MAXVALUE": true,
|
||||
"MIN": true,
|
||||
"MEMBER": true,
|
||||
"MINIMUM": true,
|
||||
"MINEXTENTS": true,
|
||||
"MINUS": true,
|
||||
"MINVALUE": true,
|
||||
"MLSLABEL": true,
|
||||
"MLS_LABEL_FORMAT": true,
|
||||
"MODE": true,
|
||||
"MODIFY": true,
|
||||
"MOUNT": true,
|
||||
"MOVE": true,
|
||||
"MTS_DISPATCHERS": true,
|
||||
"MULTISET": true,
|
||||
"NATIONAL": true,
|
||||
"NCHAR": true,
|
||||
"NCHAR_CS": true,
|
||||
"NCLOB": true,
|
||||
"NEEDED": true,
|
||||
"NESTED": true,
|
||||
"NETWORK": true,
|
||||
"NEW": true,
|
||||
"NEXT": true,
|
||||
"NOARCHIVELOG": true,
|
||||
"NOAUDIT": true,
|
||||
"NOCACHE": true,
|
||||
"NOCOMPRESS": true,
|
||||
"NOCYCLE": true,
|
||||
"NOFORCE": true,
|
||||
"NOLOGGING": true,
|
||||
"NOMAXVALUE": true,
|
||||
"NOMINVALUE": true,
|
||||
"NONE": true,
|
||||
"NOORDER": true,
|
||||
"NOOVERRIDE": true,
|
||||
"NOPARALLEL": true,
|
||||
"NOREVERSE": true,
|
||||
"NORMAL": true,
|
||||
"NOSORT": true,
|
||||
"NOT": true,
|
||||
"NOTHING": true,
|
||||
"NOWAIT": true,
|
||||
"NULL": true,
|
||||
"NUMBER": true,
|
||||
"NUMERIC": true,
|
||||
"NVARCHAR2": true,
|
||||
"OBJECT": true,
|
||||
"OBJNO": true,
|
||||
"OBJNO_REUSE": true,
|
||||
"OF": true,
|
||||
"OFF": true,
|
||||
"OFFLINE": true,
|
||||
"OID": true,
|
||||
"OIDINDEX": true,
|
||||
"OLD": true,
|
||||
"ON": true,
|
||||
"ONLINE": true,
|
||||
"ONLY": true,
|
||||
"OPCODE": true,
|
||||
"OPEN": true,
|
||||
"OPTIMAL": true,
|
||||
"OPTIMIZER_GOAL": true,
|
||||
"OPTION": true,
|
||||
"OR": true,
|
||||
"ORDER": true,
|
||||
"ORGANIZATION": true,
|
||||
"OSLABEL": true,
|
||||
"OVERFLOW": true,
|
||||
"OWN": true,
|
||||
"PACKAGE": true,
|
||||
"PARALLEL": true,
|
||||
"PARTITION": true,
|
||||
"PASSWORD": true,
|
||||
"PASSWORD_GRACE_TIME": true,
|
||||
"PASSWORD_LIFE_TIME": true,
|
||||
"PASSWORD_LOCK_TIME": true,
|
||||
"PASSWORD_REUSE_MAX": true,
|
||||
"PASSWORD_REUSE_TIME": true,
|
||||
"PASSWORD_VERIFY_FUNCTION": true,
|
||||
"PCTFREE": true,
|
||||
"PCTINCREASE": true,
|
||||
"PCTTHRESHOLD": true,
|
||||
"PCTUSED": true,
|
||||
"PCTVERSION": true,
|
||||
"PERCENT": true,
|
||||
"PERMANENT": true,
|
||||
"PLAN": true,
|
||||
"PLSQL_DEBUG": true,
|
||||
"POST_TRANSACTION": true,
|
||||
"PRECISION": true,
|
||||
"PRESERVE": true,
|
||||
"PRIMARY": true,
|
||||
"PRIOR": true,
|
||||
"PRIVATE": true,
|
||||
"PRIVATE_SGA": true,
|
||||
"PRIVILEGE": true,
|
||||
"PRIVILEGES": true,
|
||||
"PROCEDURE": true,
|
||||
"PROFILE": true,
|
||||
"PUBLIC": true,
|
||||
"PURGE": true,
|
||||
"QUEUE": true,
|
||||
"QUOTA": true,
|
||||
"RANGE": true,
|
||||
"RAW": true,
|
||||
"RBA": true,
|
||||
"READ": true,
|
||||
"READUP": true,
|
||||
"REAL": true,
|
||||
"REBUILD": true,
|
||||
"RECOVER": true,
|
||||
"RECOVERABLE": true,
|
||||
"RECOVERY": true,
|
||||
"REF": true,
|
||||
"REFERENCES": true,
|
||||
"REFERENCING": true,
|
||||
"REFRESH": true,
|
||||
"RENAME": true,
|
||||
"REPLACE": true,
|
||||
"RESET": true,
|
||||
"RESETLOGS": true,
|
||||
"RESIZE": true,
|
||||
"RESOURCE": true,
|
||||
"RESTRICTED": true,
|
||||
"RETURN": true,
|
||||
"RETURNING": true,
|
||||
"REUSE": true,
|
||||
"REVERSE": true,
|
||||
"REVOKE": true,
|
||||
"ROLE": true,
|
||||
"ROLES": true,
|
||||
"ROLLBACK": true,
|
||||
"ROW": true,
|
||||
"ROWID": true,
|
||||
"ROWNUM": true,
|
||||
"ROWS": true,
|
||||
"RULE": true,
|
||||
"SAMPLE": true,
|
||||
"SAVEPOINT": true,
|
||||
"SB4": true,
|
||||
"SCAN_INSTANCES": true,
|
||||
"SCHEMA": true,
|
||||
"SCN": true,
|
||||
"SCOPE": true,
|
||||
"SD_ALL": true,
|
||||
"SD_INHIBIT": true,
|
||||
"SD_SHOW": true,
|
||||
"SEGMENT": true,
|
||||
"SEG_BLOCK": true,
|
||||
"SEG_FILE": true,
|
||||
"SELECT": true,
|
||||
"SEQUENCE": true,
|
||||
"SERIALIZABLE": true,
|
||||
"SESSION": true,
|
||||
"SESSION_CACHED_CURSORS": true,
|
||||
"SESSIONS_PER_USER": true,
|
||||
"SET": true,
|
||||
"SHARE": true,
|
||||
"SHARED": true,
|
||||
"SHARED_POOL": true,
|
||||
"SHRINK": true,
|
||||
"SIZE": true,
|
||||
"SKIP": true,
|
||||
"SKIP_UNUSABLE_INDEXES": true,
|
||||
"SMALLINT": true,
|
||||
"SNAPSHOT": true,
|
||||
"SOME": true,
|
||||
"SORT": true,
|
||||
"SPECIFICATION": true,
|
||||
"SPLIT": true,
|
||||
"SQL_TRACE": true,
|
||||
"STANDBY": true,
|
||||
"START": true,
|
||||
"STATEMENT_ID": true,
|
||||
"STATISTICS": true,
|
||||
"STOP": true,
|
||||
"STORAGE": true,
|
||||
"STORE": true,
|
||||
"STRUCTURE": true,
|
||||
"SUCCESSFUL": true,
|
||||
"SWITCH": true,
|
||||
"SYS_OP_ENFORCE_NOT_NULL$": true,
|
||||
"SYS_OP_NTCIMG$": true,
|
||||
"SYNONYM": true,
|
||||
"SYSDATE": true,
|
||||
"SYSDBA": true,
|
||||
"SYSOPER": true,
|
||||
"SYSTEM": true,
|
||||
"TABLE": true,
|
||||
"TABLES": true,
|
||||
"TABLESPACE": true,
|
||||
"TABLESPACE_NO": true,
|
||||
"TABNO": true,
|
||||
"TEMPORARY": true,
|
||||
"THAN": true,
|
||||
"THE": true,
|
||||
"THEN": true,
|
||||
"THREAD": true,
|
||||
"TIMESTAMP": true,
|
||||
"TIME": true,
|
||||
"TO": true,
|
||||
"TOPLEVEL": true,
|
||||
"TRACE": true,
|
||||
"TRACING": true,
|
||||
"TRANSACTION": true,
|
||||
"TRANSITIONAL": true,
|
||||
"TRIGGER": true,
|
||||
"TRIGGERS": true,
|
||||
"TRUE": true,
|
||||
"TRUNCATE": true,
|
||||
"TX": true,
|
||||
"TYPE": true,
|
||||
"UB2": true,
|
||||
"UBA": true,
|
||||
"UID": true,
|
||||
"UNARCHIVED": true,
|
||||
"UNDO": true,
|
||||
"UNION": true,
|
||||
"UNIQUE": true,
|
||||
"UNLIMITED": true,
|
||||
"UNLOCK": true,
|
||||
"UNRECOVERABLE": true,
|
||||
"UNTIL": true,
|
||||
"UNUSABLE": true,
|
||||
"UNUSED": true,
|
||||
"UPDATABLE": true,
|
||||
"UPDATE": true,
|
||||
"USAGE": true,
|
||||
"USE": true,
|
||||
"USER": true,
|
||||
"USING": true,
|
||||
"VALIDATE": true,
|
||||
"VALIDATION": true,
|
||||
"VALUE": true,
|
||||
"VALUES": true,
|
||||
"VARCHAR": true,
|
||||
"VARCHAR2": true,
|
||||
"VARYING": true,
|
||||
"VIEW": true,
|
||||
"WHEN": true,
|
||||
"WHENEVER": true,
|
||||
"WHERE": true,
|
||||
"WITH": true,
|
||||
"WITHOUT": true,
|
||||
"WORK": true,
|
||||
"WRITE": true,
|
||||
"WRITEDOWN": true,
|
||||
"WRITEUP": true,
|
||||
"XID": true,
|
||||
"YEAR": true,
|
||||
"ZONE": true,
|
||||
}
|
||||
)
|
||||
|
||||
type oracle struct {
|
||||
core.Base
|
||||
}
|
||||
|
||||
func (db *oracle) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
||||
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
}
|
||||
|
||||
func (db *oracle) SqlType(c *core.Column) string {
|
||||
var res string
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool, core.Serial, core.BigSerial:
|
||||
res = "NUMBER"
|
||||
case core.Binary, core.VarBinary, core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob, core.Bytea:
|
||||
return core.Blob
|
||||
case core.Time, core.DateTime, core.TimeStamp:
|
||||
res = core.TimeStamp
|
||||
case core.TimeStampz:
|
||||
res = "TIMESTAMP WITH TIME ZONE"
|
||||
case core.Float, core.Double, core.Numeric, core.Decimal:
|
||||
res = "NUMBER"
|
||||
case core.Text, core.MediumText, core.LongText, core.Json:
|
||||
res = "CLOB"
|
||||
case core.Char, core.Varchar, core.TinyText:
|
||||
res = "VARCHAR2"
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
|
||||
var hasLen1 bool = (c.Length > 0)
|
||||
var hasLen2 bool = (c.Length2 > 0)
|
||||
if hasLen2 {
|
||||
res += "(" + strconv.Itoa(c.Length) + "," + strconv.Itoa(c.Length2) + ")"
|
||||
} else if hasLen1 {
|
||||
res += "(" + strconv.Itoa(c.Length) + ")"
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (db *oracle) AutoIncrStr() string {
|
||||
return "AUTO_INCREMENT"
|
||||
}
|
||||
|
||||
func (db *oracle) SupportInsertMany() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *oracle) IsReserved(name string) bool {
|
||||
_, ok := oracleReservedWords[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (db *oracle) Quote(name string) string {
|
||||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *oracle) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (db *oracle) SupportEngine() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) SupportCharset() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) SupportDropIfExists() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) IndexOnTable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) DropTableSql(tableName string) string {
|
||||
return fmt.Sprintf("DROP TABLE `%s`", tableName)
|
||||
}
|
||||
|
||||
func (b *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string {
|
||||
var sql string
|
||||
sql = "CREATE TABLE "
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
sql += b.Quote(tableName) + " ("
|
||||
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
for _, colName := range table.ColumnsSeq() {
|
||||
col := table.GetColumn(colName)
|
||||
/*if col.IsPrimaryKey && len(pkList) == 1 {
|
||||
sql += col.String(b.dialect)
|
||||
} else {*/
|
||||
sql += col.StringNoPk(b)
|
||||
//}
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 0 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += b.Quote(strings.Join(pkList, b.Quote(",")))
|
||||
sql += " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2] + ")"
|
||||
if b.SupportEngine() && storeEngine != "" {
|
||||
sql += " ENGINE=" + storeEngine
|
||||
}
|
||||
if b.SupportCharset() {
|
||||
if len(charset) == 0 {
|
||||
charset = b.URI().Charset
|
||||
}
|
||||
if len(charset) > 0 {
|
||||
sql += " DEFAULT CHARSET " + charset
|
||||
}
|
||||
}
|
||||
return sql
|
||||
}
|
||||
|
||||
func (db *oracle) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName, idxName}
|
||||
return `SELECT INDEX_NAME FROM USER_INDEXES ` +
|
||||
`WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args
|
||||
}
|
||||
|
||||
func (db *oracle) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName}
|
||||
return `SELECT table_name FROM user_tables WHERE table_name = :1`, args
|
||||
}
|
||||
|
||||
func (db *oracle) MustDropTable(tableName string) error {
|
||||
sql, args := db.TableCheckSql(tableName)
|
||||
db.LogSQL(sql, args)
|
||||
|
||||
rows, err := db.DB().Query(sql, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if !rows.Next() {
|
||||
return nil
|
||||
}
|
||||
|
||||
sql = "Drop Table \"" + tableName + "\""
|
||||
db.LogSQL(sql, args)
|
||||
|
||||
_, err = db.DB().Exec(sql)
|
||||
return err
|
||||
}
|
||||
|
||||
/*func (db *oracle) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
args := []interface{}{strings.ToUpper(tableName), strings.ToUpper(colName)}
|
||||
return "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = ?" +
|
||||
" AND column_name = ?", args
|
||||
}*/
|
||||
|
||||
func (db *oracle) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
args := []interface{}{tableName, colName}
|
||||
query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" +
|
||||
" AND column_name = :2"
|
||||
db.LogSQL(query, args)
|
||||
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
args := []interface{}{tableName}
|
||||
s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," +
|
||||
"nullable FROM USER_TAB_COLUMNS WHERE table_name = :1"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
cols := make(map[string]*core.Column)
|
||||
colSeq := make([]string, 0)
|
||||
for rows.Next() {
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]int)
|
||||
|
||||
var colName, colDefault, nullable, dataType, dataPrecision, dataScale *string
|
||||
var dataLen int
|
||||
|
||||
err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision,
|
||||
&dataScale, &nullable)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
col.Name = strings.Trim(*colName, `" `)
|
||||
if colDefault != nil {
|
||||
col.Default = *colDefault
|
||||
col.DefaultIsEmpty = false
|
||||
}
|
||||
|
||||
if *nullable == "Y" {
|
||||
col.Nullable = true
|
||||
} else {
|
||||
col.Nullable = false
|
||||
}
|
||||
|
||||
var ignore bool
|
||||
|
||||
var dt string
|
||||
var len1, len2 int
|
||||
dts := strings.Split(*dataType, "(")
|
||||
dt = dts[0]
|
||||
if len(dts) > 1 {
|
||||
lens := strings.Split(dts[1][:len(dts[1])-1], ",")
|
||||
if len(lens) > 1 {
|
||||
len1, _ = strconv.Atoi(lens[0])
|
||||
len2, _ = strconv.Atoi(lens[1])
|
||||
} else {
|
||||
len1, _ = strconv.Atoi(lens[0])
|
||||
}
|
||||
}
|
||||
|
||||
switch dt {
|
||||
case "VARCHAR2":
|
||||
col.SQLType = core.SQLType{core.Varchar, len1, len2}
|
||||
case "NVARCHAR2":
|
||||
col.SQLType = core.SQLType{core.NVarchar, len1, len2}
|
||||
case "TIMESTAMP WITH TIME ZONE":
|
||||
col.SQLType = core.SQLType{core.TimeStampz, 0, 0}
|
||||
case "NUMBER":
|
||||
col.SQLType = core.SQLType{core.Double, len1, len2}
|
||||
case "LONG", "LONG RAW":
|
||||
col.SQLType = core.SQLType{core.Text, 0, 0}
|
||||
case "RAW":
|
||||
col.SQLType = core.SQLType{core.Binary, 0, 0}
|
||||
case "ROWID":
|
||||
col.SQLType = core.SQLType{core.Varchar, 18, 0}
|
||||
case "AQ$_SUBSCRIBERS":
|
||||
ignore = true
|
||||
default:
|
||||
col.SQLType = core.SQLType{strings.ToUpper(dt), len1, len2}
|
||||
}
|
||||
|
||||
if ignore {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := core.SqlTypes[col.SQLType.Name]; !ok {
|
||||
return nil, nil, errors.New(fmt.Sprintf("unkonw colType %v %v", *dataType, col.SQLType))
|
||||
}
|
||||
|
||||
col.Length = dataLen
|
||||
|
||||
if col.SQLType.IsText() || col.SQLType.IsTime() {
|
||||
if !col.DefaultIsEmpty {
|
||||
col.Default = "'" + col.Default + "'"
|
||||
}
|
||||
}
|
||||
cols[col.Name] = col
|
||||
colSeq = append(colSeq, col.Name)
|
||||
}
|
||||
|
||||
return colSeq, cols, nil
|
||||
}
|
||||
|
||||
func (db *oracle) GetTables() ([]*core.Table, error) {
|
||||
args := []interface{}{}
|
||||
s := "SELECT table_name FROM user_tables"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
tables := make([]*core.Table, 0)
|
||||
for rows.Next() {
|
||||
table := core.NewEmptyTable()
|
||||
err = rows.Scan(&table.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tables = append(tables, table)
|
||||
}
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
func (db *oracle) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
args := []interface{}{tableName}
|
||||
s := "SELECT t.column_name,i.uniqueness,i.index_name FROM user_ind_columns t,user_indexes i " +
|
||||
"WHERE t.index_name = i.index_name and t.table_name = i.table_name and t.table_name =:1"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
indexes := make(map[string]*core.Index, 0)
|
||||
for rows.Next() {
|
||||
var indexType int
|
||||
var indexName, colName, uniqueness string
|
||||
|
||||
err = rows.Scan(&colName, &uniqueness, &indexName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
indexName = strings.Trim(indexName, `" `)
|
||||
|
||||
if uniqueness == "UNIQUE" {
|
||||
indexType = core.UniqueType
|
||||
} else {
|
||||
indexType = core.IndexType
|
||||
}
|
||||
|
||||
var index *core.Index
|
||||
var ok bool
|
||||
if index, ok = indexes[indexName]; !ok {
|
||||
index = new(core.Index)
|
||||
index.Type = indexType
|
||||
index.Name = indexName
|
||||
indexes[indexName] = index
|
||||
}
|
||||
index.AddColumn(colName)
|
||||
}
|
||||
return indexes, nil
|
||||
}
|
||||
|
||||
func (db *oracle) Filters() []core.Filter {
|
||||
return []core.Filter{&core.QuoteFilter{}, &core.SeqFilter{":", 1}, &core.IdFilter{}}
|
||||
}
|
746
vendor/github.com/go-xorm/xorm/pg_reserved.txt
generated
vendored
Normal file
746
vendor/github.com/go-xorm/xorm/pg_reserved.txt
generated
vendored
Normal file
|
@ -0,0 +1,746 @@
|
|||
A non-reserved non-reserved
|
||||
ABORT non-reserved
|
||||
ABS reserved reserved
|
||||
ABSENT non-reserved non-reserved
|
||||
ABSOLUTE non-reserved non-reserved non-reserved reserved
|
||||
ACCESS non-reserved
|
||||
ACCORDING non-reserved non-reserved
|
||||
ACTION non-reserved non-reserved non-reserved reserved
|
||||
ADA non-reserved non-reserved non-reserved
|
||||
ADD non-reserved non-reserved non-reserved reserved
|
||||
ADMIN non-reserved non-reserved non-reserved
|
||||
AFTER non-reserved non-reserved non-reserved
|
||||
AGGREGATE non-reserved
|
||||
ALL reserved reserved reserved reserved
|
||||
ALLOCATE reserved reserved reserved
|
||||
ALSO non-reserved
|
||||
ALTER non-reserved reserved reserved reserved
|
||||
ALWAYS non-reserved non-reserved non-reserved
|
||||
ANALYSE reserved
|
||||
ANALYZE reserved
|
||||
AND reserved reserved reserved reserved
|
||||
ANY reserved reserved reserved reserved
|
||||
ARE reserved reserved reserved
|
||||
ARRAY reserved reserved reserved
|
||||
ARRAY_AGG reserved reserved
|
||||
ARRAY_MAX_CARDINALITY reserved
|
||||
AS reserved reserved reserved reserved
|
||||
ASC reserved non-reserved non-reserved reserved
|
||||
ASENSITIVE reserved reserved
|
||||
ASSERTION non-reserved non-reserved non-reserved reserved
|
||||
ASSIGNMENT non-reserved non-reserved non-reserved
|
||||
ASYMMETRIC reserved reserved reserved
|
||||
AT non-reserved reserved reserved reserved
|
||||
ATOMIC reserved reserved
|
||||
ATTRIBUTE non-reserved non-reserved non-reserved
|
||||
ATTRIBUTES non-reserved non-reserved
|
||||
AUTHORIZATION reserved (can be function or type) reserved reserved reserved
|
||||
AVG reserved reserved reserved
|
||||
BACKWARD non-reserved
|
||||
BASE64 non-reserved non-reserved
|
||||
BEFORE non-reserved non-reserved non-reserved
|
||||
BEGIN non-reserved reserved reserved reserved
|
||||
BEGIN_FRAME reserved
|
||||
BEGIN_PARTITION reserved
|
||||
BERNOULLI non-reserved non-reserved
|
||||
BETWEEN non-reserved (cannot be function or type) reserved reserved reserved
|
||||
BIGINT non-reserved (cannot be function or type) reserved reserved
|
||||
BINARY reserved (can be function or type) reserved reserved
|
||||
BIT non-reserved (cannot be function or type) reserved
|
||||
BIT_LENGTH reserved
|
||||
BLOB reserved reserved
|
||||
BLOCKED non-reserved non-reserved
|
||||
BOM non-reserved non-reserved
|
||||
BOOLEAN non-reserved (cannot be function or type) reserved reserved
|
||||
BOTH reserved reserved reserved reserved
|
||||
BREADTH non-reserved non-reserved
|
||||
BY non-reserved reserved reserved reserved
|
||||
C non-reserved non-reserved non-reserved
|
||||
CACHE non-reserved
|
||||
CALL reserved reserved
|
||||
CALLED non-reserved reserved reserved
|
||||
CARDINALITY reserved reserved
|
||||
CASCADE non-reserved non-reserved non-reserved reserved
|
||||
CASCADED non-reserved reserved reserved reserved
|
||||
CASE reserved reserved reserved reserved
|
||||
CAST reserved reserved reserved reserved
|
||||
CATALOG non-reserved non-reserved non-reserved reserved
|
||||
CATALOG_NAME non-reserved non-reserved non-reserved
|
||||
CEIL reserved reserved
|
||||
CEILING reserved reserved
|
||||
CHAIN non-reserved non-reserved non-reserved
|
||||
CHAR non-reserved (cannot be function or type) reserved reserved reserved
|
||||
CHARACTER non-reserved (cannot be function or type) reserved reserved reserved
|
||||
CHARACTERISTICS non-reserved non-reserved non-reserved
|
||||
CHARACTERS non-reserved non-reserved
|
||||
CHARACTER_LENGTH reserved reserved reserved
|
||||
CHARACTER_SET_CATALOG non-reserved non-reserved non-reserved
|
||||
CHARACTER_SET_NAME non-reserved non-reserved non-reserved
|
||||
CHARACTER_SET_SCHEMA non-reserved non-reserved non-reserved
|
||||
CHAR_LENGTH reserved reserved reserved
|
||||
CHECK reserved reserved reserved reserved
|
||||
CHECKPOINT non-reserved
|
||||
CLASS non-reserved
|
||||
CLASS_ORIGIN non-reserved non-reserved non-reserved
|
||||
CLOB reserved reserved
|
||||
CLOSE non-reserved reserved reserved reserved
|
||||
CLUSTER non-reserved
|
||||
COALESCE non-reserved (cannot be function or type) reserved reserved reserved
|
||||
COBOL non-reserved non-reserved non-reserved
|
||||
COLLATE reserved reserved reserved reserved
|
||||
COLLATION reserved (can be function or type) non-reserved non-reserved reserved
|
||||
COLLATION_CATALOG non-reserved non-reserved non-reserved
|
||||
COLLATION_NAME non-reserved non-reserved non-reserved
|
||||
COLLATION_SCHEMA non-reserved non-reserved non-reserved
|
||||
COLLECT reserved reserved
|
||||
COLUMN reserved reserved reserved reserved
|
||||
COLUMNS non-reserved non-reserved
|
||||
COLUMN_NAME non-reserved non-reserved non-reserved
|
||||
COMMAND_FUNCTION non-reserved non-reserved non-reserved
|
||||
COMMAND_FUNCTION_CODE non-reserved non-reserved
|
||||
COMMENT non-reserved
|
||||
COMMENTS non-reserved
|
||||
COMMIT non-reserved reserved reserved reserved
|
||||
COMMITTED non-reserved non-reserved non-reserved non-reserved
|
||||
CONCURRENTLY reserved (can be function or type)
|
||||
CONDITION reserved reserved
|
||||
CONDITION_NUMBER non-reserved non-reserved non-reserved
|
||||
CONFIGURATION non-reserved
|
||||
CONNECT reserved reserved reserved
|
||||
CONNECTION non-reserved non-reserved non-reserved reserved
|
||||
CONNECTION_NAME non-reserved non-reserved non-reserved
|
||||
CONSTRAINT reserved reserved reserved reserved
|
||||
CONSTRAINTS non-reserved non-reserved non-reserved reserved
|
||||
CONSTRAINT_CATALOG non-reserved non-reserved non-reserved
|
||||
CONSTRAINT_NAME non-reserved non-reserved non-reserved
|
||||
CONSTRAINT_SCHEMA non-reserved non-reserved non-reserved
|
||||
CONSTRUCTOR non-reserved non-reserved
|
||||
CONTAINS reserved non-reserved
|
||||
CONTENT non-reserved non-reserved non-reserved
|
||||
CONTINUE non-reserved non-reserved non-reserved reserved
|
||||
CONTROL non-reserved non-reserved
|
||||
CONVERSION non-reserved
|
||||
CONVERT reserved reserved reserved
|
||||
COPY non-reserved
|
||||
CORR reserved reserved
|
||||
CORRESPONDING reserved reserved reserved
|
||||
COST non-reserved
|
||||
COUNT reserved reserved reserved
|
||||
COVAR_POP reserved reserved
|
||||
COVAR_SAMP reserved reserved
|
||||
CREATE reserved reserved reserved reserved
|
||||
CROSS reserved (can be function or type) reserved reserved reserved
|
||||
CSV non-reserved
|
||||
CUBE reserved reserved
|
||||
CUME_DIST reserved reserved
|
||||
CURRENT non-reserved reserved reserved reserved
|
||||
CURRENT_CATALOG reserved reserved reserved
|
||||
CURRENT_DATE reserved reserved reserved reserved
|
||||
CURRENT_DEFAULT_TRANSFORM_GROUP reserved reserved
|
||||
CURRENT_PATH reserved reserved
|
||||
CURRENT_ROLE reserved reserved reserved
|
||||
CURRENT_ROW reserved
|
||||
CURRENT_SCHEMA reserved (can be function or type) reserved reserved
|
||||
CURRENT_TIME reserved reserved reserved reserved
|
||||
CURRENT_TIMESTAMP reserved reserved reserved reserved
|
||||
CURRENT_TRANSFORM_GROUP_FOR_TYPE reserved reserved
|
||||
CURRENT_USER reserved reserved reserved reserved
|
||||
CURSOR non-reserved reserved reserved reserved
|
||||
CURSOR_NAME non-reserved non-reserved non-reserved
|
||||
CYCLE non-reserved reserved reserved
|
||||
DATA non-reserved non-reserved non-reserved non-reserved
|
||||
DATABASE non-reserved
|
||||
DATALINK reserved reserved
|
||||
DATE reserved reserved reserved
|
||||
DATETIME_INTERVAL_CODE non-reserved non-reserved non-reserved
|
||||
DATETIME_INTERVAL_PRECISION non-reserved non-reserved non-reserved
|
||||
DAY non-reserved reserved reserved reserved
|
||||
DB non-reserved non-reserved
|
||||
DEALLOCATE non-reserved reserved reserved reserved
|
||||
DEC non-reserved (cannot be function or type) reserved reserved reserved
|
||||
DECIMAL non-reserved (cannot be function or type) reserved reserved reserved
|
||||
DECLARE non-reserved reserved reserved reserved
|
||||
DEFAULT reserved reserved reserved reserved
|
||||
DEFAULTS non-reserved non-reserved non-reserved
|
||||
DEFERRABLE reserved non-reserved non-reserved reserved
|
||||
DEFERRED non-reserved non-reserved non-reserved reserved
|
||||
DEFINED non-reserved non-reserved
|
||||
DEFINER non-reserved non-reserved non-reserved
|
||||
DEGREE non-reserved non-reserved
|
||||
DELETE non-reserved reserved reserved reserved
|
||||
DELIMITER non-reserved
|
||||
DELIMITERS non-reserved
|
||||
DENSE_RANK reserved reserved
|
||||
DEPTH non-reserved non-reserved
|
||||
DEREF reserved reserved
|
||||
DERIVED non-reserved non-reserved
|
||||
DESC reserved non-reserved non-reserved reserved
|
||||
DESCRIBE reserved reserved reserved
|
||||
DESCRIPTOR non-reserved non-reserved reserved
|
||||
DETERMINISTIC reserved reserved
|
||||
DIAGNOSTICS non-reserved non-reserved reserved
|
||||
DICTIONARY non-reserved
|
||||
DISABLE non-reserved
|
||||
DISCARD non-reserved
|
||||
DISCONNECT reserved reserved reserved
|
||||
DISPATCH non-reserved non-reserved
|
||||
DISTINCT reserved reserved reserved reserved
|
||||
DLNEWCOPY reserved reserved
|
||||
DLPREVIOUSCOPY reserved reserved
|
||||
DLURLCOMPLETE reserved reserved
|
||||
DLURLCOMPLETEONLY reserved reserved
|
||||
DLURLCOMPLETEWRITE reserved reserved
|
||||
DLURLPATH reserved reserved
|
||||
DLURLPATHONLY reserved reserved
|
||||
DLURLPATHWRITE reserved reserved
|
||||
DLURLSCHEME reserved reserved
|
||||
DLURLSERVER reserved reserved
|
||||
DLVALUE reserved reserved
|
||||
DO reserved
|
||||
DOCUMENT non-reserved non-reserved non-reserved
|
||||
DOMAIN non-reserved non-reserved non-reserved reserved
|
||||
DOUBLE non-reserved reserved reserved reserved
|
||||
DROP non-reserved reserved reserved reserved
|
||||
DYNAMIC reserved reserved
|
||||
DYNAMIC_FUNCTION non-reserved non-reserved non-reserved
|
||||
DYNAMIC_FUNCTION_CODE non-reserved non-reserved
|
||||
EACH non-reserved reserved reserved
|
||||
ELEMENT reserved reserved
|
||||
ELSE reserved reserved reserved reserved
|
||||
EMPTY non-reserved non-reserved
|
||||
ENABLE non-reserved
|
||||
ENCODING non-reserved non-reserved non-reserved
|
||||
ENCRYPTED non-reserved
|
||||
END reserved reserved reserved reserved
|
||||
END-EXEC reserved reserved reserved
|
||||
END_FRAME reserved
|
||||
END_PARTITION reserved
|
||||
ENFORCED non-reserved
|
||||
ENUM non-reserved
|
||||
EQUALS reserved non-reserved
|
||||
ESCAPE non-reserved reserved reserved reserved
|
||||
EVENT non-reserved
|
||||
EVERY reserved reserved
|
||||
EXCEPT reserved reserved reserved reserved
|
||||
EXCEPTION reserved
|
||||
EXCLUDE non-reserved non-reserved non-reserved
|
||||
EXCLUDING non-reserved non-reserved non-reserved
|
||||
EXCLUSIVE non-reserved
|
||||
EXEC reserved reserved reserved
|
||||
EXECUTE non-reserved reserved reserved reserved
|
||||
EXISTS non-reserved (cannot be function or type) reserved reserved reserved
|
||||
EXP reserved reserved
|
||||
EXPLAIN non-reserved
|
||||
EXPRESSION non-reserved
|
||||
EXTENSION non-reserved
|
||||
EXTERNAL non-reserved reserved reserved reserved
|
||||
EXTRACT non-reserved (cannot be function or type) reserved reserved reserved
|
||||
FALSE reserved reserved reserved reserved
|
||||
FAMILY non-reserved
|
||||
FETCH reserved reserved reserved reserved
|
||||
FILE non-reserved non-reserved
|
||||
FILTER reserved reserved
|
||||
FINAL non-reserved non-reserved
|
||||
FIRST non-reserved non-reserved non-reserved reserved
|
||||
FIRST_VALUE reserved reserved
|
||||
FLAG non-reserved non-reserved
|
||||
FLOAT non-reserved (cannot be function or type) reserved reserved reserved
|
||||
FLOOR reserved reserved
|
||||
FOLLOWING non-reserved non-reserved non-reserved
|
||||
FOR reserved reserved reserved reserved
|
||||
FORCE non-reserved
|
||||
FOREIGN reserved reserved reserved reserved
|
||||
FORTRAN non-reserved non-reserved non-reserved
|
||||
FORWARD non-reserved
|
||||
FOUND non-reserved non-reserved reserved
|
||||
FRAME_ROW reserved
|
||||
FREE reserved reserved
|
||||
FREEZE reserved (can be function or type)
|
||||
FROM reserved reserved reserved reserved
|
||||
FS non-reserved non-reserved
|
||||
FULL reserved (can be function or type) reserved reserved reserved
|
||||
FUNCTION non-reserved reserved reserved
|
||||
FUNCTIONS non-reserved
|
||||
FUSION reserved reserved
|
||||
G non-reserved non-reserved
|
||||
GENERAL non-reserved non-reserved
|
||||
GENERATED non-reserved non-reserved
|
||||
GET reserved reserved reserved
|
||||
GLOBAL non-reserved reserved reserved reserved
|
||||
GO non-reserved non-reserved reserved
|
||||
GOTO non-reserved non-reserved reserved
|
||||
GRANT reserved reserved reserved reserved
|
||||
GRANTED non-reserved non-reserved non-reserved
|
||||
GREATEST non-reserved (cannot be function or type)
|
||||
GROUP reserved reserved reserved reserved
|
||||
GROUPING reserved reserved
|
||||
GROUPS reserved
|
||||
HANDLER non-reserved
|
||||
HAVING reserved reserved reserved reserved
|
||||
HEADER non-reserved
|
||||
HEX non-reserved non-reserved
|
||||
HIERARCHY non-reserved non-reserved
|
||||
HOLD non-reserved reserved reserved
|
||||
HOUR non-reserved reserved reserved reserved
|
||||
ID non-reserved non-reserved
|
||||
IDENTITY non-reserved reserved reserved reserved
|
||||
IF non-reserved
|
||||
IGNORE non-reserved non-reserved
|
||||
ILIKE reserved (can be function or type)
|
||||
IMMEDIATE non-reserved non-reserved non-reserved reserved
|
||||
IMMEDIATELY non-reserved
|
||||
IMMUTABLE non-reserved
|
||||
IMPLEMENTATION non-reserved non-reserved
|
||||
IMPLICIT non-reserved
|
||||
IMPORT reserved reserved
|
||||
IN reserved reserved reserved reserved
|
||||
INCLUDING non-reserved non-reserved non-reserved
|
||||
INCREMENT non-reserved non-reserved non-reserved
|
||||
INDENT non-reserved non-reserved
|
||||
INDEX non-reserved
|
||||
INDEXES non-reserved
|
||||
INDICATOR reserved reserved reserved
|
||||
INHERIT non-reserved
|
||||
INHERITS non-reserved
|
||||
INITIALLY reserved non-reserved non-reserved reserved
|
||||
INLINE non-reserved
|
||||
INNER reserved (can be function or type) reserved reserved reserved
|
||||
INOUT non-reserved (cannot be function or type) reserved reserved
|
||||
INPUT non-reserved non-reserved non-reserved reserved
|
||||
INSENSITIVE non-reserved reserved reserved reserved
|
||||
INSERT non-reserved reserved reserved reserved
|
||||
INSTANCE non-reserved non-reserved
|
||||
INSTANTIABLE non-reserved non-reserved
|
||||
INSTEAD non-reserved non-reserved non-reserved
|
||||
INT non-reserved (cannot be function or type) reserved reserved reserved
|
||||
INTEGER non-reserved (cannot be function or type) reserved reserved reserved
|
||||
INTEGRITY non-reserved non-reserved
|
||||
INTERSECT reserved reserved reserved reserved
|
||||
INTERSECTION reserved reserved
|
||||
INTERVAL non-reserved (cannot be function or type) reserved reserved reserved
|
||||
INTO reserved reserved reserved reserved
|
||||
INVOKER non-reserved non-reserved non-reserved
|
||||
IS reserved (can be function or type) reserved reserved reserved
|
||||
ISNULL reserved (can be function or type)
|
||||
ISOLATION non-reserved non-reserved non-reserved reserved
|
||||
JOIN reserved (can be function or type) reserved reserved reserved
|
||||
K non-reserved non-reserved
|
||||
KEY non-reserved non-reserved non-reserved reserved
|
||||
KEY_MEMBER non-reserved non-reserved
|
||||
KEY_TYPE non-reserved non-reserved
|
||||
LABEL non-reserved
|
||||
LAG reserved reserved
|
||||
LANGUAGE non-reserved reserved reserved reserved
|
||||
LARGE non-reserved reserved reserved
|
||||
LAST non-reserved non-reserved non-reserved reserved
|
||||
LAST_VALUE reserved reserved
|
||||
LATERAL reserved reserved reserved
|
||||
LC_COLLATE non-reserved
|
||||
LC_CTYPE non-reserved
|
||||
LEAD reserved reserved
|
||||
LEADING reserved reserved reserved reserved
|
||||
LEAKPROOF non-reserved
|
||||
LEAST non-reserved (cannot be function or type)
|
||||
LEFT reserved (can be function or type) reserved reserved reserved
|
||||
LENGTH non-reserved non-reserved non-reserved
|
||||
LEVEL non-reserved non-reserved non-reserved reserved
|
||||
LIBRARY non-reserved non-reserved
|
||||
LIKE reserved (can be function or type) reserved reserved reserved
|
||||
LIKE_REGEX reserved reserved
|
||||
LIMIT reserved non-reserved non-reserved
|
||||
LINK non-reserved non-reserved
|
||||
LISTEN non-reserved
|
||||
LN reserved reserved
|
||||
LOAD non-reserved
|
||||
LOCAL non-reserved reserved reserved reserved
|
||||
LOCALTIME reserved reserved reserved
|
||||
LOCALTIMESTAMP reserved reserved reserved
|
||||
LOCATION non-reserved non-reserved non-reserved
|
||||
LOCATOR non-reserved non-reserved
|
||||
LOCK non-reserved
|
||||
LOWER reserved reserved reserved
|
||||
M non-reserved non-reserved
|
||||
MAP non-reserved non-reserved
|
||||
MAPPING non-reserved non-reserved non-reserved
|
||||
MATCH non-reserved reserved reserved reserved
|
||||
MATCHED non-reserved non-reserved
|
||||
MATERIALIZED non-reserved
|
||||
MAX reserved reserved reserved
|
||||
MAXVALUE non-reserved non-reserved non-reserved
|
||||
MAX_CARDINALITY reserved
|
||||
MEMBER reserved reserved
|
||||
MERGE reserved reserved
|
||||
MESSAGE_LENGTH non-reserved non-reserved non-reserved
|
||||
MESSAGE_OCTET_LENGTH non-reserved non-reserved non-reserved
|
||||
MESSAGE_TEXT non-reserved non-reserved non-reserved
|
||||
METHOD reserved reserved
|
||||
MIN reserved reserved reserved
|
||||
MINUTE non-reserved reserved reserved reserved
|
||||
MINVALUE non-reserved non-reserved non-reserved
|
||||
MOD reserved reserved
|
||||
MODE non-reserved
|
||||
MODIFIES reserved reserved
|
||||
MODULE reserved reserved reserved
|
||||
MONTH non-reserved reserved reserved reserved
|
||||
MORE non-reserved non-reserved non-reserved
|
||||
MOVE non-reserved
|
||||
MULTISET reserved reserved
|
||||
MUMPS non-reserved non-reserved non-reserved
|
||||
NAME non-reserved non-reserved non-reserved non-reserved
|
||||
NAMES non-reserved non-reserved non-reserved reserved
|
||||
NAMESPACE non-reserved non-reserved
|
||||
NATIONAL non-reserved (cannot be function or type) reserved reserved reserved
|
||||
NATURAL reserved (can be function or type) reserved reserved reserved
|
||||
NCHAR non-reserved (cannot be function or type) reserved reserved reserved
|
||||
NCLOB reserved reserved
|
||||
NESTING non-reserved non-reserved
|
||||
NEW reserved reserved
|
||||
NEXT non-reserved non-reserved non-reserved reserved
|
||||
NFC non-reserved non-reserved
|
||||
NFD non-reserved non-reserved
|
||||
NFKC non-reserved non-reserved
|
||||
NFKD non-reserved non-reserved
|
||||
NIL non-reserved non-reserved
|
||||
NO non-reserved reserved reserved reserved
|
||||
NONE non-reserved (cannot be function or type) reserved reserved
|
||||
NORMALIZE reserved reserved
|
||||
NORMALIZED non-reserved non-reserved
|
||||
NOT reserved reserved reserved reserved
|
||||
NOTHING non-reserved
|
||||
NOTIFY non-reserved
|
||||
NOTNULL reserved (can be function or type)
|
||||
NOWAIT non-reserved
|
||||
NTH_VALUE reserved reserved
|
||||
NTILE reserved reserved
|
||||
NULL reserved reserved reserved reserved
|
||||
NULLABLE non-reserved non-reserved non-reserved
|
||||
NULLIF non-reserved (cannot be function or type) reserved reserved reserved
|
||||
NULLS non-reserved non-reserved non-reserved
|
||||
NUMBER non-reserved non-reserved non-reserved
|
||||
NUMERIC non-reserved (cannot be function or type) reserved reserved reserved
|
||||
OBJECT non-reserved non-reserved non-reserved
|
||||
OCCURRENCES_REGEX reserved reserved
|
||||
OCTETS non-reserved non-reserved
|
||||
OCTET_LENGTH reserved reserved reserved
|
||||
OF non-reserved reserved reserved reserved
|
||||
OFF non-reserved non-reserved non-reserved
|
||||
OFFSET reserved reserved reserved
|
||||
OIDS non-reserved
|
||||
OLD reserved reserved
|
||||
ON reserved reserved reserved reserved
|
||||
ONLY reserved reserved reserved reserved
|
||||
OPEN reserved reserved reserved
|
||||
OPERATOR non-reserved
|
||||
OPTION non-reserved non-reserved non-reserved reserved
|
||||
OPTIONS non-reserved non-reserved non-reserved
|
||||
OR reserved reserved reserved reserved
|
||||
ORDER reserved reserved reserved reserved
|
||||
ORDERING non-reserved non-reserved
|
||||
ORDINALITY non-reserved non-reserved
|
||||
OTHERS non-reserved non-reserved
|
||||
OUT non-reserved (cannot be function or type) reserved reserved
|
||||
OUTER reserved (can be function or type) reserved reserved reserved
|
||||
OUTPUT non-reserved non-reserved reserved
|
||||
OVER reserved (can be function or type) reserved reserved
|
||||
OVERLAPS reserved (can be function or type) reserved reserved reserved
|
||||
OVERLAY non-reserved (cannot be function or type) reserved reserved
|
||||
OVERRIDING non-reserved non-reserved
|
||||
OWNED non-reserved
|
||||
OWNER non-reserved
|
||||
P non-reserved non-reserved
|
||||
PAD non-reserved non-reserved reserved
|
||||
PARAMETER reserved reserved
|
||||
PARAMETER_MODE non-reserved non-reserved
|
||||
PARAMETER_NAME non-reserved non-reserved
|
||||
PARAMETER_ORDINAL_POSITION non-reserved non-reserved
|
||||
PARAMETER_SPECIFIC_CATALOG non-reserved non-reserved
|
||||
PARAMETER_SPECIFIC_NAME non-reserved non-reserved
|
||||
PARAMETER_SPECIFIC_SCHEMA non-reserved non-reserved
|
||||
PARSER non-reserved
|
||||
PARTIAL non-reserved non-reserved non-reserved reserved
|
||||
PARTITION non-reserved reserved reserved
|
||||
PASCAL non-reserved non-reserved non-reserved
|
||||
PASSING non-reserved non-reserved non-reserved
|
||||
PASSTHROUGH non-reserved non-reserved
|
||||
PASSWORD non-reserved
|
||||
PATH non-reserved non-reserved
|
||||
PERCENT reserved
|
||||
PERCENTILE_CONT reserved reserved
|
||||
PERCENTILE_DISC reserved reserved
|
||||
PERCENT_RANK reserved reserved
|
||||
PERIOD reserved
|
||||
PERMISSION non-reserved non-reserved
|
||||
PLACING reserved non-reserved non-reserved
|
||||
PLANS non-reserved
|
||||
PLI non-reserved non-reserved non-reserved
|
||||
PORTION reserved
|
||||
POSITION non-reserved (cannot be function or type) reserved reserved reserved
|
||||
POSITION_REGEX reserved reserved
|
||||
POWER reserved reserved
|
||||
PRECEDES reserved
|
||||
PRECEDING non-reserved non-reserved non-reserved
|
||||
PRECISION non-reserved (cannot be function or type) reserved reserved reserved
|
||||
PREPARE non-reserved reserved reserved reserved
|
||||
PREPARED non-reserved
|
||||
PRESERVE non-reserved non-reserved non-reserved reserved
|
||||
PRIMARY reserved reserved reserved reserved
|
||||
PRIOR non-reserved non-reserved non-reserved reserved
|
||||
PRIVILEGES non-reserved non-reserved non-reserved reserved
|
||||
PROCEDURAL non-reserved
|
||||
PROCEDURE non-reserved reserved reserved reserved
|
||||
PROGRAM non-reserved
|
||||
PUBLIC non-reserved non-reserved reserved
|
||||
QUOTE non-reserved
|
||||
RANGE non-reserved reserved reserved
|
||||
RANK reserved reserved
|
||||
READ non-reserved non-reserved non-reserved reserved
|
||||
READS reserved reserved
|
||||
REAL non-reserved (cannot be function or type) reserved reserved reserved
|
||||
REASSIGN non-reserved
|
||||
RECHECK non-reserved
|
||||
RECOVERY non-reserved non-reserved
|
||||
RECURSIVE non-reserved reserved reserved
|
||||
REF non-reserved reserved reserved
|
||||
REFERENCES reserved reserved reserved reserved
|
||||
REFERENCING reserved reserved
|
||||
REFRESH non-reserved
|
||||
REGR_AVGX reserved reserved
|
||||
REGR_AVGY reserved reserved
|
||||
REGR_COUNT reserved reserved
|
||||
REGR_INTERCEPT reserved reserved
|
||||
REGR_R2 reserved reserved
|
||||
REGR_SLOPE reserved reserved
|
||||
REGR_SXX reserved reserved
|
||||
REGR_SXY reserved reserved
|
||||
REGR_SYY reserved reserved
|
||||
REINDEX non-reserved
|
||||
RELATIVE non-reserved non-reserved non-reserved reserved
|
||||
RELEASE non-reserved reserved reserved
|
||||
RENAME non-reserved
|
||||
REPEATABLE non-reserved non-reserved non-reserved non-reserved
|
||||
REPLACE non-reserved
|
||||
REPLICA non-reserved
|
||||
REQUIRING non-reserved non-reserved
|
||||
RESET non-reserved
|
||||
RESPECT non-reserved non-reserved
|
||||
RESTART non-reserved non-reserved non-reserved
|
||||
RESTORE non-reserved non-reserved
|
||||
RESTRICT non-reserved non-reserved non-reserved reserved
|
||||
RESULT reserved reserved
|
||||
RETURN reserved reserved
|
||||
RETURNED_CARDINALITY non-reserved non-reserved
|
||||
RETURNED_LENGTH non-reserved non-reserved non-reserved
|
||||
RETURNED_OCTET_LENGTH non-reserved non-reserved non-reserved
|
||||
RETURNED_SQLSTATE non-reserved non-reserved non-reserved
|
||||
RETURNING reserved non-reserved non-reserved
|
||||
RETURNS non-reserved reserved reserved
|
||||
REVOKE non-reserved reserved reserved reserved
|
||||
RIGHT reserved (can be function or type) reserved reserved reserved
|
||||
ROLE non-reserved non-reserved non-reserved
|
||||
ROLLBACK non-reserved reserved reserved reserved
|
||||
ROLLUP reserved reserved
|
||||
ROUTINE non-reserved non-reserved
|
||||
ROUTINE_CATALOG non-reserved non-reserved
|
||||
ROUTINE_NAME non-reserved non-reserved
|
||||
ROUTINE_SCHEMA non-reserved non-reserved
|
||||
ROW non-reserved (cannot be function or type) reserved reserved
|
||||
ROWS non-reserved reserved reserved reserved
|
||||
ROW_COUNT non-reserved non-reserved non-reserved
|
||||
ROW_NUMBER reserved reserved
|
||||
RULE non-reserved
|
||||
SAVEPOINT non-reserved reserved reserved
|
||||
SCALE non-reserved non-reserved non-reserved
|
||||
SCHEMA non-reserved non-reserved non-reserved reserved
|
||||
SCHEMA_NAME non-reserved non-reserved non-reserved
|
||||
SCOPE reserved reserved
|
||||
SCOPE_CATALOG non-reserved non-reserved
|
||||
SCOPE_NAME non-reserved non-reserved
|
||||
SCOPE_SCHEMA non-reserved non-reserved
|
||||
SCROLL non-reserved reserved reserved reserved
|
||||
SEARCH non-reserved reserved reserved
|
||||
SECOND non-reserved reserved reserved reserved
|
||||
SECTION non-reserved non-reserved reserved
|
||||
SECURITY non-reserved non-reserved non-reserved
|
||||
SELECT reserved reserved reserved reserved
|
||||
SELECTIVE non-reserved non-reserved
|
||||
SELF non-reserved non-reserved
|
||||
SENSITIVE reserved reserved
|
||||
SEQUENCE non-reserved non-reserved non-reserved
|
||||
SEQUENCES non-reserved
|
||||
SERIALIZABLE non-reserved non-reserved non-reserved non-reserved
|
||||
SERVER non-reserved non-reserved non-reserved
|
||||
SERVER_NAME non-reserved non-reserved non-reserved
|
||||
SESSION non-reserved non-reserved non-reserved reserved
|
||||
SESSION_USER reserved reserved reserved reserved
|
||||
SET non-reserved reserved reserved reserved
|
||||
SETOF non-reserved (cannot be function or type)
|
||||
SETS non-reserved non-reserved
|
||||
SHARE non-reserved
|
||||
SHOW non-reserved
|
||||
SIMILAR reserved (can be function or type) reserved reserved
|
||||
SIMPLE non-reserved non-reserved non-reserved
|
||||
SIZE non-reserved non-reserved reserved
|
||||
SMALLINT non-reserved (cannot be function or type) reserved reserved reserved
|
||||
SNAPSHOT non-reserved
|
||||
SOME reserved reserved reserved reserved
|
||||
SOURCE non-reserved non-reserved
|
||||
SPACE non-reserved non-reserved reserved
|
||||
SPECIFIC reserved reserved
|
||||
SPECIFICTYPE reserved reserved
|
||||
SPECIFIC_NAME non-reserved non-reserved
|
||||
SQL reserved reserved reserved
|
||||
SQLCODE reserved
|
||||
SQLERROR reserved
|
||||
SQLEXCEPTION reserved reserved
|
||||
SQLSTATE reserved reserved reserved
|
||||
SQLWARNING reserved reserved
|
||||
SQRT reserved reserved
|
||||
STABLE non-reserved
|
||||
STANDALONE non-reserved non-reserved non-reserved
|
||||
START non-reserved reserved reserved
|
||||
STATE non-reserved non-reserved
|
||||
STATEMENT non-reserved non-reserved non-reserved
|
||||
STATIC reserved reserved
|
||||
STATISTICS non-reserved
|
||||
STDDEV_POP reserved reserved
|
||||
STDDEV_SAMP reserved reserved
|
||||
STDIN non-reserved
|
||||
STDOUT non-reserved
|
||||
STORAGE non-reserved
|
||||
STRICT non-reserved
|
||||
STRIP non-reserved non-reserved non-reserved
|
||||
STRUCTURE non-reserved non-reserved
|
||||
STYLE non-reserved non-reserved
|
||||
SUBCLASS_ORIGIN non-reserved non-reserved non-reserved
|
||||
SUBMULTISET reserved reserved
|
||||
SUBSTRING non-reserved (cannot be function or type) reserved reserved reserved
|
||||
SUBSTRING_REGEX reserved reserved
|
||||
SUCCEEDS reserved
|
||||
SUM reserved reserved reserved
|
||||
SYMMETRIC reserved reserved reserved
|
||||
SYSID non-reserved
|
||||
SYSTEM non-reserved reserved reserved
|
||||
SYSTEM_TIME reserved
|
||||
SYSTEM_USER reserved reserved reserved
|
||||
T non-reserved non-reserved
|
||||
TABLE reserved reserved reserved reserved
|
||||
TABLES non-reserved
|
||||
TABLESAMPLE reserved reserved
|
||||
TABLESPACE non-reserved
|
||||
TABLE_NAME non-reserved non-reserved non-reserved
|
||||
TEMP non-reserved
|
||||
TEMPLATE non-reserved
|
||||
TEMPORARY non-reserved non-reserved non-reserved reserved
|
||||
TEXT non-reserved
|
||||
THEN reserved reserved reserved reserved
|
||||
TIES non-reserved non-reserved
|
||||
TIME non-reserved (cannot be function or type) reserved reserved reserved
|
||||
TIMESTAMP non-reserved (cannot be function or type) reserved reserved reserved
|
||||
TIMEZONE_HOUR reserved reserved reserved
|
||||
TIMEZONE_MINUTE reserved reserved reserved
|
||||
TO reserved reserved reserved reserved
|
||||
TOKEN non-reserved non-reserved
|
||||
TOP_LEVEL_COUNT non-reserved non-reserved
|
||||
TRAILING reserved reserved reserved reserved
|
||||
TRANSACTION non-reserved non-reserved non-reserved reserved
|
||||
TRANSACTIONS_COMMITTED non-reserved non-reserved
|
||||
TRANSACTIONS_ROLLED_BACK non-reserved non-reserved
|
||||
TRANSACTION_ACTIVE non-reserved non-reserved
|
||||
TRANSFORM non-reserved non-reserved
|
||||
TRANSFORMS non-reserved non-reserved
|
||||
TRANSLATE reserved reserved reserved
|
||||
TRANSLATE_REGEX reserved reserved
|
||||
TRANSLATION reserved reserved reserved
|
||||
TREAT non-reserved (cannot be function or type) reserved reserved
|
||||
TRIGGER non-reserved reserved reserved
|
||||
TRIGGER_CATALOG non-reserved non-reserved
|
||||
TRIGGER_NAME non-reserved non-reserved
|
||||
TRIGGER_SCHEMA non-reserved non-reserved
|
||||
TRIM non-reserved (cannot be function or type) reserved reserved reserved
|
||||
TRIM_ARRAY reserved reserved
|
||||
TRUE reserved reserved reserved reserved
|
||||
TRUNCATE non-reserved reserved reserved
|
||||
TRUSTED non-reserved
|
||||
TYPE non-reserved non-reserved non-reserved non-reserved
|
||||
TYPES non-reserved
|
||||
UESCAPE reserved reserved
|
||||
UNBOUNDED non-reserved non-reserved non-reserved
|
||||
UNCOMMITTED non-reserved non-reserved non-reserved non-reserved
|
||||
UNDER non-reserved non-reserved
|
||||
UNENCRYPTED non-reserved
|
||||
UNION reserved reserved reserved reserved
|
||||
UNIQUE reserved reserved reserved reserved
|
||||
UNKNOWN non-reserved reserved reserved reserved
|
||||
UNLINK non-reserved non-reserved
|
||||
UNLISTEN non-reserved
|
||||
UNLOGGED non-reserved
|
||||
UNNAMED non-reserved non-reserved non-reserved
|
||||
UNNEST reserved reserved
|
||||
UNTIL non-reserved
|
||||
UNTYPED non-reserved non-reserved
|
||||
UPDATE non-reserved reserved reserved reserved
|
||||
UPPER reserved reserved reserved
|
||||
URI non-reserved non-reserved
|
||||
USAGE non-reserved non-reserved reserved
|
||||
USER reserved reserved reserved reserved
|
||||
USER_DEFINED_TYPE_CATALOG non-reserved non-reserved
|
||||
USER_DEFINED_TYPE_CODE non-reserved non-reserved
|
||||
USER_DEFINED_TYPE_NAME non-reserved non-reserved
|
||||
USER_DEFINED_TYPE_SCHEMA non-reserved non-reserved
|
||||
USING reserved reserved reserved reserved
|
||||
VACUUM non-reserved
|
||||
VALID non-reserved non-reserved non-reserved
|
||||
VALIDATE non-reserved
|
||||
VALIDATOR non-reserved
|
||||
VALUE non-reserved reserved reserved reserved
|
||||
VALUES non-reserved (cannot be function or type) reserved reserved reserved
|
||||
VALUE_OF reserved
|
||||
VARBINARY reserved reserved
|
||||
VARCHAR non-reserved (cannot be function or type) reserved reserved reserved
|
||||
VARIADIC reserved
|
||||
VARYING non-reserved reserved reserved reserved
|
||||
VAR_POP reserved reserved
|
||||
VAR_SAMP reserved reserved
|
||||
VERBOSE reserved (can be function or type)
|
||||
VERSION non-reserved non-reserved non-reserved
|
||||
VERSIONING reserved
|
||||
VIEW non-reserved non-reserved non-reserved reserved
|
||||
VOLATILE non-reserved
|
||||
WHEN reserved reserved reserved reserved
|
||||
WHENEVER reserved reserved reserved
|
||||
WHERE reserved reserved reserved reserved
|
||||
WHITESPACE non-reserved non-reserved non-reserved
|
||||
WIDTH_BUCKET reserved reserved
|
||||
WINDOW reserved reserved reserved
|
||||
WITH reserved reserved reserved reserved
|
||||
WITHIN reserved reserved
|
||||
WITHOUT non-reserved reserved reserved
|
||||
WORK non-reserved non-reserved non-reserved reserved
|
||||
WRAPPER non-reserved non-reserved non-reserved
|
||||
WRITE non-reserved non-reserved non-reserved reserved
|
||||
XML non-reserved reserved reserved
|
||||
XMLAGG reserved reserved
|
||||
XMLATTRIBUTES non-reserved (cannot be function or type) reserved reserved
|
||||
XMLBINARY reserved reserved
|
||||
XMLCAST reserved reserved
|
||||
XMLCOMMENT reserved reserved
|
||||
XMLCONCAT non-reserved (cannot be function or type) reserved reserved
|
||||
XMLDECLARATION non-reserved non-reserved
|
||||
XMLDOCUMENT reserved reserved
|
||||
XMLELEMENT non-reserved (cannot be function or type) reserved reserved
|
||||
XMLEXISTS non-reserved (cannot be function or type) reserved reserved
|
||||
XMLFOREST non-reserved (cannot be function or type) reserved reserved
|
||||
XMLITERATE reserved reserved
|
||||
XMLNAMESPACES reserved reserved
|
||||
XMLPARSE non-reserved (cannot be function or type) reserved reserved
|
||||
XMLPI non-reserved (cannot be function or type) reserved reserved
|
||||
XMLQUERY reserved reserved
|
||||
XMLROOT non-reserved (cannot be function or type)
|
||||
XMLSCHEMA non-reserved non-reserved
|
||||
XMLSERIALIZE non-reserved (cannot be function or type) reserved reserved
|
||||
XMLTABLE reserved reserved
|
||||
XMLTEXT reserved reserved
|
||||
XMLVALIDATE reserved reserved
|
||||
YEAR non-reserved reserved reserved reserved
|
||||
YES non-reserved non-reserved non-reserved
|
||||
ZONE non-reserved non-reserved non-reserved reserved
|
1091
vendor/github.com/go-xorm/xorm/postgres_dialect.go
generated
vendored
Normal file
1091
vendor/github.com/go-xorm/xorm/postgres_dialect.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
119
vendor/github.com/go-xorm/xorm/pq_driver.go
generated
vendored
Normal file
119
vendor/github.com/go-xorm/xorm/pq_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
type pqDriver struct {
|
||||
}
|
||||
|
||||
type values map[string]string
|
||||
|
||||
func (vs values) Set(k, v string) {
|
||||
vs[k] = v
|
||||
}
|
||||
|
||||
func (vs values) Get(k string) (v string) {
|
||||
return vs[k]
|
||||
}
|
||||
|
||||
func errorf(s string, args ...interface{}) {
|
||||
panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)))
|
||||
}
|
||||
|
||||
func parseURL(connstr string) (string, error) {
|
||||
u, err := url.Parse(connstr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if u.Scheme != "postgresql" && u.Scheme != "postgres" {
|
||||
return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
|
||||
}
|
||||
|
||||
var kvs []string
|
||||
escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`)
|
||||
accrue := func(k, v string) {
|
||||
if v != "" {
|
||||
kvs = append(kvs, k+"="+escaper.Replace(v))
|
||||
}
|
||||
}
|
||||
|
||||
if u.User != nil {
|
||||
v := u.User.Username()
|
||||
accrue("user", v)
|
||||
|
||||
v, _ = u.User.Password()
|
||||
accrue("password", v)
|
||||
}
|
||||
|
||||
i := strings.Index(u.Host, ":")
|
||||
if i < 0 {
|
||||
accrue("host", u.Host)
|
||||
} else {
|
||||
accrue("host", u.Host[:i])
|
||||
accrue("port", u.Host[i+1:])
|
||||
}
|
||||
|
||||
if u.Path != "" {
|
||||
accrue("dbname", u.Path[1:])
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
for k := range q {
|
||||
accrue(k, q.Get(k))
|
||||
}
|
||||
|
||||
sort.Strings(kvs) // Makes testing easier (not a performance concern)
|
||||
return strings.Join(kvs, " "), nil
|
||||
}
|
||||
|
||||
func parseOpts(name string, o values) {
|
||||
if len(name) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
name = strings.TrimSpace(name)
|
||||
|
||||
ps := strings.Split(name, " ")
|
||||
for _, p := range ps {
|
||||
kv := strings.Split(p, "=")
|
||||
if len(kv) < 2 {
|
||||
errorf("invalid option: %q", p)
|
||||
}
|
||||
o.Set(kv[0], kv[1])
|
||||
}
|
||||
}
|
||||
|
||||
func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.POSTGRES}
|
||||
o := make(values)
|
||||
var err error
|
||||
if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") {
|
||||
dataSourceName, err = parseURL(dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
parseOpts(dataSourceName, o)
|
||||
|
||||
db.DbName = o.Get("dbname")
|
||||
if db.DbName == "" {
|
||||
return nil, errors.New("dbname is empty")
|
||||
}
|
||||
/*db.Schema = o.Get("schema")
|
||||
if len(db.Schema) == 0 {
|
||||
db.Schema = "public"
|
||||
}*/
|
||||
return db, nil
|
||||
}
|
50
vendor/github.com/go-xorm/xorm/processors.go
generated
vendored
Normal file
50
vendor/github.com/go-xorm/xorm/processors.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
// Executed before an object is initially persisted to the database
|
||||
type BeforeInsertProcessor interface {
|
||||
BeforeInsert()
|
||||
}
|
||||
|
||||
// Executed before an object is updated
|
||||
type BeforeUpdateProcessor interface {
|
||||
BeforeUpdate()
|
||||
}
|
||||
|
||||
// Executed before an object is deleted
|
||||
type BeforeDeleteProcessor interface {
|
||||
BeforeDelete()
|
||||
}
|
||||
|
||||
type BeforeSetProcessor interface {
|
||||
BeforeSet(string, Cell)
|
||||
}
|
||||
|
||||
type AfterSetProcessor interface {
|
||||
AfterSet(string, Cell)
|
||||
}
|
||||
|
||||
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
|
||||
//// Executed before an object is validated
|
||||
//type BeforeValidateProcessor interface {
|
||||
// BeforeValidate()
|
||||
//}
|
||||
// --
|
||||
|
||||
// Executed after an object is persisted to the database
|
||||
type AfterInsertProcessor interface {
|
||||
AfterInsert()
|
||||
}
|
||||
|
||||
// Executed after an object has been updated
|
||||
type AfterUpdateProcessor interface {
|
||||
AfterUpdate()
|
||||
}
|
||||
|
||||
// Executed after an object has been deleted
|
||||
type AfterDeleteProcessor interface {
|
||||
AfterDelete()
|
||||
}
|
146
vendor/github.com/go-xorm/xorm/rows.go
generated
vendored
Normal file
146
vendor/github.com/go-xorm/xorm/rows.go
generated
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// Rows rows wrapper a rows to
|
||||
type Rows struct {
|
||||
NoTypeCheck bool
|
||||
|
||||
session *Session
|
||||
stmt *core.Stmt
|
||||
rows *core.Rows
|
||||
fields []string
|
||||
fieldsCount int
|
||||
beanType reflect.Type
|
||||
lastError error
|
||||
}
|
||||
|
||||
func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||
rows := new(Rows)
|
||||
rows.session = session
|
||||
rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type()
|
||||
|
||||
defer rows.session.resetStatement()
|
||||
|
||||
var sqlStr string
|
||||
var args []interface{}
|
||||
|
||||
rows.session.Statement.setRefValue(rValue(bean))
|
||||
if len(session.Statement.TableName()) <= 0 {
|
||||
return nil, ErrTableNotFound
|
||||
}
|
||||
|
||||
if rows.session.Statement.RawSQL == "" {
|
||||
sqlStr, args = rows.session.Statement.genGetSQL(bean)
|
||||
} else {
|
||||
sqlStr = rows.session.Statement.RawSQL
|
||||
args = rows.session.Statement.RawParams
|
||||
}
|
||||
|
||||
for _, filter := range rows.session.Engine.dialect.Filters() {
|
||||
sqlStr = filter.Do(sqlStr, session.Engine.dialect, rows.session.Statement.RefTable)
|
||||
}
|
||||
|
||||
rows.session.saveLastSQL(sqlStr, args...)
|
||||
var err error
|
||||
if rows.session.prepareStmt {
|
||||
rows.stmt, err = rows.session.DB().Prepare(sqlStr)
|
||||
if err != nil {
|
||||
rows.lastError = err
|
||||
rows.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows.rows, err = rows.stmt.Query(args...)
|
||||
if err != nil {
|
||||
rows.lastError = err
|
||||
rows.Close()
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
rows.rows, err = rows.session.DB().Query(sqlStr, args...)
|
||||
if err != nil {
|
||||
rows.lastError = err
|
||||
rows.Close()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
rows.fields, err = rows.rows.Columns()
|
||||
if err != nil {
|
||||
rows.lastError = err
|
||||
rows.Close()
|
||||
return nil, err
|
||||
}
|
||||
rows.fieldsCount = len(rows.fields)
|
||||
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// Next move cursor to next record, return false if end has reached
|
||||
func (rows *Rows) Next() bool {
|
||||
if rows.lastError == nil && rows.rows != nil {
|
||||
hasNext := rows.rows.Next()
|
||||
if !hasNext {
|
||||
rows.lastError = sql.ErrNoRows
|
||||
}
|
||||
return hasNext
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Err returns the error, if any, that was encountered during iteration. Err may be called after an explicit or implicit Close.
|
||||
func (rows *Rows) Err() error {
|
||||
return rows.lastError
|
||||
}
|
||||
|
||||
// Scan row record to bean properties
|
||||
func (rows *Rows) Scan(bean interface{}) error {
|
||||
if rows.lastError != nil {
|
||||
return rows.lastError
|
||||
}
|
||||
|
||||
if !rows.NoTypeCheck && reflect.Indirect(reflect.ValueOf(bean)).Type() != rows.beanType {
|
||||
return fmt.Errorf("scan arg is incompatible type to [%v]", rows.beanType)
|
||||
}
|
||||
|
||||
return rows.session.row2Bean(rows.rows, rows.fields, rows.fieldsCount, bean)
|
||||
}
|
||||
|
||||
// Close session if session.IsAutoClose is true, and claimed any opened resources
|
||||
func (rows *Rows) Close() error {
|
||||
if rows.session.IsAutoClose {
|
||||
defer rows.session.Close()
|
||||
}
|
||||
|
||||
if rows.lastError == nil {
|
||||
if rows.rows != nil {
|
||||
rows.lastError = rows.rows.Close()
|
||||
if rows.lastError != nil {
|
||||
defer rows.stmt.Close()
|
||||
return rows.lastError
|
||||
}
|
||||
}
|
||||
if rows.stmt != nil {
|
||||
rows.lastError = rows.stmt.Close()
|
||||
}
|
||||
} else {
|
||||
if rows.stmt != nil {
|
||||
defer rows.stmt.Close()
|
||||
}
|
||||
if rows.rows != nil {
|
||||
defer rows.rows.Close()
|
||||
}
|
||||
}
|
||||
return rows.lastError
|
||||
}
|
4144
vendor/github.com/go-xorm/xorm/session.go
generated
vendored
Normal file
4144
vendor/github.com/go-xorm/xorm/session.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
435
vendor/github.com/go-xorm/xorm/sqlite3_dialect.go
generated
vendored
Normal file
435
vendor/github.com/go-xorm/xorm/sqlite3_dialect.go
generated
vendored
Normal file
|
@ -0,0 +1,435 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// func init() {
|
||||
// RegisterDialect("sqlite3", &sqlite3{})
|
||||
// }
|
||||
|
||||
var (
|
||||
sqlite3ReservedWords = map[string]bool{
|
||||
"ABORT": true,
|
||||
"ACTION": true,
|
||||
"ADD": true,
|
||||
"AFTER": true,
|
||||
"ALL": true,
|
||||
"ALTER": true,
|
||||
"ANALYZE": true,
|
||||
"AND": true,
|
||||
"AS": true,
|
||||
"ASC": true,
|
||||
"ATTACH": true,
|
||||
"AUTOINCREMENT": true,
|
||||
"BEFORE": true,
|
||||
"BEGIN": true,
|
||||
"BETWEEN": true,
|
||||
"BY": true,
|
||||
"CASCADE": true,
|
||||
"CASE": true,
|
||||
"CAST": true,
|
||||
"CHECK": true,
|
||||
"COLLATE": true,
|
||||
"COLUMN": true,
|
||||
"COMMIT": true,
|
||||
"CONFLICT": true,
|
||||
"CONSTRAINT": true,
|
||||
"CREATE": true,
|
||||
"CROSS": true,
|
||||
"CURRENT_DATE": true,
|
||||
"CURRENT_TIME": true,
|
||||
"CURRENT_TIMESTAMP": true,
|
||||
"DATABASE": true,
|
||||
"DEFAULT": true,
|
||||
"DEFERRABLE": true,
|
||||
"DEFERRED": true,
|
||||
"DELETE": true,
|
||||
"DESC": true,
|
||||
"DETACH": true,
|
||||
"DISTINCT": true,
|
||||
"DROP": true,
|
||||
"EACH": true,
|
||||
"ELSE": true,
|
||||
"END": true,
|
||||
"ESCAPE": true,
|
||||
"EXCEPT": true,
|
||||
"EXCLUSIVE": true,
|
||||
"EXISTS": true,
|
||||
"EXPLAIN": true,
|
||||
"FAIL": true,
|
||||
"FOR": true,
|
||||
"FOREIGN": true,
|
||||
"FROM": true,
|
||||
"FULL": true,
|
||||
"GLOB": true,
|
||||
"GROUP": true,
|
||||
"HAVING": true,
|
||||
"IF": true,
|
||||
"IGNORE": true,
|
||||
"IMMEDIATE": true,
|
||||
"IN": true,
|
||||
"INDEX": true,
|
||||
"INDEXED": true,
|
||||
"INITIALLY": true,
|
||||
"INNER": true,
|
||||
"INSERT": true,
|
||||
"INSTEAD": true,
|
||||
"INTERSECT": true,
|
||||
"INTO": true,
|
||||
"IS": true,
|
||||
"ISNULL": true,
|
||||
"JOIN": true,
|
||||
"KEY": true,
|
||||
"LEFT": true,
|
||||
"LIKE": true,
|
||||
"LIMIT": true,
|
||||
"MATCH": true,
|
||||
"NATURAL": true,
|
||||
"NO": true,
|
||||
"NOT": true,
|
||||
"NOTNULL": true,
|
||||
"NULL": true,
|
||||
"OF": true,
|
||||
"OFFSET": true,
|
||||
"ON": true,
|
||||
"OR": true,
|
||||
"ORDER": true,
|
||||
"OUTER": true,
|
||||
"PLAN": true,
|
||||
"PRAGMA": true,
|
||||
"PRIMARY": true,
|
||||
"QUERY": true,
|
||||
"RAISE": true,
|
||||
"RECURSIVE": true,
|
||||
"REFERENCES": true,
|
||||
"REGEXP": true,
|
||||
"REINDEX": true,
|
||||
"RELEASE": true,
|
||||
"RENAME": true,
|
||||
"REPLACE": true,
|
||||
"RESTRICT": true,
|
||||
"RIGHT": true,
|
||||
"ROLLBACK": true,
|
||||
"ROW": true,
|
||||
"SAVEPOINT": true,
|
||||
"SELECT": true,
|
||||
"SET": true,
|
||||
"TABLE": true,
|
||||
"TEMP": true,
|
||||
"TEMPORARY": true,
|
||||
"THEN": true,
|
||||
"TO": true,
|
||||
"TRANSACTI": true,
|
||||
"TRIGGER": true,
|
||||
"UNION": true,
|
||||
"UNIQUE": true,
|
||||
"UPDATE": true,
|
||||
"USING": true,
|
||||
"VACUUM": true,
|
||||
"VALUES": true,
|
||||
"VIEW": true,
|
||||
"VIRTUAL": true,
|
||||
"WHEN": true,
|
||||
"WHERE": true,
|
||||
"WITH": true,
|
||||
"WITHOUT": true,
|
||||
}
|
||||
)
|
||||
|
||||
type sqlite3 struct {
|
||||
core.Base
|
||||
}
|
||||
|
||||
func (db *sqlite3) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName string) error {
|
||||
return db.Base.Init(d, db, uri, drivername, dataSourceName)
|
||||
}
|
||||
|
||||
func (db *sqlite3) SqlType(c *core.Column) string {
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bool:
|
||||
if c.Default == "true" {
|
||||
c.Default = "1"
|
||||
} else if c.Default == "false" {
|
||||
c.Default = "0"
|
||||
}
|
||||
return core.Integer
|
||||
case core.Date, core.DateTime, core.TimeStamp, core.Time:
|
||||
return core.DateTime
|
||||
case core.TimeStampz:
|
||||
return core.Text
|
||||
case core.Char, core.Varchar, core.NVarchar, core.TinyText,
|
||||
core.Text, core.MediumText, core.LongText, core.Json:
|
||||
return core.Text
|
||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt:
|
||||
return core.Integer
|
||||
case core.Float, core.Double, core.Real:
|
||||
return core.Real
|
||||
case core.Decimal, core.Numeric:
|
||||
return core.Numeric
|
||||
case core.TinyBlob, core.Blob, core.MediumBlob, core.LongBlob, core.Bytea, core.Binary, core.VarBinary:
|
||||
return core.Blob
|
||||
case core.Serial, core.BigSerial:
|
||||
c.IsPrimaryKey = true
|
||||
c.IsAutoIncrement = true
|
||||
c.Nullable = false
|
||||
return core.Integer
|
||||
default:
|
||||
return t
|
||||
}
|
||||
}
|
||||
|
||||
func (db *sqlite3) FormatBytes(bs []byte) string {
|
||||
return fmt.Sprintf("X'%x'", bs)
|
||||
}
|
||||
|
||||
func (db *sqlite3) SupportInsertMany() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *sqlite3) IsReserved(name string) bool {
|
||||
_, ok := sqlite3ReservedWords[name]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (db *sqlite3) Quote(name string) string {
|
||||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *sqlite3) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *sqlite3) AutoIncrStr() string {
|
||||
return "AUTOINCREMENT"
|
||||
}
|
||||
|
||||
func (db *sqlite3) SupportEngine() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *sqlite3) SupportCharset() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *sqlite3) IndexOnTable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *sqlite3) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
||||
args := []interface{}{idxName}
|
||||
return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args
|
||||
}
|
||||
|
||||
func (db *sqlite3) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName}
|
||||
return "SELECT name FROM sqlite_master WHERE type='table' and name = ?", args
|
||||
}
|
||||
|
||||
func (db *sqlite3) DropIndexSql(tableName string, index *core.Index) string {
|
||||
quote := db.Quote
|
||||
//var unique string
|
||||
var idxName string = index.Name
|
||||
if !strings.HasPrefix(idxName, "UQE_") &&
|
||||
!strings.HasPrefix(idxName, "IDX_") {
|
||||
if index.Type == core.UniqueType {
|
||||
idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||
} else {
|
||||
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
||||
}
|
||||
|
||||
func (db *sqlite3) ForUpdateSql(query string) string {
|
||||
return query
|
||||
}
|
||||
|
||||
/*func (db *sqlite3) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName}
|
||||
sql := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))"
|
||||
return sql, args
|
||||
}*/
|
||||
|
||||
func (db *sqlite3) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
args := []interface{}{tableName}
|
||||
query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))"
|
||||
db.LogSQL(query, args)
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
args := []interface{}{tableName}
|
||||
s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?"
|
||||
db.LogSQL(s, args)
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var name string
|
||||
for rows.Next() {
|
||||
err = rows.Scan(&name)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
return nil, nil, errors.New("no table named " + tableName)
|
||||
}
|
||||
|
||||
nStart := strings.Index(name, "(")
|
||||
nEnd := strings.LastIndex(name, ")")
|
||||
reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`)
|
||||
colCreates := reg.FindAllString(name[nStart+1:nEnd], -1)
|
||||
cols := make(map[string]*core.Column)
|
||||
colSeq := make([]string, 0)
|
||||
for _, colStr := range colCreates {
|
||||
reg = regexp.MustCompile(`,\s`)
|
||||
colStr = reg.ReplaceAllString(colStr, ",")
|
||||
fields := strings.Fields(strings.TrimSpace(colStr))
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]int)
|
||||
col.Nullable = true
|
||||
col.DefaultIsEmpty = true
|
||||
for idx, field := range fields {
|
||||
if idx == 0 {
|
||||
col.Name = strings.Trim(field, "`[] ")
|
||||
continue
|
||||
} else if idx == 1 {
|
||||
col.SQLType = core.SQLType{field, 0, 0}
|
||||
}
|
||||
switch field {
|
||||
case "PRIMARY":
|
||||
col.IsPrimaryKey = true
|
||||
case "AUTOINCREMENT":
|
||||
col.IsAutoIncrement = true
|
||||
case "NULL":
|
||||
if fields[idx-1] == "NOT" {
|
||||
col.Nullable = false
|
||||
} else {
|
||||
col.Nullable = true
|
||||
}
|
||||
case "DEFAULT":
|
||||
col.Default = fields[idx+1]
|
||||
col.DefaultIsEmpty = false
|
||||
}
|
||||
}
|
||||
if !col.SQLType.IsNumeric() && !col.DefaultIsEmpty {
|
||||
col.Default = "'" + col.Default + "'"
|
||||
}
|
||||
cols[col.Name] = col
|
||||
colSeq = append(colSeq, col.Name)
|
||||
}
|
||||
return colSeq, cols, nil
|
||||
}
|
||||
|
||||
func (db *sqlite3) GetTables() ([]*core.Table, error) {
|
||||
args := []interface{}{}
|
||||
s := "SELECT name FROM sqlite_master WHERE type='table'"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
tables := make([]*core.Table, 0)
|
||||
for rows.Next() {
|
||||
table := core.NewEmptyTable()
|
||||
err = rows.Scan(&table.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if table.Name == "sqlite_sequence" {
|
||||
continue
|
||||
}
|
||||
tables = append(tables, table)
|
||||
}
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
args := []interface{}{tableName}
|
||||
s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?"
|
||||
db.LogSQL(s, args)
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
indexes := make(map[string]*core.Index, 0)
|
||||
for rows.Next() {
|
||||
var tmpSql sql.NullString
|
||||
err = rows.Scan(&tmpSql)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !tmpSql.Valid {
|
||||
continue
|
||||
}
|
||||
sql := tmpSql.String
|
||||
|
||||
index := new(core.Index)
|
||||
nNStart := strings.Index(sql, "INDEX")
|
||||
nNEnd := strings.Index(sql, "ON")
|
||||
if nNStart == -1 || nNEnd == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
indexName := strings.Trim(sql[nNStart+6:nNEnd], "` []")
|
||||
if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
|
||||
index.Name = indexName[5+len(tableName) : len(indexName)]
|
||||
} else {
|
||||
index.Name = indexName
|
||||
}
|
||||
|
||||
if strings.HasPrefix(sql, "CREATE UNIQUE INDEX") {
|
||||
index.Type = core.UniqueType
|
||||
} else {
|
||||
index.Type = core.IndexType
|
||||
}
|
||||
|
||||
nStart := strings.Index(sql, "(")
|
||||
nEnd := strings.Index(sql, ")")
|
||||
colIndexes := strings.Split(sql[nStart+1:nEnd], ",")
|
||||
|
||||
index.Cols = make([]string, 0)
|
||||
for _, col := range colIndexes {
|
||||
index.Cols = append(index.Cols, strings.Trim(col, "` []"))
|
||||
}
|
||||
indexes[index.Name] = index
|
||||
}
|
||||
|
||||
return indexes, nil
|
||||
}
|
||||
|
||||
func (db *sqlite3) Filters() []core.Filter {
|
||||
return []core.Filter{&core.IdFilter{}}
|
||||
}
|
20
vendor/github.com/go-xorm/xorm/sqlite3_driver.go
generated
vendored
Normal file
20
vendor/github.com/go-xorm/xorm/sqlite3_driver.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// func init() {
|
||||
// core.RegisterDriver("sqlite3", &sqlite3Driver{})
|
||||
// }
|
||||
|
||||
type sqlite3Driver struct {
|
||||
}
|
||||
|
||||
func (p *sqlite3Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
return &core.Uri{DbType: core.SQLITE, DbName: dataSourceName}, nil
|
||||
}
|
1359
vendor/github.com/go-xorm/xorm/statement.go
generated
vendored
Normal file
1359
vendor/github.com/go-xorm/xorm/statement.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
77
vendor/github.com/go-xorm/xorm/syslogger.go
generated
vendored
Normal file
77
vendor/github.com/go-xorm/xorm/syslogger.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/syslog"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var _ core.ILogger = &SyslogLogger{}
|
||||
|
||||
// SyslogLogger will be depricated
|
||||
type SyslogLogger struct {
|
||||
w *syslog.Writer
|
||||
showSQL bool
|
||||
}
|
||||
|
||||
func NewSyslogLogger(w *syslog.Writer) *SyslogLogger {
|
||||
return &SyslogLogger{w: w}
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Debug(v ...interface{}) {
|
||||
s.w.Debug(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Debugf(format string, v ...interface{}) {
|
||||
s.w.Debug(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Error(v ...interface{}) {
|
||||
s.w.Err(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Errorf(format string, v ...interface{}) {
|
||||
s.w.Err(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Info(v ...interface{}) {
|
||||
s.w.Info(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Infof(format string, v ...interface{}) {
|
||||
s.w.Info(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Warn(v ...interface{}) {
|
||||
s.w.Warning(fmt.Sprint(v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Warnf(format string, v ...interface{}) {
|
||||
s.w.Warning(fmt.Sprintf(format, v...))
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) Level() core.LogLevel {
|
||||
return core.LOG_UNKNOWN
|
||||
}
|
||||
|
||||
// SetLevel always return error, as current log/syslog package doesn't allow to set priority level after syslog.Writer created
|
||||
func (s *SyslogLogger) SetLevel(l core.LogLevel) {}
|
||||
|
||||
func (s *SyslogLogger) ShowSQL(show ...bool) {
|
||||
if len(show) == 0 {
|
||||
s.showSQL = true
|
||||
return
|
||||
}
|
||||
s.showSQL = show[0]
|
||||
}
|
||||
|
||||
func (s *SyslogLogger) IsShowSQL() bool {
|
||||
return s.showSQL
|
||||
}
|
12
vendor/github.com/go-xorm/xorm/types.go
generated
vendored
Normal file
12
vendor/github.com/go-xorm/xorm/types.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
package xorm
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
var (
|
||||
ptrPkType = reflect.TypeOf(&core.PK{})
|
||||
pkType = reflect.TypeOf(core.PK{})
|
||||
)
|
104
vendor/github.com/go-xorm/xorm/xorm.go
generated
vendored
Normal file
104
vendor/github.com/go-xorm/xorm/xorm.go
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
const (
|
||||
// Version show the xorm's version
|
||||
Version string = "0.6.0.1022"
|
||||
)
|
||||
|
||||
func regDrvsNDialects() bool {
|
||||
providedDrvsNDialects := map[string]struct {
|
||||
dbType core.DbType
|
||||
getDriver func() core.Driver
|
||||
getDialect func() core.Dialect
|
||||
}{
|
||||
"mssql": {"mssql", func() core.Driver { return &odbcDriver{} }, func() core.Dialect { return &mssql{} }},
|
||||
"odbc": {"mssql", func() core.Driver { return &odbcDriver{} }, func() core.Dialect { return &mssql{} }}, // !nashtsai! TODO change this when supporting MS Access
|
||||
"mysql": {"mysql", func() core.Driver { return &mysqlDriver{} }, func() core.Dialect { return &mysql{} }},
|
||||
"mymysql": {"mysql", func() core.Driver { return &mymysqlDriver{} }, func() core.Dialect { return &mysql{} }},
|
||||
"postgres": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }},
|
||||
"pgx": {"postgres", func() core.Driver { return &pqDriver{} }, func() core.Dialect { return &postgres{} }},
|
||||
"sqlite3": {"sqlite3", func() core.Driver { return &sqlite3Driver{} }, func() core.Dialect { return &sqlite3{} }},
|
||||
"oci8": {"oracle", func() core.Driver { return &oci8Driver{} }, func() core.Dialect { return &oracle{} }},
|
||||
"goracle": {"oracle", func() core.Driver { return &goracleDriver{} }, func() core.Dialect { return &oracle{} }},
|
||||
}
|
||||
|
||||
for driverName, v := range providedDrvsNDialects {
|
||||
if driver := core.QueryDriver(driverName); driver == nil {
|
||||
core.RegisterDriver(driverName, v.getDriver())
|
||||
core.RegisterDialect(v.dbType, v.getDialect)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func close(engine *Engine) {
|
||||
engine.Close()
|
||||
}
|
||||
|
||||
// NewEngine new a db manager according to the parameter. Currently support four
|
||||
// drivers
|
||||
func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||
regDrvsNDialects()
|
||||
driver := core.QueryDriver(driverName)
|
||||
if driver == nil {
|
||||
return nil, fmt.Errorf("Unsupported driver name: %v", driverName)
|
||||
}
|
||||
|
||||
uri, err := driver.Parse(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dialect := core.QueryDialect(uri.DbType)
|
||||
if dialect == nil {
|
||||
return nil, fmt.Errorf("Unsupported dialect type: %v", uri.DbType)
|
||||
}
|
||||
|
||||
db, err := core.Open(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = dialect.Init(db, uri, driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
engine := &Engine{
|
||||
db: db,
|
||||
dialect: dialect,
|
||||
Tables: make(map[reflect.Type]*core.Table),
|
||||
mutex: &sync.RWMutex{},
|
||||
TagIdentifier: "xorm",
|
||||
TZLocation: time.Local,
|
||||
}
|
||||
|
||||
logger := NewSimpleLogger(os.Stdout)
|
||||
logger.SetLevel(core.LOG_INFO)
|
||||
engine.SetLogger(logger)
|
||||
engine.SetMapper(core.NewCacheMapper(new(core.SnakeMapper)))
|
||||
|
||||
runtime.SetFinalizer(engine, close)
|
||||
|
||||
return engine, nil
|
||||
}
|
||||
|
||||
// Clone clone an engine
|
||||
func (engine *Engine) Clone() (*Engine, error) {
|
||||
return NewEngine(engine.DriverName(), engine.DataSourceName())
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue