github.com/leg100/ots@v0.0.7-0.20210919080622-034055ced4bd/sqlite/sqlite.go (about) 1 /* 2 Package sqlite implements persistent storage using the sqlite database. 3 */ 4 package sqlite 5 6 import ( 7 "github.com/leg100/go-tfe" 8 gormzerolog "github.com/leg100/gorm-zerolog" 9 "github.com/leg100/ots" 10 "github.com/rs/zerolog" 11 driver "gorm.io/driver/sqlite" 12 "gorm.io/gorm" 13 ) 14 15 var models = []interface{}{ 16 &Run{}, 17 &Apply{}, 18 &Plan{}, 19 &ConfigurationVersion{}, 20 &Organization{}, 21 &StateVersion{}, 22 &StateVersionOutput{}, 23 &Workspace{}, 24 } 25 26 type Option func(*gorm.Config) 27 28 func WithZeroLogger(logger *zerolog.Logger) Option { 29 return func(cfg *gorm.Config) { 30 cfg.Logger = &gormzerolog.Logger{Zlog: *logger} 31 } 32 } 33 34 func New(path string, opts ...Option) (*gorm.DB, error) { 35 cfg := &gorm.Config{} 36 for _, o := range opts { 37 o(cfg) 38 } 39 40 db, err := gorm.Open(driver.Open(path), cfg) 41 if err != nil { 42 return nil, err 43 } 44 45 // Avoid "database is locked" errors: 46 // https://github.com/mattn/go-sqlite3/issues/274 47 sqlDB, err := db.DB() 48 if err != nil { 49 return nil, err 50 } 51 sqlDB.SetMaxOpenConns(1) 52 53 // Enable WAL. SQLite performs better with the WAL because it allows 54 // multiple readers to operate while data is being written. 55 db.Exec(`PRAGMA journal_mode = wal;`) 56 57 if err := db.AutoMigrate(models...); err != nil { 58 return nil, err 59 } 60 61 return db, nil 62 } 63 64 // Gorm scopes: https://gorm.io/docs/advanced_query.html#Scopes 65 66 func paginate(opts tfe.ListOptions) func(*gorm.DB) *gorm.DB { 67 return func(db *gorm.DB) *gorm.DB { 68 ots.SanitizeListOptions(&opts) 69 70 offset := (opts.PageNumber - 1) * opts.PageSize 71 72 return db.Offset(offset).Limit(opts.PageSize) 73 } 74 }