You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dialect.go 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. package core
  2. import (
  3. "fmt"
  4. "strings"
  5. "time"
  6. )
  7. type DbType string
  8. type Uri struct {
  9. DbType DbType
  10. Proto string
  11. Host string
  12. Port string
  13. DbName string
  14. User string
  15. Passwd string
  16. Charset string
  17. Laddr string
  18. Raddr string
  19. Timeout time.Duration
  20. Schema string
  21. }
  22. // a dialect is a driver's wrapper
  23. type Dialect interface {
  24. SetLogger(logger ILogger)
  25. Init(*DB, *Uri, string, string) error
  26. URI() *Uri
  27. DB() *DB
  28. DBType() DbType
  29. SqlType(*Column) string
  30. FormatBytes(b []byte) string
  31. DriverName() string
  32. DataSourceName() string
  33. QuoteStr() string
  34. IsReserved(string) bool
  35. Quote(string) string
  36. AndStr() string
  37. OrStr() string
  38. EqStr() string
  39. RollBackStr() string
  40. AutoIncrStr() string
  41. SupportInsertMany() bool
  42. SupportEngine() bool
  43. SupportCharset() bool
  44. SupportDropIfExists() bool
  45. IndexOnTable() bool
  46. ShowCreateNull() bool
  47. IndexCheckSql(tableName, idxName string) (string, []interface{})
  48. TableCheckSql(tableName string) (string, []interface{})
  49. IsColumnExist(tableName string, colName string) (bool, error)
  50. CreateTableSql(table *Table, tableName, storeEngine, charset string) string
  51. DropTableSql(tableName string) string
  52. CreateIndexSql(tableName string, index *Index) string
  53. DropIndexSql(tableName string, index *Index) string
  54. ModifyColumnSql(tableName string, col *Column) string
  55. ForUpdateSql(query string) string
  56. //CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
  57. //MustDropTable(tableName string) error
  58. GetColumns(tableName string) ([]string, map[string]*Column, error)
  59. GetTables() ([]*Table, error)
  60. GetIndexes(tableName string) (map[string]*Index, error)
  61. Filters() []Filter
  62. SetParams(params map[string]string)
  63. }
  64. func OpenDialect(dialect Dialect) (*DB, error) {
  65. return Open(dialect.DriverName(), dialect.DataSourceName())
  66. }
  67. type Base struct {
  68. db *DB
  69. dialect Dialect
  70. driverName string
  71. dataSourceName string
  72. logger ILogger
  73. *Uri
  74. }
  75. func (b *Base) DB() *DB {
  76. return b.db
  77. }
  78. func (b *Base) SetLogger(logger ILogger) {
  79. b.logger = logger
  80. }
  81. func (b *Base) Init(db *DB, dialect Dialect, uri *Uri, drivername, dataSourceName string) error {
  82. b.db, b.dialect, b.Uri = db, dialect, uri
  83. b.driverName, b.dataSourceName = drivername, dataSourceName
  84. return nil
  85. }
  86. func (b *Base) URI() *Uri {
  87. return b.Uri
  88. }
  89. func (b *Base) DBType() DbType {
  90. return b.Uri.DbType
  91. }
  92. func (b *Base) FormatBytes(bs []byte) string {
  93. return fmt.Sprintf("0x%x", bs)
  94. }
  95. func (b *Base) DriverName() string {
  96. return b.driverName
  97. }
  98. func (b *Base) ShowCreateNull() bool {
  99. return true
  100. }
  101. func (b *Base) DataSourceName() string {
  102. return b.dataSourceName
  103. }
  104. func (b *Base) AndStr() string {
  105. return "AND"
  106. }
  107. func (b *Base) OrStr() string {
  108. return "OR"
  109. }
  110. func (b *Base) EqStr() string {
  111. return "="
  112. }
  113. func (db *Base) RollBackStr() string {
  114. return "ROLL BACK"
  115. }
  116. func (db *Base) SupportDropIfExists() bool {
  117. return true
  118. }
  119. func (db *Base) DropTableSql(tableName string) string {
  120. quote := db.dialect.Quote
  121. return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName))
  122. }
  123. func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
  124. db.LogSQL(query, args)
  125. rows, err := db.DB().Query(query, args...)
  126. if err != nil {
  127. return false, err
  128. }
  129. defer rows.Close()
  130. if rows.Next() {
  131. return true, nil
  132. }
  133. return false, nil
  134. }
  135. func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
  136. query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
  137. query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
  138. return db.HasRecords(query, db.DbName, tableName, colName)
  139. }
  140. /*
  141. func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error {
  142. sql, args := db.dialect.TableCheckSql(tableName)
  143. rows, err := db.DB().Query(sql, args...)
  144. if db.Logger != nil {
  145. db.Logger.Info("[sql]", sql, args)
  146. }
  147. if err != nil {
  148. return err
  149. }
  150. defer rows.Close()
  151. if rows.Next() {
  152. return nil
  153. }
  154. sql = db.dialect.CreateTableSql(table, tableName, storeEngine, charset)
  155. _, err = db.DB().Exec(sql)
  156. if db.Logger != nil {
  157. db.Logger.Info("[sql]", sql)
  158. }
  159. return err
  160. }*/
  161. func (db *Base) CreateIndexSql(tableName string, index *Index) string {
  162. quote := db.dialect.Quote
  163. var unique string
  164. var idxName string
  165. if index.Type == UniqueType {
  166. unique = " UNIQUE"
  167. }
  168. idxName = index.XName(tableName)
  169. return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
  170. quote(idxName), quote(tableName),
  171. quote(strings.Join(index.Cols, quote(","))))
  172. }
  173. func (db *Base) DropIndexSql(tableName string, index *Index) string {
  174. quote := db.dialect.Quote
  175. var name string
  176. if index.IsRegular {
  177. name = index.XName(tableName)
  178. } else {
  179. name = index.Name
  180. }
  181. return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
  182. }
  183. func (db *Base) ModifyColumnSql(tableName string, col *Column) string {
  184. return fmt.Sprintf("alter table %s MODIFY COLUMN %s", tableName, col.StringNoPk(db.dialect))
  185. }
  186. func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset string) string {
  187. var sql string
  188. sql = "CREATE TABLE IF NOT EXISTS "
  189. if tableName == "" {
  190. tableName = table.Name
  191. }
  192. sql += b.dialect.Quote(tableName)
  193. sql += " ("
  194. if len(table.ColumnsSeq()) > 0 {
  195. pkList := table.PrimaryKeys
  196. for _, colName := range table.ColumnsSeq() {
  197. col := table.GetColumn(colName)
  198. if col.IsPrimaryKey && len(pkList) == 1 {
  199. sql += col.String(b.dialect)
  200. } else {
  201. sql += col.StringNoPk(b.dialect)
  202. }
  203. sql = strings.TrimSpace(sql)
  204. if b.DriverName() == MYSQL && len(col.Comment) > 0 {
  205. sql += " COMMENT '" + col.Comment + "'"
  206. }
  207. sql += ", "
  208. }
  209. if len(pkList) > 1 {
  210. sql += "PRIMARY KEY ( "
  211. sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
  212. sql += " ), "
  213. }
  214. sql = sql[:len(sql)-2]
  215. }
  216. sql += ")"
  217. if b.dialect.SupportEngine() && storeEngine != "" {
  218. sql += " ENGINE=" + storeEngine
  219. }
  220. if b.dialect.SupportCharset() {
  221. if len(charset) == 0 {
  222. charset = b.dialect.URI().Charset
  223. }
  224. if len(charset) > 0 {
  225. sql += " DEFAULT CHARSET " + charset
  226. }
  227. }
  228. return sql
  229. }
  230. func (b *Base) ForUpdateSql(query string) string {
  231. return query + " FOR UPDATE"
  232. }
  233. func (b *Base) LogSQL(sql string, args []interface{}) {
  234. if b.logger != nil && b.logger.IsShowSQL() {
  235. if len(args) > 0 {
  236. b.logger.Infof("[SQL] %v %v", sql, args)
  237. } else {
  238. b.logger.Infof("[SQL] %v", sql)
  239. }
  240. }
  241. }
  242. func (b *Base) SetParams(params map[string]string) {
  243. }
  244. var (
  245. dialects = map[string]func() Dialect{}
  246. )
  247. // RegisterDialect register database dialect
  248. func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
  249. if dialectFunc == nil {
  250. panic("core: Register dialect is nil")
  251. }
  252. dialects[strings.ToLower(string(dbName))] = dialectFunc // !nashtsai! allow override dialect
  253. }
  254. // QueryDialect query if registed database dialect
  255. func QueryDialect(dbName DbType) Dialect {
  256. if d, ok := dialects[strings.ToLower(string(dbName))]; ok {
  257. return d()
  258. }
  259. return nil
  260. }