mysql.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package mysql
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "github.com/go-sql-driver/mysql"
  7. "github.com/pkg/errors"
  8. "github.com/usememos/memos/common/log"
  9. "github.com/usememos/memos/server/profile"
  10. "github.com/usememos/memos/store"
  11. )
  12. type DB struct {
  13. db *sql.DB
  14. profile *profile.Profile
  15. config *mysql.Config
  16. }
  17. func NewDB(profile *profile.Profile) (store.Driver, error) {
  18. // Open MySQL connection with parameter.
  19. // multiStatements=true is required for migration.
  20. // See more in: https://github.com/go-sql-driver/mysql#multistatements
  21. dsn := fmt.Sprintf("%s?multiStatements=true", profile.DSN)
  22. var err error
  23. driver := DB{profile: profile}
  24. driver.config, err = mysql.ParseDSN(dsn)
  25. if err != nil {
  26. log.Error(fmt.Sprintf("DSN parse error: %s", dsn))
  27. return nil, errors.New("Parse DSN eroor")
  28. }
  29. driver.db, err = sql.Open("mysql", dsn)
  30. if err != nil {
  31. return nil, errors.Wrapf(err, "failed to open db: %s", profile.DSN)
  32. }
  33. return &driver, nil
  34. }
  35. func (d *DB) GetDB() *sql.DB {
  36. return d.db
  37. }
  38. func (d *DB) Vacuum(ctx context.Context) error {
  39. tx, err := d.db.BeginTx(ctx, nil)
  40. if err != nil {
  41. return err
  42. }
  43. defer tx.Rollback()
  44. if err := vacuumMemo(ctx, tx); err != nil {
  45. return err
  46. }
  47. if err := vacuumResource(ctx, tx); err != nil {
  48. return err
  49. }
  50. if err := vacuumUserSetting(ctx, tx); err != nil {
  51. return err
  52. }
  53. if err := vacuumMemoOrganizer(ctx, tx); err != nil {
  54. return err
  55. }
  56. if err := vacuumMemoRelations(ctx, tx); err != nil {
  57. return err
  58. }
  59. if err := vacuumTag(ctx, tx); err != nil {
  60. // Prevent revive warning.
  61. return err
  62. }
  63. return tx.Commit()
  64. }
  65. func (*DB) BackupTo(context.Context, string) error {
  66. return errors.New("Please use mysqldump to backup")
  67. }
  68. func (d *DB) GetCurrentDBSize(ctx context.Context) (int64, error) {
  69. query := "SELECT SUM(`data_length` + `index_length`) AS `size` " +
  70. " FROM information_schema.TABLES" +
  71. " WHERE `table_schema` = ?" +
  72. " GROUP BY `table_schema`"
  73. rows, err := d.db.QueryContext(ctx, query, d.config.DBName)
  74. if err != nil {
  75. log.Error("Query db size error, make sure you have enough privilege")
  76. return 0, err
  77. }
  78. defer rows.Close()
  79. var size int64
  80. for rows.Next() {
  81. if err := rows.Scan(&size); err != nil {
  82. return 0, err
  83. }
  84. }
  85. if rows.Err() != nil {
  86. return 0, rows.Err()
  87. }
  88. return size, nil
  89. }
  90. func (d *DB) Close() error {
  91. return d.db.Close()
  92. }