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.

129 lines
4.0 KiB

  1. package dameng
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "github.com/seaweedfs/seaweedfs/weed/glog"
  7. "strings"
  8. "time"
  9. _ "gitee.com/chunanyong/dm"
  10. "github.com/seaweedfs/seaweedfs/weed/filer"
  11. "github.com/seaweedfs/seaweedfs/weed/filer/abstract_sql"
  12. "github.com/seaweedfs/seaweedfs/weed/util"
  13. )
  14. const (
  15. CONNECTION_URL_PATTERN = "dm://%s:%s@%s:%d?schema=%s"
  16. )
  17. func init() {
  18. filer.Stores = append(filer.Stores, &DamengStore{})
  19. }
  20. type DamengStore struct {
  21. abstract_sql.AbstractSqlStore
  22. }
  23. func (store *DamengStore) GetName() string {
  24. return "dameng"
  25. }
  26. func (store *DamengStore) Initialize(configuration util.Configuration, prefix string) (err error) {
  27. return store.initialize(
  28. configuration.GetString(prefix+"dsn"),
  29. configuration.GetString(prefix+"upsertQuery"),
  30. configuration.GetBool(prefix+"enableUpsert"),
  31. configuration.GetString(prefix+"username"),
  32. configuration.GetString(prefix+"password"),
  33. configuration.GetString(prefix+"hostname"),
  34. configuration.GetInt(prefix+"port"),
  35. configuration.GetString(prefix+"database"),
  36. configuration.GetInt(prefix+"connection_max_idle"),
  37. configuration.GetInt(prefix+"connection_max_open"),
  38. configuration.GetInt(prefix+"connection_max_lifetime_seconds"),
  39. configuration.GetBool(prefix+"interpolateParams"),
  40. )
  41. }
  42. func (store *DamengStore) initialize(dsn string, upsertQuery string, enableUpsert bool, user, password, hostname string, port int, database string, maxIdle, maxOpen,
  43. maxLifetimeSeconds int, interpolateParams bool) (err error) {
  44. store.SupportBucketTable = false
  45. if !enableUpsert {
  46. upsertQuery = ""
  47. }
  48. store.SqlGenerator = &SqlGenDameng{
  49. CreateTableSqlTemplate: "",
  50. DropTableSqlTemplate: "DROP TABLE `%s`",
  51. UpsertQueryTemplate: upsertQuery,
  52. }
  53. dsn = fmt.Sprintf(CONNECTION_URL_PATTERN, user, password, hostname, port, database)
  54. var dbErr error
  55. store.DB, dbErr = sql.Open("dm", dsn)
  56. if dbErr != nil {
  57. store.DB.Close()
  58. store.DB = nil
  59. return fmt.Errorf("can not connect to %s error:%v", strings.ReplaceAll(dsn, "", "<ADAPTED>"), err)
  60. }
  61. store.DB.SetMaxIdleConns(maxIdle)
  62. store.DB.SetMaxOpenConns(maxOpen)
  63. store.DB.SetConnMaxLifetime(time.Duration(maxLifetimeSeconds) * time.Second)
  64. if err = store.DB.Ping(); err != nil {
  65. return fmt.Errorf("connect to %s error:%v", strings.ReplaceAll(dsn, "", "<ADAPTED>"), err)
  66. }
  67. return nil
  68. }
  69. func (store *DamengStore) ListDirectoryEntries(ctx context.Context, dirPath util.FullPath, startFileName string, includeStartFile bool, limit int64, eachEntryFunc filer.ListEachEntryFunc) (lastFileName string, err error) {
  70. return store.ListDirectoryPrefixedEntries(ctx, dirPath, startFileName, includeStartFile, limit, "", eachEntryFunc)
  71. }
  72. func (store *DamengStore) ListDirectoryPrefixedEntries(ctx context.Context, dirPath util.FullPath, startFileName string, includeStartFile bool, limit int64, prefix string, eachEntryFunc filer.ListEachEntryFunc) (lastFileName string, err error) {
  73. db, bucket, shortPath, err := store.GetTxOrDB(ctx, dirPath, true)
  74. if err != nil {
  75. return lastFileName, fmt.Errorf("findDB %s : %v", dirPath, err)
  76. }
  77. sqlText := store.GetSqlListExclusive(bucket)
  78. if includeStartFile {
  79. sqlText = store.GetSqlListInclusive(bucket)
  80. }
  81. rows, err := db.QueryContext(ctx, sqlText, util.HashStringToLong(string(shortPath)), string(shortPath), startFileName, string(shortPath), limit)
  82. if err != nil {
  83. return lastFileName, fmt.Errorf("list %s : %v", dirPath, err)
  84. }
  85. defer rows.Close()
  86. for rows.Next() {
  87. var name string
  88. var data []byte
  89. if err = rows.Scan(&name, &data); err != nil {
  90. glog.V(0).Infof("scan %s : %v", dirPath, err)
  91. return lastFileName, fmt.Errorf("scan %s: %v", dirPath, err)
  92. }
  93. lastFileName = name
  94. entry := &filer.Entry{
  95. FullPath: util.NewFullPath(string(dirPath), name),
  96. }
  97. if err = entry.DecodeAttributesAndChunks(util.MaybeDecompressData(data)); err != nil {
  98. glog.V(0).Infof("scan decode %s : %v", entry.FullPath, err)
  99. return lastFileName, fmt.Errorf("scan decode %s : %v", entry.FullPath, err)
  100. }
  101. if !eachEntryFunc(entry) {
  102. break
  103. }
  104. }
  105. return lastFileName, nil
  106. }