diff --git a/caches/leveldb.go b/caches/leveldb.go index d1a177ad..f2f71d84 100644 --- a/caches/leveldb.go +++ b/caches/leveldb.go @@ -19,6 +19,7 @@ type LevelDBStore struct { var _ CacheStore = &LevelDBStore{} +// NewLevelDBStore creates a leveldb store func NewLevelDBStore(dbfile string) (*LevelDBStore, error) { db := &LevelDBStore{} h, err := leveldb.OpenFile(dbfile, nil) @@ -29,6 +30,7 @@ func NewLevelDBStore(dbfile string) (*LevelDBStore, error) { return db, nil } +// Put implements CacheStore func (s *LevelDBStore) Put(key string, value interface{}) error { val, err := Encode(value) if err != nil { @@ -50,6 +52,7 @@ func (s *LevelDBStore) Put(key string, value interface{}) error { return err } +// Get implements CacheStore func (s *LevelDBStore) Get(key string) (interface{}, error) { data, err := s.store.Get([]byte(key), nil) if err != nil { @@ -75,6 +78,7 @@ func (s *LevelDBStore) Get(key string) (interface{}, error) { return s.v, err } +// Del implements CacheStore func (s *LevelDBStore) Del(key string) error { err := s.store.Delete([]byte(key), nil) if err != nil { @@ -89,6 +93,7 @@ func (s *LevelDBStore) Del(key string) error { return err } +// Close implements CacheStore func (s *LevelDBStore) Close() { s.store.Close() } diff --git a/caches/manager.go b/caches/manager.go index 05045210..89a14106 100644 --- a/caches/manager.go +++ b/caches/manager.go @@ -6,6 +6,7 @@ package caches import "sync" +// Manager represents a cache manager type Manager struct { cacher Cacher disableGlobalCache bool @@ -14,6 +15,7 @@ type Manager struct { cacherLock sync.RWMutex } +// NewManager creates a cache manager func NewManager() *Manager { return &Manager{ cachers: make(map[string]Cacher), @@ -27,12 +29,14 @@ func (mgr *Manager) SetDisableGlobalCache(disable bool) { } } +// SetCacher set cacher of table func (mgr *Manager) SetCacher(tableName string, cacher Cacher) { mgr.cacherLock.Lock() mgr.cachers[tableName] = cacher mgr.cacherLock.Unlock() } +// GetCacher returns a cache of a table func (mgr *Manager) GetCacher(tableName string) Cacher { var cacher Cacher var ok bool diff --git a/contexts/hook.go b/contexts/hook.go index 71ad8e87..70f114dd 100644 --- a/contexts/hook.go +++ b/contexts/hook.go @@ -31,6 +31,7 @@ func NewContextHook(ctx context.Context, sql string, args []interface{}) *Contex } } +// End finish the hook invokation func (c *ContextHook) End(ctx context.Context, result sql.Result, err error) { c.Ctx = ctx c.Result = result @@ -38,19 +39,23 @@ func (c *ContextHook) End(ctx context.Context, result sql.Result, err error) { c.ExecuteTime = time.Now().Sub(c.start) } +// Hook represents a hook behaviour type Hook interface { BeforeProcess(c *ContextHook) (context.Context, error) AfterProcess(c *ContextHook) error } +// Hooks implements Hook interface but contains multiple Hook type Hooks struct { hooks []Hook } +// AddHook adds a Hook func (h *Hooks) AddHook(hooks ...Hook) { h.hooks = append(h.hooks, hooks...) } +// BeforeProcess invoked before execute the process func (h *Hooks) BeforeProcess(c *ContextHook) (context.Context, error) { ctx := c.Ctx for _, h := range h.hooks { @@ -63,6 +68,7 @@ func (h *Hooks) BeforeProcess(c *ContextHook) (context.Context, error) { return ctx, nil } +// AfterProcess invoked after exetue the process func (h *Hooks) AfterProcess(c *ContextHook) error { firstErr := c.Err for _, h := range h.hooks { diff --git a/dialects/dialect.go b/dialects/dialect.go index d9a640a4..b02ec4ae 100644 --- a/dialects/dialect.go +++ b/dialects/dialect.go @@ -79,32 +79,34 @@ type Base struct { quoter schemas.Quoter } -func (b *Base) Quoter() schemas.Quoter { - return b.quoter +// Quoter returns the current database Quoter +func (db *Base) Quoter() schemas.Quoter { + return db.quoter } -func (b *Base) Init(dialect Dialect, uri *URI) error { - b.dialect, b.uri = dialect, uri +// Init initialize the dialect +func (db *Base) Init(dialect Dialect, uri *URI) error { + db.dialect, db.uri = dialect, uri return nil } -func (b *Base) URI() *URI { - return b.uri +// URI returns the uri of database +func (db *Base) URI() *URI { + return db.uri } -func (b *Base) DBType() schemas.DBType { - return b.uri.DBType -} - -func (b *Base) FormatBytes(bs []byte) string { +// FormatBytes formats bytes +func (db *Base) FormatBytes(bs []byte) string { return fmt.Sprintf("0x%x", bs) } +// DropTableSQL returns drop table SQL func (db *Base) DropTableSQL(tableName string) (string, bool) { quote := db.dialect.Quoter().Quote return fmt.Sprintf("DROP TABLE IF EXISTS %s", quote(tableName)), true } +// HasRecords returns true if the SQL has records returned func (db *Base) HasRecords(queryer core.Queryer, ctx context.Context, query string, args ...interface{}) (bool, error) { rows, err := queryer.QueryContext(ctx, query, args...) if err != nil { @@ -118,6 +120,7 @@ func (db *Base) HasRecords(queryer core.Queryer, ctx context.Context, query stri return false, nil } +// IsColumnExist returns true if the column of the table exist func (db *Base) IsColumnExist(queryer core.Queryer, ctx context.Context, tableName, colName string) (bool, error) { quote := db.dialect.Quoter().Quote query := fmt.Sprintf( @@ -132,11 +135,13 @@ func (db *Base) IsColumnExist(queryer core.Queryer, ctx context.Context, tableNa return db.HasRecords(queryer, ctx, query, db.uri.DBName, tableName, colName) } +// AddColumnSQL returns a SQL to add a column func (db *Base) AddColumnSQL(tableName string, col *schemas.Column) string { s, _ := ColumnString(db.dialect, col, true) return fmt.Sprintf("ALTER TABLE %v ADD %v", db.dialect.Quoter().Quote(tableName), s) } +// CreateIndexSQL returns a SQL to create index func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string { quoter := db.dialect.Quoter() var unique string @@ -150,6 +155,7 @@ func (db *Base) CreateIndexSQL(tableName string, index *schemas.Index) string { quoter.Join(index.Cols, ",")) } +// DropIndexSQL returns a SQL to drop index func (db *Base) DropIndexSQL(tableName string, index *schemas.Index) string { quote := db.dialect.Quoter().Quote var name string @@ -161,16 +167,19 @@ func (db *Base) DropIndexSQL(tableName string, index *schemas.Index) string { return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName)) } +// ModifyColumnSQL returns a SQL to modify SQL func (db *Base) ModifyColumnSQL(tableName string, col *schemas.Column) string { s, _ := ColumnString(db.dialect, col, false) return fmt.Sprintf("ALTER TABLE %s MODIFY COLUMN %s", tableName, s) } -func (b *Base) ForUpdateSQL(query string) string { +// ForUpdateSQL returns for updateSQL +func (db *Base) ForUpdateSQL(query string) string { return query + " FOR UPDATE" } -func (b *Base) SetParams(params map[string]string) { +// SetParams set params +func (db *Base) SetParams(params map[string]string) { } var ( diff --git a/engine.go b/engine.go index ee98ed05..384928d6 100644 --- a/engine.go +++ b/engine.go @@ -1278,6 +1278,7 @@ func (engine *Engine) SetSchema(schema string) { engine.dialect.URI().SetSchema(schema) } +// AddHook adds a context Hook func (engine *Engine) AddHook(hook contexts.Hook) { engine.db.AddHook(hook) } @@ -1293,7 +1294,7 @@ func (engine *Engine) tbNameWithSchema(v string) string { return dialects.TableNameWithSchema(engine.dialect, v) } -// ContextHook creates a session with the context +// Context creates a session with the context func (engine *Engine) Context(ctx context.Context) *Session { session := engine.NewSession() session.isAutoClose = true diff --git a/engine_group.go b/engine_group.go index 3e91cbd6..3569690b 100644 --- a/engine_group.go +++ b/engine_group.go @@ -79,7 +79,7 @@ func (eg *EngineGroup) Close() error { return nil } -// ContextHook returned a group session +// Context returned a group session func (eg *EngineGroup) Context(ctx context.Context) *Session { sess := eg.NewSession() sess.isAutoClose = true @@ -144,6 +144,7 @@ func (eg *EngineGroup) SetLogger(logger interface{}) { } } +// AddHook adds Hook func (eg *EngineGroup) AddHook(hook contexts.Hook) { eg.Engine.AddHook(hook) for i := 0; i < len(eg.slaves); i++ { diff --git a/integrations/engine_test.go b/integrations/engine_test.go index 1e2e9f4a..3b843f16 100644 --- a/integrations/engine_test.go +++ b/integrations/engine_test.go @@ -190,7 +190,7 @@ func TestSetSchema(t *testing.T) { func TestImport(t *testing.T) { if testEngine.Dialect().URI().DBType != schemas.MYSQL { - t.SkipNow() + t.Skip() return } sess := testEngine.NewSession() diff --git a/integrations/tests.go b/integrations/tests.go index 840b1020..512f3962 100644 --- a/integrations/tests.go +++ b/integrations/tests.go @@ -8,6 +8,7 @@ import ( "database/sql" "flag" "fmt" + "net/url" "os" "strings" "testing" @@ -97,6 +98,13 @@ func createEngine(dbType, connStr string) error { return fmt.Errorf("db.Exec: %v", err) } db.Close() + case schemas.SQLITE, "sqlite": + u, err := url.Parse(connStr) + if err != nil { + return err + } + connStr = u.Path + *ignoreSelectUpdate = true default: *ignoreSelectUpdate = true } @@ -164,10 +172,12 @@ func createEngine(dbType, connStr string) error { return nil } +// PrepareEngine prepare tests ORM engine func PrepareEngine() error { return createEngine(dbType, connString) } +// MainTest the tests entrance func MainTest(m *testing.M) { flag.Parse() diff --git a/internal/json/json.go b/internal/json/json.go index c9a2eb4e..ef52f51f 100644 --- a/internal/json/json.go +++ b/internal/json/json.go @@ -6,15 +6,15 @@ package json import "encoding/json" -// JSONInterface represents an interface to handle json data -type JSONInterface interface { +// Interface represents an interface to handle json data +type Interface interface { Marshal(v interface{}) ([]byte, error) Unmarshal(data []byte, v interface{}) error } var ( // DefaultJSONHandler default json handler - DefaultJSONHandler JSONInterface = StdJSON{} + DefaultJSONHandler Interface = StdJSON{} ) // StdJSON implements JSONInterface via encoding/json diff --git a/internal/utils/name.go b/internal/utils/name.go index f5fc3ff7..840dd9e8 100644 --- a/internal/utils/name.go +++ b/internal/utils/name.go @@ -8,6 +8,7 @@ import ( "fmt" ) +// IndexName returns index name func IndexName(tableName, idxName string) string { return fmt.Sprintf("IDX_%v_%v", tableName, idxName) } diff --git a/internal/utils/reflect.go b/internal/utils/reflect.go index 3dad6bfe..7973d4d3 100644 --- a/internal/utils/reflect.go +++ b/internal/utils/reflect.go @@ -8,6 +8,7 @@ import ( "reflect" ) +// ReflectValue returns value of a bean func ReflectValue(bean interface{}) reflect.Value { return reflect.Indirect(reflect.ValueOf(bean)) } diff --git a/internal/utils/sql.go b/internal/utils/sql.go index 5e68c4a4..369ca2b8 100644 --- a/internal/utils/sql.go +++ b/internal/utils/sql.go @@ -8,6 +8,7 @@ import ( "strings" ) +// IsSubQuery returns true if it contains a sub query func IsSubQuery(tbName string) bool { const selStr = "select" if len(tbName) <= len(selStr)+1 { diff --git a/internal/utils/strings.go b/internal/utils/strings.go index 72466705..86469c0f 100644 --- a/internal/utils/strings.go +++ b/internal/utils/strings.go @@ -8,10 +8,12 @@ import ( "strings" ) +// IndexNoCase index a string in a string with no care of capitalize func IndexNoCase(s, sep string) int { return strings.Index(strings.ToLower(s), strings.ToLower(sep)) } +// SplitNoCase split a string by a seperator with no care of capitalize func SplitNoCase(s, sep string) []string { idx := IndexNoCase(s, sep) if idx < 0 { @@ -20,6 +22,7 @@ func SplitNoCase(s, sep string) []string { return strings.Split(s, s[idx:idx+len(sep)]) } +// SplitNNoCase split n by a seperator with no care of capitalize func SplitNNoCase(s, sep string, n int) []string { idx := IndexNoCase(s, sep) if idx < 0 { diff --git a/internal/utils/zero.go b/internal/utils/zero.go index 8f033c60..007e3c33 100644 --- a/internal/utils/zero.go +++ b/internal/utils/zero.go @@ -9,6 +9,7 @@ import ( "time" ) +// Zeroable represents an interface which could know if it's a zero value type Zeroable interface { IsZero() bool } @@ -21,39 +22,39 @@ func IsZero(k interface{}) bool { return true } - switch k.(type) { + switch t := k.(type) { case int: - return k.(int) == 0 + return t == 0 case int8: - return k.(int8) == 0 + return t == 0 case int16: - return k.(int16) == 0 + return t == 0 case int32: - return k.(int32) == 0 + return t == 0 case int64: - return k.(int64) == 0 + return t == 0 case uint: - return k.(uint) == 0 + return t == 0 case uint8: - return k.(uint8) == 0 + return t == 0 case uint16: - return k.(uint16) == 0 + return t == 0 case uint32: - return k.(uint32) == 0 + return t == 0 case uint64: - return k.(uint64) == 0 + return t == 0 case float32: - return k.(float32) == 0 + return t == 0 case float64: - return k.(float64) == 0 + return t == 0 case bool: - return k.(bool) == false + return !t case string: - return k.(string) == "" + return t == "" case *time.Time: - return k.(*time.Time) == nilTime || IsTimeZero(*k.(*time.Time)) + return t == nilTime || IsTimeZero(*t) case time.Time: - return IsTimeZero(k.(time.Time)) + return IsTimeZero(t) case Zeroable: return k.(Zeroable) == nil || k.(Zeroable).IsZero() case reflect.Value: // for go version less than 1.13 because reflect.Value has no method IsZero @@ -65,6 +66,7 @@ func IsZero(k interface{}) bool { var zeroType = reflect.TypeOf((*Zeroable)(nil)).Elem() +// IsValueZero returns true if the reflect Value is a zero func IsValueZero(v reflect.Value) bool { switch v.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice: @@ -88,6 +90,7 @@ func IsValueZero(v reflect.Value) bool { return false } +// IsStructZero returns true if the Value is a struct and all fields is zero func IsStructZero(v reflect.Value) bool { if !v.IsValid() || v.NumField() == 0 { return true @@ -120,6 +123,7 @@ func IsStructZero(v reflect.Value) bool { return true } +// IsArrayZero returns true is a slice of array is zero func IsArrayZero(v reflect.Value) bool { if !v.IsValid() || v.Len() == 0 { return true @@ -134,11 +138,13 @@ func IsArrayZero(v reflect.Value) bool { return true } +// represents all zero times const ( ZeroTime0 = "0000-00-00 00:00:00" ZeroTime1 = "0001-01-01 00:00:00" ) +// IsTimeZero return true if a time is zero func IsTimeZero(t time.Time) bool { return t.IsZero() || t.Format("2006-01-02 15:04:05") == ZeroTime0 || t.Format("2006-01-02 15:04:05") == ZeroTime1 diff --git a/migrate/migrate.go b/migrate/migrate.go index 82c58f90..19b4afe0 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -110,10 +110,7 @@ func (m *Migrate) RollbackLast() error { return err } - if err := m.RollbackMigration(lastRunnedMigration); err != nil { - return err - } - return nil + return m.RollbackMigration(lastRunnedMigration) } func (m *Migrate) getLastRunnedMigration() (*Migration, error) { diff --git a/migrate/migrate_test.go b/migrate/migrate_test.go index 19554f7e..3d7aa189 100644 --- a/migrate/migrate_test.go +++ b/migrate/migrate_test.go @@ -106,10 +106,7 @@ func TestInitSchema(t *testing.T) { if err := tx.Sync2(&Person{}); err != nil { return err } - if err := tx.Sync2(&Pet{}); err != nil { - return err - } - return nil + return tx.Sync2(&Pet{}) }) err = m.Migrate() diff --git a/session.go b/session.go index 17abd453..d5ccb6dc 100644 --- a/session.go +++ b/session.go @@ -169,6 +169,7 @@ func (session *Session) db() *core.DB { return session.engine.db } +// Engine returns session Engine func (session *Session) Engine() *Engine { return session.engine } @@ -895,7 +896,7 @@ func (session *Session) incrVersionFieldValue(fieldValue *reflect.Value) { } } -// ContextHook sets the context on this session +// Context sets the context on this session func (session *Session) Context(ctx context.Context) *Session { session.ctx = ctx return session diff --git a/session_get.go b/session_get.go index 6e65ea2f..e303176d 100644 --- a/session_get.go +++ b/session_get.go @@ -17,6 +17,7 @@ import ( ) var ( + // ErrObjectIsNil return error of object is nil ErrObjectIsNil = errors.New("object should not be nil") ) diff --git a/session_tx.go b/session_tx.go index 33ef72c6..8763784c 100644 --- a/session_tx.go +++ b/session_tx.go @@ -85,7 +85,7 @@ func (session *Session) Commit() error { return nil } -// if current session is in a transaction +// IsInTx if current session is in a transaction func (session *Session) IsInTx() bool { return !session.isAutoCommit }