gdb_driver_sqlite.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. //
  7. // Note:
  8. // 1. It needs manually import: _ "github.com/mattn/go-sqlite3"
  9. // 2. It does not support Save/Replace features.
  10. package gdb
  11. import (
  12. "context"
  13. "database/sql"
  14. "fmt"
  15. "github.com/gogf/gf/errors/gcode"
  16. "strings"
  17. "github.com/gogf/gf/errors/gerror"
  18. "github.com/gogf/gf/internal/intlog"
  19. "github.com/gogf/gf/os/gfile"
  20. "github.com/gogf/gf/text/gstr"
  21. )
  22. // DriverSqlite is the driver for sqlite database.
  23. type DriverSqlite struct {
  24. *Core
  25. }
  26. // New creates and returns a database object for sqlite.
  27. // It implements the interface of gdb.Driver for extra database driver installation.
  28. func (d *DriverSqlite) New(core *Core, node *ConfigNode) (DB, error) {
  29. return &DriverSqlite{
  30. Core: core,
  31. }, nil
  32. }
  33. // Open creates and returns a underlying sql.DB object for sqlite.
  34. func (d *DriverSqlite) Open(config *ConfigNode) (*sql.DB, error) {
  35. var source string
  36. if config.Link != "" {
  37. source = config.Link
  38. } else {
  39. source = config.Name
  40. }
  41. // It searches the source file to locate its absolute path..
  42. if absolutePath, _ := gfile.Search(source); absolutePath != "" {
  43. source = absolutePath
  44. }
  45. intlog.Printf(d.GetCtx(), "Open: %s", source)
  46. if db, err := sql.Open("sqlite3", source); err == nil {
  47. return db, nil
  48. } else {
  49. return nil, err
  50. }
  51. }
  52. // FilteredLink retrieves and returns filtered `linkInfo` that can be using for
  53. // logging or tracing purpose.
  54. func (d *DriverSqlite) FilteredLink() string {
  55. return d.GetConfig().Link
  56. }
  57. // GetChars returns the security char for this type of database.
  58. func (d *DriverSqlite) GetChars() (charLeft string, charRight string) {
  59. return "`", "`"
  60. }
  61. // DoCommit deals with the sql string before commits it to underlying sql driver.
  62. func (d *DriverSqlite) DoCommit(ctx context.Context, link Link, sql string, args []interface{}) (newSql string, newArgs []interface{}, err error) {
  63. return d.Core.DoCommit(ctx, link, sql, args)
  64. }
  65. // Tables retrieves and returns the tables of current schema.
  66. // It's mainly used in cli tool chain for automatically generating the models.
  67. func (d *DriverSqlite) Tables(ctx context.Context, schema ...string) (tables []string, err error) {
  68. var result Result
  69. link, err := d.SlaveLink(schema...)
  70. if err != nil {
  71. return nil, err
  72. }
  73. result, err = d.DoGetAll(ctx, link, `SELECT NAME FROM SQLITE_MASTER WHERE TYPE='table' ORDER BY NAME`)
  74. if err != nil {
  75. return
  76. }
  77. for _, m := range result {
  78. for _, v := range m {
  79. tables = append(tables, v.String())
  80. }
  81. }
  82. return
  83. }
  84. // TableFields retrieves and returns the fields information of specified table of current schema.
  85. //
  86. // Also see DriverMysql.TableFields.
  87. func (d *DriverSqlite) TableFields(ctx context.Context, table string, schema ...string) (fields map[string]*TableField, err error) {
  88. charL, charR := d.GetChars()
  89. table = gstr.Trim(table, charL+charR)
  90. if gstr.Contains(table, " ") {
  91. return nil, gerror.NewCode(gcode.CodeInvalidParameter, "function TableFields supports only single table operations")
  92. }
  93. useSchema := d.db.GetSchema()
  94. if len(schema) > 0 && schema[0] != "" {
  95. useSchema = schema[0]
  96. }
  97. tableFieldsCacheKey := fmt.Sprintf(
  98. `sqlite_table_fields_%s_%s@group:%s`,
  99. table, useSchema, d.GetGroup(),
  100. )
  101. v := tableFieldsMap.GetOrSetFuncLock(tableFieldsCacheKey, func() interface{} {
  102. var (
  103. result Result
  104. link, err = d.SlaveLink(useSchema)
  105. )
  106. if err != nil {
  107. return nil
  108. }
  109. result, err = d.DoGetAll(ctx, link, fmt.Sprintf(`PRAGMA TABLE_INFO(%s)`, table))
  110. if err != nil {
  111. return nil
  112. }
  113. fields = make(map[string]*TableField)
  114. for i, m := range result {
  115. fields[strings.ToLower(m["name"].String())] = &TableField{
  116. Index: i,
  117. Name: strings.ToLower(m["name"].String()),
  118. Type: strings.ToLower(m["type"].String()),
  119. }
  120. }
  121. return fields
  122. })
  123. if v != nil {
  124. fields = v.(map[string]*TableField)
  125. }
  126. return
  127. }
  128. // DoInsert is not supported in sqlite.
  129. func (d *DriverSqlite) DoInsert(ctx context.Context, link Link, table string, list List, option DoInsertOption) (result sql.Result, err error) {
  130. switch option.InsertOption {
  131. case insertOptionSave:
  132. return nil, gerror.NewCode(gcode.CodeNotSupported, `Save operation is not supported by sqlite driver`)
  133. case insertOptionReplace:
  134. return nil, gerror.NewCode(gcode.CodeNotSupported, `Replace operation is not supported by sqlite driver`)
  135. default:
  136. return d.Core.DoInsert(ctx, link, table, list, option)
  137. }
  138. }