* upgrade xorm to v1.0.1 * fix start fail with postgres Co-authored-by: zeripath <art27@cantab.net>tags/v1.13.0-dev
mvdan.cc/xurls/v2 v2.1.0 | mvdan.cc/xurls/v2 v2.1.0 | ||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 | ||||
xorm.io/builder v0.3.7 | xorm.io/builder v0.3.7 | ||||
xorm.io/xorm v1.0.0 | |||||
xorm.io/xorm v1.0.1 | |||||
) | ) |
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= | xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= | ||||
xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM= | xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM= | ||||
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= | xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= | ||||
xorm.io/xorm v1.0.0 h1:ceiwUTrJHqfNFxIUcWjkcbz6kt7sINf2dOXlgLLhaQM= | |||||
xorm.io/xorm v1.0.0/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY= | |||||
xorm.io/xorm v1.0.1 h1:/lITxpJtkZauNpdzj+L9CN/3OQxZaABrbergMcJu+Cw= | |||||
xorm.io/xorm v1.0.1/go.mod h1:o4vnEsQ5V2F1/WK6w4XTwmiWJeGj82tqjAnHe44wVHY= |
# xorm.io/builder v0.3.7 | # xorm.io/builder v0.3.7 | ||||
## explicit | ## explicit | ||||
xorm.io/builder | xorm.io/builder | ||||
# xorm.io/xorm v1.0.0 | |||||
# xorm.io/xorm v1.0.1 | |||||
## explicit | ## explicit | ||||
xorm.io/xorm | xorm.io/xorm | ||||
xorm.io/xorm/caches | xorm.io/xorm/caches |
This changelog goes through all the changes that have been made in each release | This changelog goes through all the changes that have been made in each release | ||||
without substantial changes to our git log. | without substantial changes to our git log. | ||||
## [1.0.1](https://gitea.com/xorm/xorm/pulls?q=&type=all&state=closed&milestone=1253) - 2020-03-25 | |||||
* BUGFIXES | |||||
* Oracle : Local Naming Method (#1515) | |||||
* Fix find and count bug (#1618) | |||||
* Fix duplicated deleted condition on FindAndCount (#1619) | |||||
* Fix find and count bug with cache (#1622) | |||||
* Fix postgres schema problem (#1624) | |||||
* Fix quote with blank (#1626) | |||||
## [1.0.0](https://gitea.com/xorm/xorm/pulls?q=&type=all&state=closed&milestone=1242) - 2020-03-22 | ## [1.0.0](https://gitea.com/xorm/xorm/pulls?q=&type=all&state=closed&milestone=1242) - 2020-03-22 | ||||
* BREAKING | * BREAKING |
idx int | idx int | ||||
} | } | ||||
var ( | |||||
_ QueryExecuter = &DB{} | |||||
) | |||||
// DB is a wrap of sql.DB with extra contents | // DB is a wrap of sql.DB with extra contents | ||||
type DB struct { | type DB struct { | ||||
*sql.DB | *sql.DB |
package core | |||||
import ( | |||||
"context" | |||||
"database/sql" | |||||
) | |||||
// Queryer represents an interface to query a SQL to get data from database | |||||
type Queryer interface { | |||||
QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) | |||||
} | |||||
// Executer represents an interface to execute a SQL | |||||
type Executer interface { | |||||
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) | |||||
} | |||||
// QueryExecuter combines the Queryer and Executer | |||||
type QueryExecuter interface { | |||||
Queryer | |||||
Executer | |||||
} |
var i int | var i int | ||||
query = re.ReplaceAllStringFunc(query, func(src string) string { | query = re.ReplaceAllStringFunc(query, func(src string) string { | ||||
names[src[1:]] = i | names[src[1:]] = i | ||||
i += 1 | |||||
i++ | |||||
return "?" | return "?" | ||||
}) | }) | ||||
"xorm.io/xorm/log" | "xorm.io/xorm/log" | ||||
) | ) | ||||
var ( | |||||
_ QueryExecuter = &Tx{} | |||||
) | |||||
// Tx represents a transaction | |||||
type Tx struct { | type Tx struct { | ||||
*sql.Tx | *sql.Tx | ||||
db *DB | db *DB | ||||
var i int | var i int | ||||
query = re.ReplaceAllStringFunc(query, func(src string) string { | query = re.ReplaceAllStringFunc(query, func(src string) string { | ||||
names[src[1:]] = i | names[src[1:]] = i | ||||
i += 1 | |||||
i++ | |||||
return "?" | return "?" | ||||
}) | }) | ||||
// SetSchema set schema | // SetSchema set schema | ||||
func (uri *URI) SetSchema(schema string) { | func (uri *URI) SetSchema(schema string) { | ||||
// hack me | |||||
if uri.DBType == schemas.POSTGRES { | if uri.DBType == schemas.POSTGRES { | ||||
uri.Schema = schema | |||||
uri.Schema = strings.TrimSpace(schema) | |||||
} | } | ||||
} | } | ||||
// Dialect represents a kind of database | // Dialect represents a kind of database | ||||
type Dialect interface { | type Dialect interface { | ||||
Init(*core.DB, *URI) error | |||||
Init(*URI) error | |||||
URI() *URI | URI() *URI | ||||
DB() *core.DB | |||||
SQLType(*schemas.Column) string | SQLType(*schemas.Column) string | ||||
FormatBytes(b []byte) string | FormatBytes(b []byte) string | ||||
DefaultSchema() string | |||||
IsReserved(string) bool | IsReserved(string) bool | ||||
Quoter() schemas.Quoter | Quoter() schemas.Quoter | ||||
AutoIncrStr() string | AutoIncrStr() string | ||||
GetIndexes(ctx context.Context, tableName string) (map[string]*schemas.Index, error) | |||||
GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) | |||||
IndexCheckSQL(tableName, idxName string) (string, []interface{}) | IndexCheckSQL(tableName, idxName string) (string, []interface{}) | ||||
CreateIndexSQL(tableName string, index *schemas.Index) string | CreateIndexSQL(tableName string, index *schemas.Index) string | ||||
DropIndexSQL(tableName string, index *schemas.Index) string | DropIndexSQL(tableName string, index *schemas.Index) string | ||||
GetTables(ctx context.Context) ([]*schemas.Table, error) | |||||
IsTableExist(ctx context.Context, tableName string) (bool, error) | |||||
GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) | |||||
IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) | |||||
CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) | CreateTableSQL(table *schemas.Table, tableName string) ([]string, bool) | ||||
DropTableSQL(tableName string) (string, bool) | DropTableSQL(tableName string) (string, bool) | ||||
GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) | |||||
IsColumnExist(ctx context.Context, tableName string, colName string) (bool, error) | |||||
GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) | |||||
IsColumnExist(queryer core.Queryer, ctx context.Context, tableName string, colName string) (bool, error) | |||||
AddColumnSQL(tableName string, col *schemas.Column) string | AddColumnSQL(tableName string, col *schemas.Column) string | ||||
ModifyColumnSQL(tableName string, col *schemas.Column) string | ModifyColumnSQL(tableName string, col *schemas.Column) string | ||||
// Base represents a basic dialect and all real dialects could embed this struct | // Base represents a basic dialect and all real dialects could embed this struct | ||||
type Base struct { | type Base struct { | ||||
db *core.DB | |||||
dialect Dialect | dialect Dialect | ||||
uri *URI | uri *URI | ||||
quoter schemas.Quoter | quoter schemas.Quoter | ||||
return b.quoter | return b.quoter | ||||
} | } | ||||
func (b *Base) DB() *core.DB { | |||||
return b.db | |||||
} | |||||
func (b *Base) DefaultSchema() string { | |||||
return "" | |||||
} | |||||
func (b *Base) Init(db *core.DB, dialect Dialect, uri *URI) error { | |||||
b.db, b.dialect, b.uri = db, dialect, uri | |||||
func (b *Base) Init(dialect Dialect, uri *URI) error { | |||||
b.dialect, b.uri = dialect, uri | |||||
return nil | return nil | ||||
} | } | ||||
return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName)), true | return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName)), true | ||||
} | } | ||||
func (db *Base) HasRecords(ctx context.Context, query string, args ...interface{}) (bool, error) { | |||||
rows, err := db.DB().QueryContext(ctx, query, args...) | |||||
func (db *Base) HasRecords(queryer core.Queryer, ctx context.Context, query string, args ...interface{}) (bool, error) { | |||||
rows, err := queryer.QueryContext(ctx, query, args...) | |||||
if err != nil { | if err != nil { | ||||
return false, err | return false, err | ||||
} | } | ||||
return false, nil | return false, nil | ||||
} | } | ||||
func (db *Base) IsColumnExist(ctx context.Context, tableName, colName string) (bool, error) { | |||||
func (db *Base) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) { | |||||
quote := db.dialect.Quoter().Quote | quote := db.dialect.Quoter().Quote | ||||
query := fmt.Sprintf( | query := fmt.Sprintf( | ||||
"SELECT %v FROM %v.%v WHERE %v = ? AND %v = ? AND %v = ?", | "SELECT %v FROM %v.%v WHERE %v = ? AND %v = ? AND %v = ?", | ||||
quote("TABLE_NAME"), | quote("TABLE_NAME"), | ||||
quote("COLUMN_NAME"), | quote("COLUMN_NAME"), | ||||
) | ) | ||||
return db.HasRecords(ctx, query, db.uri.DBName, tableName, colName) | |||||
return db.HasRecords(queryer, ctx, query, db.uri.DBName, tableName, colName) | |||||
} | } | ||||
func (db *Base) AddColumnSQL(tableName string, col *schemas.Column) string { | func (db *Base) AddColumnSQL(tableName string, col *schemas.Column) string { |
import ( | import ( | ||||
"fmt" | "fmt" | ||||
"xorm.io/xorm/core" | |||||
) | ) | ||||
type Driver interface { | type Driver interface { | ||||
return nil, fmt.Errorf("Unsupported dialect type: %v", uri.DBType) | return nil, fmt.Errorf("Unsupported dialect type: %v", uri.DBType) | ||||
} | } | ||||
db, err := core.Open(driverName, connstr) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
dialect.Init(db, uri) | |||||
dialect.Init(uri) | |||||
return dialect, nil | return dialect, nil | ||||
} | } |
Base | Base | ||||
} | } | ||||
func (db *mssql) Init(d *core.DB, uri *URI) error { | |||||
func (db *mssql) Init(uri *URI) error { | |||||
db.quoter = mssqlQuoter | db.quoter = mssqlQuoter | ||||
return db.Base.Init(d, db, uri) | |||||
return db.Base.Init(db, uri) | |||||
} | } | ||||
func (db *mssql) SQLType(c *schemas.Column) string { | func (db *mssql) SQLType(c *schemas.Column) string { | ||||
return sql, args | return sql, args | ||||
} | } | ||||
func (db *mssql) IsColumnExist(ctx context.Context, tableName, colName string) (bool, error) { | |||||
func (db *mssql) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) { | |||||
query := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?` | query := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?` | ||||
return db.HasRecords(ctx, query, tableName, colName) | |||||
return db.HasRecords(queryer, ctx, query, tableName, colName) | |||||
} | } | ||||
func (db *mssql) IsTableExist(ctx context.Context, tableName string) (bool, error) { | |||||
func (db *mssql) IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) { | |||||
sql := "select * from sysobjects where id = object_id(N'" + tableName + "') and OBJECTPROPERTY(id, N'IsUserTable') = 1" | sql := "select * from sysobjects where id = object_id(N'" + tableName + "') and OBJECTPROPERTY(id, N'IsUserTable') = 1" | ||||
return db.HasRecords(ctx, sql) | |||||
return db.HasRecords(queryer, ctx, sql) | |||||
} | } | ||||
func (db *mssql) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
func (db *mssql) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
args := []interface{}{} | args := []interface{}{} | ||||
s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable, | s := `select a.name as name, b.name as ctype,a.max_length,a.precision,a.scale,a.is_nullable as nullable, | ||||
"default_is_null" = (CASE WHEN c.text is null THEN 1 ELSE 0 END), | "default_is_null" = (CASE WHEN c.text is null THEN 1 ELSE 0 END), | ||||
) as p on p.object_id = a.object_id AND p.column_id = a.column_id | ) as p on p.object_id = a.object_id AND p.column_id = a.column_id | ||||
where a.object_id=object_id('` + tableName + `')` | where a.object_id=object_id('` + tableName + `')` | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, nil, err | return nil, nil, err | ||||
} | } | ||||
return colSeq, cols, nil | return colSeq, cols, nil | ||||
} | } | ||||
func (db *mssql) GetTables(ctx context.Context) ([]*schemas.Table, error) { | |||||
func (db *mssql) GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) { | |||||
args := []interface{}{} | args := []interface{}{} | ||||
s := `select name from sysobjects where xtype ='U'` | s := `select name from sysobjects where xtype ='U'` | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
return tables, nil | return tables, nil | ||||
} | } | ||||
func (db *mssql) GetIndexes(ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
func (db *mssql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
args := []interface{}{tableName} | args := []interface{}{tableName} | ||||
s := `SELECT | s := `SELECT | ||||
IXS.NAME AS [INDEX_NAME], | IXS.NAME AS [INDEX_NAME], | ||||
WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =? | WHERE IXS.TYPE_DESC='NONCLUSTERED' and OBJECT_NAME(IXS.OBJECT_ID) =? | ||||
` | ` | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } |
rowFormat string | rowFormat string | ||||
} | } | ||||
func (db *mysql) Init(d *core.DB, uri *URI) error { | |||||
func (db *mysql) Init(uri *URI) error { | |||||
db.quoter = mysqlQuoter | db.quoter = mysqlQuoter | ||||
return db.Base.Init(d, db, uri) | |||||
return db.Base.Init(db, uri) | |||||
} | } | ||||
func (db *mysql) SetParams(params map[string]string) { | func (db *mysql) SetParams(params map[string]string) { | ||||
return sql, args | return sql, args | ||||
} | } | ||||
func (db *mysql) IsTableExist(ctx context.Context, tableName string) (bool, error) { | |||||
func (db *mysql) IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) { | |||||
sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?" | sql := "SELECT `TABLE_NAME` from `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? and `TABLE_NAME`=?" | ||||
return db.HasRecords(ctx, sql, db.uri.DBName, tableName) | |||||
return db.HasRecords(queryer, ctx, sql, db.uri.DBName, tableName) | |||||
} | } | ||||
func (db *mysql) AddColumnSQL(tableName string, col *schemas.Column) string { | func (db *mysql) AddColumnSQL(tableName string, col *schemas.Column) string { | ||||
return sql | return sql | ||||
} | } | ||||
func (db *mysql) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
args := []interface{}{db.uri.DBName, tableName} | args := []interface{}{db.uri.DBName, tableName} | ||||
s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," + | s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," + | ||||
" `COLUMN_KEY`, `EXTRA`,`COLUMN_COMMENT` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" | " `COLUMN_KEY`, `EXTRA`,`COLUMN_COMMENT` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, nil, err | return nil, nil, err | ||||
} | } | ||||
return colSeq, cols, nil | return colSeq, cols, nil | ||||
} | } | ||||
func (db *mysql) GetTables(ctx context.Context) ([]*schemas.Table, error) { | |||||
func (db *mysql) GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) { | |||||
args := []interface{}{db.uri.DBName} | args := []interface{}{db.uri.DBName} | ||||
s := "SELECT `TABLE_NAME`, `ENGINE`, `AUTO_INCREMENT`, `TABLE_COMMENT` from " + | s := "SELECT `TABLE_NAME`, `ENGINE`, `AUTO_INCREMENT`, `TABLE_COMMENT` from " + | ||||
"`INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? AND (`ENGINE`='MyISAM' OR `ENGINE` = 'InnoDB' OR `ENGINE` = 'TokuDB')" | "`INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA`=? AND (`ENGINE`='MyISAM' OR `ENGINE` = 'InnoDB' OR `ENGINE` = 'TokuDB')" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
} | } | ||||
} | } | ||||
func (db *mysql) GetIndexes(ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
func (db *mysql) GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
args := []interface{}{db.uri.DBName, tableName} | args := []interface{}{db.uri.DBName, tableName} | ||||
s := "SELECT `INDEX_NAME`, `NON_UNIQUE`, `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" | s := "SELECT `INDEX_NAME`, `NON_UNIQUE`, `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`STATISTICS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } |
Base | Base | ||||
} | } | ||||
func (db *oracle) Init(d *core.DB, uri *URI) error { | |||||
func (db *oracle) Init(uri *URI) error { | |||||
db.quoter = oracleQuoter | db.quoter = oracleQuoter | ||||
return db.Base.Init(d, db, uri) | |||||
return db.Base.Init(db, uri) | |||||
} | } | ||||
func (db *oracle) SQLType(c *schemas.Column) string { | func (db *oracle) SQLType(c *schemas.Column) string { | ||||
`WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args | `WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args | ||||
} | } | ||||
func (db *oracle) IsTableExist(ctx context.Context, tableName string) (bool, error) { | |||||
return db.HasRecords(ctx, `SELECT table_name FROM user_tables WHERE table_name = :1`, tableName) | |||||
func (db *oracle) IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) { | |||||
return db.HasRecords(queryer, ctx, `SELECT table_name FROM user_tables WHERE table_name = :1`, tableName) | |||||
} | } | ||||
func (db *oracle) IsColumnExist(ctx context.Context, tableName, colName string) (bool, error) { | |||||
func (db *oracle) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) { | |||||
args := []interface{}{tableName, colName} | args := []interface{}{tableName, colName} | ||||
query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" + | query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" + | ||||
" AND column_name = :2" | " AND column_name = :2" | ||||
return db.HasRecords(ctx, query, args...) | |||||
return db.HasRecords(queryer, ctx, query, args...) | |||||
} | } | ||||
func (db *oracle) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
func (db *oracle) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
args := []interface{}{tableName} | args := []interface{}{tableName} | ||||
s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," + | s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," + | ||||
"nullable FROM USER_TAB_COLUMNS WHERE table_name = :1" | "nullable FROM USER_TAB_COLUMNS WHERE table_name = :1" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, nil, err | return nil, nil, err | ||||
} | } | ||||
return colSeq, cols, nil | return colSeq, cols, nil | ||||
} | } | ||||
func (db *oracle) GetTables(ctx context.Context) ([]*schemas.Table, error) { | |||||
func (db *oracle) GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) { | |||||
args := []interface{}{} | args := []interface{}{} | ||||
s := "SELECT table_name FROM user_tables" | s := "SELECT table_name FROM user_tables" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
return tables, nil | return tables, nil | ||||
} | } | ||||
func (db *oracle) GetIndexes(ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
func (db *oracle) GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
args := []interface{}{tableName} | args := []interface{}{tableName} | ||||
s := "SELECT t.column_name,i.uniqueness,i.index_name FROM user_ind_columns t,user_indexes i " + | 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" | "WHERE t.index_name = i.index_name and t.table_name = i.table_name and t.table_name =:1" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
db.DBName = match | db.DBName = match | ||||
} | } | ||||
} | } | ||||
if db.DBName == "" { | |||||
if db.DBName == "" && len(matches) != 0 { | |||||
return nil, errors.New("dbname is empty") | return nil, errors.New("dbname is empty") | ||||
} | } | ||||
return db, nil | return db, nil |
postgresQuoter = schemas.Quoter{'"', '"', schemas.AlwaysReserve} | postgresQuoter = schemas.Quoter{'"', '"', schemas.AlwaysReserve} | ||||
) | ) | ||||
const postgresPublicSchema = "public" | |||||
var ( | |||||
// DefaultPostgresSchema default postgres schema | |||||
DefaultPostgresSchema = "public" | |||||
) | |||||
type postgres struct { | type postgres struct { | ||||
Base | Base | ||||
} | } | ||||
func (db *postgres) Init(d *core.DB, uri *URI) error { | |||||
func (db *postgres) Init(uri *URI) error { | |||||
db.quoter = postgresQuoter | db.quoter = postgresQuoter | ||||
err := db.Base.Init(d, db, uri) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
if db.uri.Schema == "" { | |||||
db.uri.Schema = postgresPublicSchema | |||||
return db.Base.Init(db, uri) | |||||
} | |||||
func (db *postgres) getSchema() string { | |||||
if db.uri.Schema != "" { | |||||
return db.uri.Schema | |||||
} | } | ||||
return nil | |||||
return DefaultPostgresSchema | |||||
} | } | ||||
func (db *postgres) needQuote(name string) bool { | func (db *postgres) needQuote(name string) bool { | ||||
} | } | ||||
} | } | ||||
func (db *postgres) DefaultSchema() string { | |||||
return postgresPublicSchema | |||||
} | |||||
func (db *postgres) SQLType(c *schemas.Column) string { | func (db *postgres) SQLType(c *schemas.Column) string { | ||||
var res string | var res string | ||||
switch t := c.SQLType.Name; t { | switch t := c.SQLType.Name; t { | ||||
} | } | ||||
func (db *postgres) IndexCheckSQL(tableName, idxName string) (string, []interface{}) { | func (db *postgres) IndexCheckSQL(tableName, idxName string) (string, []interface{}) { | ||||
if len(db.uri.Schema) == 0 { | |||||
if len(db.getSchema()) == 0 { | |||||
args := []interface{}{tableName, idxName} | args := []interface{}{tableName, idxName} | ||||
return `SELECT indexname FROM pg_indexes WHERE tablename = ? AND indexname = ?`, args | return `SELECT indexname FROM pg_indexes WHERE tablename = ? AND indexname = ?`, args | ||||
} | } | ||||
args := []interface{}{db.uri.Schema, tableName, idxName} | |||||
args := []interface{}{db.getSchema(), tableName, idxName} | |||||
return `SELECT indexname FROM pg_indexes ` + | return `SELECT indexname FROM pg_indexes ` + | ||||
`WHERE schemaname = ? AND tablename = ? AND indexname = ?`, args | `WHERE schemaname = ? AND tablename = ? AND indexname = ?`, args | ||||
} | } | ||||
func (db *postgres) IsTableExist(ctx context.Context, tableName string) (bool, error) { | |||||
if len(db.uri.Schema) == 0 { | |||||
return db.HasRecords(ctx, `SELECT tablename FROM pg_tables WHERE tablename = $1`, tableName) | |||||
func (db *postgres) IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) { | |||||
if len(db.getSchema()) == 0 { | |||||
return db.HasRecords(queryer, ctx, `SELECT tablename FROM pg_tables WHERE tablename = $1`, tableName) | |||||
} | } | ||||
return db.HasRecords(ctx, `SELECT tablename FROM pg_tables WHERE schemaname = $1 AND tablename = $2`, | |||||
db.uri.Schema, tableName) | |||||
return db.HasRecords(queryer, ctx, `SELECT tablename FROM pg_tables WHERE schemaname = $1 AND tablename = $2`, | |||||
db.getSchema(), tableName) | |||||
} | } | ||||
func (db *postgres) ModifyColumnSQL(tableName string, col *schemas.Column) string { | func (db *postgres) ModifyColumnSQL(tableName string, col *schemas.Column) string { | ||||
if len(db.uri.Schema) == 0 || strings.Contains(tableName, ".") { | |||||
if len(db.getSchema()) == 0 || strings.Contains(tableName, ".") { | |||||
return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", | return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s", | ||||
tableName, col.Name, db.SQLType(col)) | tableName, col.Name, db.SQLType(col)) | ||||
} | } | ||||
return fmt.Sprintf("alter table %s.%s ALTER COLUMN %s TYPE %s", | return fmt.Sprintf("alter table %s.%s ALTER COLUMN %s TYPE %s", | ||||
db.uri.Schema, tableName, col.Name, db.SQLType(col)) | |||||
db.getSchema(), tableName, col.Name, db.SQLType(col)) | |||||
} | } | ||||
func (db *postgres) DropIndexSQL(tableName string, index *schemas.Index) string { | func (db *postgres) DropIndexSQL(tableName string, index *schemas.Index) string { | ||||
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) | idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name) | ||||
} | } | ||||
} | } | ||||
if db.uri.Schema != "" { | |||||
idxName = db.uri.Schema + "." + idxName | |||||
if db.getSchema() != "" { | |||||
idxName = db.getSchema() + "." + idxName | |||||
} | } | ||||
return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName)) | return fmt.Sprintf("DROP INDEX %v", db.Quoter().Quote(idxName)) | ||||
} | } | ||||
func (db *postgres) IsColumnExist(ctx context.Context, tableName, colName string) (bool, error) { | |||||
args := []interface{}{db.uri.Schema, tableName, colName} | |||||
func (db *postgres) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) { | |||||
args := []interface{}{db.getSchema(), tableName, colName} | |||||
query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = $1 AND table_name = $2" + | query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = $1 AND table_name = $2" + | ||||
" AND column_name = $3" | " AND column_name = $3" | ||||
if len(db.uri.Schema) == 0 { | |||||
if len(db.getSchema()) == 0 { | |||||
args = []interface{}{tableName, colName} | args = []interface{}{tableName, colName} | ||||
query = "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + | query = "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" + | ||||
" AND column_name = $2" | " AND column_name = $2" | ||||
} | } | ||||
rows, err := db.DB().QueryContext(ctx, query, args...) | |||||
rows, err := queryer.QueryContext(ctx, query, args...) | |||||
if err != nil { | if err != nil { | ||||
return false, err | return false, err | ||||
} | } | ||||
return rows.Next(), nil | return rows.Next(), nil | ||||
} | } | ||||
func (db *postgres) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
args := []interface{}{db.uri.Schema, tableName, db.uri.Schema} | |||||
func (db *postgres) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
args := []interface{}{tableName} | |||||
s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, | s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, | ||||
CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey, | CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey, | ||||
CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey | CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey | ||||
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) | LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) | ||||
LEFT JOIN pg_class AS g ON p.confrelid = g.oid | LEFT JOIN pg_class AS g ON p.confrelid = g.oid | ||||
LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name | LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name | ||||
WHERE n.nspname= $1 AND c.relkind = 'r'::char AND c.relname = $2 AND s.table_schema = $3 AND f.attnum > 0 ORDER BY f.attnum;` | |||||
WHERE n.nspname= s.table_schema AND c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.attnum;` | |||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
schema := db.getSchema() | |||||
if schema != "" { | |||||
s = fmt.Sprintf(s, "AND s.table_schema = $2") | |||||
args = append(args, schema) | |||||
} else { | |||||
s = fmt.Sprintf(s, "") | |||||
} | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, nil, err | return nil, nil, err | ||||
} | } | ||||
return colSeq, cols, nil | return colSeq, cols, nil | ||||
} | } | ||||
func (db *postgres) GetTables(ctx context.Context) ([]*schemas.Table, error) { | |||||
func (db *postgres) GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) { | |||||
args := []interface{}{} | args := []interface{}{} | ||||
s := "SELECT tablename FROM pg_tables" | s := "SELECT tablename FROM pg_tables" | ||||
if len(db.uri.Schema) != 0 { | |||||
args = append(args, db.uri.Schema) | |||||
schema := db.getSchema() | |||||
if schema != "" { | |||||
args = append(args, schema) | |||||
s = s + " WHERE schemaname = $1" | s = s + " WHERE schemaname = $1" | ||||
} | } | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
return colNames | return colNames | ||||
} | } | ||||
func (db *postgres) GetIndexes(ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
func (db *postgres) GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
args := []interface{}{tableName} | args := []interface{}{tableName} | ||||
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1") | s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1") | ||||
if len(db.uri.Schema) != 0 { | |||||
args = append(args, db.uri.Schema) | |||||
if len(db.getSchema()) != 0 { | |||||
args = append(args, db.getSchema()) | |||||
s = s + " AND schemaname=$2" | s = s + " AND schemaname=$2" | ||||
} | } | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
} | } | ||||
return pgx.pqDriver.Parse(driverName, dataSourceName) | return pgx.pqDriver.Parse(driverName, dataSourceName) | ||||
} | } | ||||
// QueryDefaultPostgresSchema returns the default postgres schema | |||||
func QueryDefaultPostgresSchema(ctx context.Context, queryer core.Queryer) (string, error) { | |||||
rows, err := queryer.QueryContext(ctx, "SHOW SEARCH_PATH") | |||||
if err != nil { | |||||
return "", err | |||||
} | |||||
defer rows.Close() | |||||
if rows.Next() { | |||||
var defaultSchema string | |||||
if err = rows.Scan(&defaultSchema); err != nil { | |||||
return "", err | |||||
} | |||||
parts := strings.Split(defaultSchema, ",") | |||||
return strings.TrimSpace(parts[len(parts)-1]), nil | |||||
} | |||||
return "", errors.New("No default schema") | |||||
} |
Base | Base | ||||
} | } | ||||
func (db *sqlite3) Init(d *core.DB, uri *URI) error { | |||||
func (db *sqlite3) Init(uri *URI) error { | |||||
db.quoter = sqlite3Quoter | db.quoter = sqlite3Quoter | ||||
return db.Base.Init(d, db, uri) | |||||
return db.Base.Init(db, uri) | |||||
} | } | ||||
func (db *sqlite3) SetQuotePolicy(quotePolicy QuotePolicy) { | func (db *sqlite3) SetQuotePolicy(quotePolicy QuotePolicy) { | ||||
return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args | return "SELECT name FROM sqlite_master WHERE type='index' and name = ?", args | ||||
} | } | ||||
func (db *sqlite3) IsTableExist(ctx context.Context, tableName string) (bool, error) { | |||||
return db.HasRecords(ctx, "SELECT name FROM sqlite_master WHERE type='table' and name = ?", tableName) | |||||
func (db *sqlite3) IsTableExist(queryer core.Queryer, ctx context.Context, tableName string) (bool, error) { | |||||
return db.HasRecords(queryer, ctx, "SELECT name FROM sqlite_master WHERE type='table' and name = ?", tableName) | |||||
} | } | ||||
func (db *sqlite3) DropIndexSQL(tableName string, index *schemas.Index) string { | func (db *sqlite3) DropIndexSQL(tableName string, index *schemas.Index) string { | ||||
return query | return query | ||||
} | } | ||||
func (db *sqlite3) IsColumnExist(ctx context.Context, tableName, colName string) (bool, error) { | |||||
func (db *sqlite3) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) { | |||||
query := "SELECT * FROM " + tableName + " LIMIT 0" | query := "SELECT * FROM " + tableName + " LIMIT 0" | ||||
rows, err := db.DB().QueryContext(ctx, query) | |||||
rows, err := queryer.QueryContext(ctx, query) | |||||
if err != nil { | if err != nil { | ||||
return false, err | return false, err | ||||
} | } | ||||
return col, nil | return col, nil | ||||
} | } | ||||
func (db *sqlite3) GetColumns(ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
func (db *sqlite3) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) { | |||||
args := []interface{}{tableName} | args := []interface{}{tableName} | ||||
s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?" | s := "SELECT sql FROM sqlite_master WHERE type='table' and name = ?" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, nil, err | return nil, nil, err | ||||
} | } | ||||
return colSeq, cols, nil | return colSeq, cols, nil | ||||
} | } | ||||
func (db *sqlite3) GetTables(ctx context.Context) ([]*schemas.Table, error) { | |||||
func (db *sqlite3) GetTables(queryer core.Queryer, ctx context.Context) ([]*schemas.Table, error) { | |||||
args := []interface{}{} | args := []interface{}{} | ||||
s := "SELECT name FROM sqlite_master WHERE type='table'" | s := "SELECT name FROM sqlite_master WHERE type='table'" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
return tables, nil | return tables, nil | ||||
} | } | ||||
func (db *sqlite3) GetIndexes(ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
func (db *sqlite3) GetIndexes(queryer core.Queryer, ctx context.Context, tableName string) (map[string]*schemas.Index, error) { | |||||
args := []interface{}{tableName} | args := []interface{}{tableName} | ||||
s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?" | s := "SELECT sql FROM sqlite_master WHERE type='index' and tbl_name = ?" | ||||
rows, err := db.DB().QueryContext(ctx, s, args...) | |||||
rows, err := queryer.QueryContext(ctx, s, args...) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } |
// Add schema name as prefix of table name. | // Add schema name as prefix of table name. | ||||
// Only for postgres database. | // Only for postgres database. | ||||
if dialect.URI().Schema != "" && | if dialect.URI().Schema != "" && | ||||
dialect.URI().Schema != dialect.DefaultSchema() && | |||||
strings.Index(tableName, ".") == -1 { | strings.Index(tableName, ".") == -1 { | ||||
return fmt.Sprintf("%s.%s", dialect.URI().Schema, tableName) | return fmt.Sprintf("%s.%s", dialect.URI().Schema, tableName) | ||||
} | } |
engineGroup *EngineGroup | engineGroup *EngineGroup | ||||
logger log.ContextLogger | logger log.ContextLogger | ||||
tagParser *tags.Parser | tagParser *tags.Parser | ||||
db *core.DB | |||||
driverName string | driverName string | ||||
dataSourceName string | dataSourceName string | ||||
// DB return the wrapper of sql.DB | // DB return the wrapper of sql.DB | ||||
func (engine *Engine) DB() *core.DB { | func (engine *Engine) DB() *core.DB { | ||||
return engine.dialect.DB() | |||||
return engine.db | |||||
} | } | ||||
// Dialect return database dialect | // Dialect return database dialect | ||||
} | } | ||||
func (engine *Engine) loadTableInfo(table *schemas.Table) error { | func (engine *Engine) loadTableInfo(table *schemas.Table) error { | ||||
colSeq, cols, err := engine.dialect.GetColumns(engine.defaultContext, table.Name) | |||||
colSeq, cols, err := engine.dialect.GetColumns(engine.db, engine.defaultContext, table.Name) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
for _, name := range colSeq { | for _, name := range colSeq { | ||||
table.AddColumn(cols[name]) | table.AddColumn(cols[name]) | ||||
} | } | ||||
indexes, err := engine.dialect.GetIndexes(engine.defaultContext, table.Name) | |||||
indexes, err := engine.dialect.GetIndexes(engine.db, engine.defaultContext, table.Name) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
// DBMetas Retrieve all tables, columns, indexes' informations from database. | // DBMetas Retrieve all tables, columns, indexes' informations from database. | ||||
func (engine *Engine) DBMetas() ([]*schemas.Table, error) { | func (engine *Engine) DBMetas() ([]*schemas.Table, error) { | ||||
tables, err := engine.dialect.GetTables(engine.defaultContext) | |||||
tables, err := engine.dialect.GetTables(engine.db, engine.defaultContext) | |||||
if err != nil { | if err != nil { | ||||
return nil, err | return nil, err | ||||
} | } | ||||
uri := engine.dialect.URI() | uri := engine.dialect.URI() | ||||
destURI := *uri | destURI := *uri | ||||
dstDialect.Init(nil, &destURI) | |||||
dstDialect.Init(&destURI) | |||||
} | } | ||||
_, err := io.WriteString(w, fmt.Sprintf("/*Generated by xorm %s, from %s to %s*/\n\n", | _, err := io.WriteString(w, fmt.Sprintf("/*Generated by xorm %s, from %s to %s*/\n\n", | ||||
} | } | ||||
} else { | } else { | ||||
for _, col := range table.Columns() { | for _, col := range table.Columns() { | ||||
isExist, err := engine.dialect.IsColumnExist(session.ctx, tableNameNoSchema, col.Name) | |||||
isExist, err := engine.dialect.IsColumnExist(engine.db, session.ctx, tableNameNoSchema, col.Name) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } |
// SetMaxIdleConns set the max idle connections on pool, default is 2 | // SetMaxIdleConns set the max idle connections on pool, default is 2 | ||||
func (eg *EngineGroup) SetMaxIdleConns(conns int) { | func (eg *EngineGroup) SetMaxIdleConns(conns int) { | ||||
eg.Engine.dialect.DB().SetMaxIdleConns(conns) | |||||
eg.Engine.DB().SetMaxIdleConns(conns) | |||||
for i := 0; i < len(eg.slaves); i++ { | for i := 0; i < len(eg.slaves); i++ { | ||||
eg.slaves[i].dialect.DB().SetMaxIdleConns(conns) | |||||
eg.slaves[i].DB().SetMaxIdleConns(conns) | |||||
} | } | ||||
} | } | ||||
// SetMaxOpenConns is only available for go 1.2+ | // SetMaxOpenConns is only available for go 1.2+ | ||||
func (eg *EngineGroup) SetMaxOpenConns(conns int) { | func (eg *EngineGroup) SetMaxOpenConns(conns int) { | ||||
eg.Engine.dialect.DB().SetMaxOpenConns(conns) | |||||
eg.Engine.DB().SetMaxOpenConns(conns) | |||||
for i := 0; i < len(eg.slaves); i++ { | for i := 0; i < len(eg.slaves); i++ { | ||||
eg.slaves[i].dialect.DB().SetMaxOpenConns(conns) | |||||
eg.slaves[i].DB().SetMaxOpenConns(conns) | |||||
} | } | ||||
} | } | ||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= | cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= | ||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= | cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= | ||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= | |||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= | gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= | ||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= | github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= | ||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= | github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= | ||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= | ||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= | |||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= | |||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= | |||||
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= | |||||
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI= | xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI= | ||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= | xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= |
} | } | ||||
func (statement *Statement) mergeConds(bean interface{}) error { | func (statement *Statement) mergeConds(bean interface{}) error { | ||||
if !statement.NoAutoCondition { | |||||
if !statement.NoAutoCondition && statement.RefTable != nil { | |||||
var addedTableName = (len(statement.JoinStr) > 0) | var addedTableName = (len(statement.JoinStr) > 0) | ||||
autoCond, err := statement.BuildConds(statement.RefTable, bean, true, true, false, true, addedTableName) | autoCond, err := statement.BuildConds(statement.RefTable, bean, true, true, false, true, addedTableName) | ||||
if err != nil { | if err != nil { |
return start | return start | ||||
} | } | ||||
var k int | |||||
var k = -1 | |||||
for j := start; j < len(value); j++ { | for j := start; j < len(value); j++ { | ||||
if value[j] != ' ' { | if value[j] != ' ' { | ||||
k = j | k = j | ||||
break | break | ||||
} | } | ||||
} | } | ||||
if k-1 == len(value) { | |||||
if k == -1 { | |||||
return len(value) | return len(value) | ||||
} | } | ||||
if (value[k] == 'A' || value[k] == 'a') && (value[k+1] == 'S' || value[k+1] == 's') { | if (value[k] == 'A' || value[k] == 'a') && (value[k+1] == 'S' || value[k+1] == 's') { | ||||
k = k + 2 | k = k + 2 | ||||
} | } | ||||
return err | return err | ||||
} | } | ||||
} | } | ||||
var nextEnd = findWord(value, start) | |||||
if start == len(value) { | |||||
return nil | |||||
} | |||||
var nextEnd = findWord(value, start) | |||||
if err := q.quoteWordTo(buf, value[start:nextEnd]); err != nil { | if err := q.quoteWordTo(buf, value[start:nextEnd]); err != nil { | ||||
return err | return err | ||||
} | } |
session.engine.tagParser, | session.engine.tagParser, | ||||
session.engine.DatabaseTZ, | session.engine.DatabaseTZ, | ||||
) | ) | ||||
session.db = session.engine.db | |||||
session.isAutoCommit = true | session.isAutoCommit = true | ||||
session.isCommitedOrRollbacked = false | session.isCommitedOrRollbacked = false | ||||
session.isAutoClose = false | session.isAutoClose = false | ||||
} | } | ||||
} | } | ||||
func (session *Session) getQueryer() core.Queryer { | |||||
if session.tx != nil { | |||||
return session.tx | |||||
} | |||||
return session.db | |||||
} | |||||
// ContextCache enable context cache or not | // ContextCache enable context cache or not | ||||
func (session *Session) ContextCache(context contexts.ContextCache) *Session { | func (session *Session) ContextCache(context contexts.ContextCache) *Session { | ||||
session.statement.SetContextCache(context) | session.statement.SetContextCache(context) |
"xorm.io/builder" | "xorm.io/builder" | ||||
"xorm.io/xorm/caches" | "xorm.io/xorm/caches" | ||||
"xorm.io/xorm/internal/statements" | |||||
"xorm.io/xorm/internal/utils" | "xorm.io/xorm/internal/utils" | ||||
"xorm.io/xorm/schemas" | "xorm.io/xorm/schemas" | ||||
) | ) | ||||
session.statement.OrderStr = "" | session.statement.OrderStr = "" | ||||
} | } | ||||
return session.Count(reflect.New(sliceElementType).Interface()) | |||||
// session has stored the conditions so we use `unscoped` to avoid duplicated condition. | |||||
return session.Unscoped().Count(reflect.New(sliceElementType).Interface()) | |||||
} | } | ||||
func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { | func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{}) error { | ||||
slices := reflect.New(reflect.SliceOf(t)) | slices := reflect.New(reflect.SliceOf(t)) | ||||
beans := slices.Interface() | beans := slices.Interface() | ||||
statement := session.statement | |||||
session.statement = statements.NewStatement( | |||||
session.engine.dialect, | |||||
session.engine.tagParser, | |||||
session.engine.DatabaseTZ, | |||||
) | |||||
if len(table.PrimaryKeys) == 1 { | if len(table.PrimaryKeys) == 1 { | ||||
ff := make([]interface{}, 0, len(ides)) | ff := make([]interface{}, 0, len(ides)) | ||||
for _, ie := range ides { | for _, ie := range ides { | ||||
return err | return err | ||||
} | } | ||||
session.statement = statement | |||||
vs := reflect.Indirect(reflect.ValueOf(beans)) | vs := reflect.Indirect(reflect.ValueOf(beans)) | ||||
for i := 0; i < vs.Len(); i++ { | for i := 0; i < vs.Len(); i++ { | ||||
rv := vs.Index(i) | rv := vs.Index(i) |
tableName := session.engine.TableName(beanOrTableName) | tableName := session.engine.TableName(beanOrTableName) | ||||
sqlStr, checkIfExist := session.engine.dialect.DropTableSQL(session.engine.TableName(tableName, true)) | sqlStr, checkIfExist := session.engine.dialect.DropTableSQL(session.engine.TableName(tableName, true)) | ||||
if !checkIfExist { | if !checkIfExist { | ||||
exist, err := session.engine.dialect.IsTableExist(session.ctx, tableName) | |||||
exist, err := session.engine.dialect.IsTableExist(session.getQueryer(), session.ctx, tableName) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } | ||||
} | } | ||||
func (session *Session) isTableExist(tableName string) (bool, error) { | func (session *Session) isTableExist(tableName string) (bool, error) { | ||||
return session.engine.dialect.IsTableExist(session.ctx, tableName) | |||||
return session.engine.dialect.IsTableExist(session.getQueryer(), session.ctx, tableName) | |||||
} | } | ||||
// IsTableEmpty if table have any records | // IsTableEmpty if table have any records | ||||
// find if index is exist according cols | // find if index is exist according cols | ||||
func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) { | func (session *Session) isIndexExist2(tableName string, cols []string, unique bool) (bool, error) { | ||||
indexes, err := session.engine.dialect.GetIndexes(session.ctx, tableName) | |||||
indexes, err := session.engine.dialect.GetIndexes(session.getQueryer(), session.ctx, tableName) | |||||
if err != nil { | if err != nil { | ||||
return false, err | return false, err | ||||
} | } | ||||
defer session.Close() | defer session.Close() | ||||
} | } | ||||
tables, err := engine.dialect.GetTables(session.ctx) | |||||
tables, err := engine.dialect.GetTables(session.getQueryer(), session.ctx) | |||||
if err != nil { | if err != nil { | ||||
return err | return err | ||||
} | } |
"time" | "time" | ||||
"xorm.io/xorm/caches" | "xorm.io/xorm/caches" | ||||
"xorm.io/xorm/core" | |||||
"xorm.io/xorm/dialects" | "xorm.io/xorm/dialects" | ||||
"xorm.io/xorm/log" | "xorm.io/xorm/log" | ||||
"xorm.io/xorm/names" | "xorm.io/xorm/names" | ||||
return nil, err | return nil, err | ||||
} | } | ||||
db, err := core.Open(driverName, dataSourceName) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
cacherMgr := caches.NewManager() | cacherMgr := caches.NewManager() | ||||
mapper := names.NewCacheMapper(new(names.SnakeMapper)) | mapper := names.NewCacheMapper(new(names.SnakeMapper)) | ||||
tagParser := tags.NewParser("xorm", dialect, mapper, mapper, cacherMgr) | tagParser := tags.NewParser("xorm", dialect, mapper, mapper, cacherMgr) | ||||
tagParser: tagParser, | tagParser: tagParser, | ||||
driverName: driverName, | driverName: driverName, | ||||
dataSourceName: dataSourceName, | dataSourceName: dataSourceName, | ||||
db: db, | |||||
} | } | ||||
if dialect.URI().DBType == schemas.SQLITE { | if dialect.URI().DBType == schemas.SQLITE { |