diff --git a/database/database.go b/database/database.go index d407361..6610136 100644 --- a/database/database.go +++ b/database/database.go @@ -6,6 +6,7 @@ package database import ( "database/sql" + "errors" "fmt" "gomark/logging" "gomark/tree" @@ -78,16 +79,24 @@ type DsnOptions map[string]string type DBError struct { // Database object where error occured - D *DB + DBName string // Error that occured Err error } -func (e DBError) Error() string { - return fmt.Sprintf("<%s>: %s", e.D.Name, e.Err) +func DBErr(dbName string, err error) DBError { + return DBError{Err: err} } +func (e DBError) Error() string { + return fmt.Sprintf("<%s>: %s", e.DBName, e.Err) +} + +var ( + ErrVfsLocked = errors.New("vfs locked") +) + type Opener interface { Open(driver string, dsn string) error } @@ -208,6 +217,7 @@ func New(name string, dbPath string, dbFormat string, opts ...DsnOptions) *DB { } +//TODO: try unlock at the browser level ! func (db *DB) tryUnlock() error { log.Debug("Unlocking ...") @@ -239,12 +249,11 @@ func (db *DB) Init() (*DB, error) { locked, err := db.Locked() if err != nil { - return nil, DBError{D: db, Err: err} + return nil, DBError{DBName: db.Name, Err: err} } if locked { - log.Warningf("<%s> is locked !", db.Path) - db.tryUnlock() + return nil, DBErr(db.Name, ErrVfsLocked) } } @@ -256,13 +265,13 @@ func (db *DB) Init() (*DB, error) { // Secondary lock check provided by sqlx Ping() method if err != nil && sqlErr.Code == sqlite3.ErrBusy { - return nil, DBError{D: db, Err: err} + return nil, DBError{DBName: db.Name, Err: err} } // Return all other errors if err != nil { - return nil, DBError{D: db, Err: err} + return nil, DBError{DBName: db.Name, Err: err} } return db, nil @@ -273,20 +282,20 @@ func (db *DB) InitSchema() error { // Populate db schema tx, err := db.Handle.Begin() if err != nil { - return DBError{D: db, Err: err} + return DBError{DBName: db.Name, Err: err} } stmt, err := tx.Prepare(QCreateGomarkDBSchema) if err != nil { - return DBError{D: db, Err: err} + return DBError{DBName: db.Name, Err: err} } if _, err = stmt.Exec(); err != nil { - return DBError{D: db, Err: err} + return DBError{DBName: db.Name, Err: err} } if err = tx.Commit(); err != nil { - return DBError{D: db, Err: err} + return DBError{DBName: db.Name, Err: err} } log.Debugf("<%s> initialized", db.Name) diff --git a/database/database_test.go b/database/database_test.go index 20e5821..d2dc61e 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -72,11 +72,11 @@ func TestNew(t *testing.T) { } type AlwaysLockedChecker struct { - err error + locked bool } func (f *AlwaysLockedChecker) Locked() (bool, error) { - return true, nil + return f.locked, nil } type LockedSQLXOpener struct { @@ -99,42 +99,57 @@ func TestInitLocked(t *testing.T) { err: sqlite3.Error{Code: sqlite3.ErrBusy}, } - lockChecker := &AlwaysLockedChecker{} + lockCheckerTrue := &AlwaysLockedChecker{locked: true} + lockCheckerFalse := &AlwaysLockedChecker{locked: false} - testDB := &DB{ - Name: "test", - Path: "file:test", - EngineMode: DriverDefault, - SQLXOpener: lockedOpener, - Type: DBTypeRegularFile, - LockChecker: lockChecker, - } + t.Run("VFSLockChecker", func(t *testing.T) { - _, err := testDB.Init() + testDB := &DB{ + Name: "test", + Path: "file:test", + EngineMode: DriverDefault, + LockChecker: lockCheckerTrue, + SQLXOpener: lockedOpener, + Type: DBTypeRegularFile, + } - if err != nil { - t.Log(err) + _, err := testDB.Init() - t.Run("VFSLockChecker", func(t *testing.T) { + if err == nil { + t.Fail() + } - t.Error("TODO") + if err != DBErr(testDB.Name, ErrVfsLocked) { + t.Fail() + } - }) + }) - t.Run("SQLXLockChecker", func(t *testing.T) { + t.Run("SQLXLockChecker", func(t *testing.T) { - e, _ := err.(DBError).Err.(sqlite3.Error) + testDB := &DB{ + Name: "test", + Path: "file:test", + EngineMode: DriverDefault, + LockChecker: lockCheckerFalse, + SQLXOpener: lockedOpener, + Type: DBTypeRegularFile, + } - if e.Code == sqlite3.ErrBusy { - t.Error("should handle locked database") - } else { - t.Fail() - } - t.Error("TODO") + _, err := testDB.Init() - }) + if err == nil { + t.Fail() + } + + e, _ := err.(DBError).Err.(sqlite3.Error) + + if e.Code != sqlite3.ErrBusy { + t.Fail() + } + + }) - } } func TestGomarkDBCeate(t *testing.T) { diff --git a/firefox.go b/firefox.go index df44198..cd12219 100644 --- a/firefox.go +++ b/firefox.go @@ -140,6 +140,8 @@ func NewFFBrowser() IBrowser { bookmarkPath, database.DBTypeFileDSN, opts).Init() if err != nil { + + //Check Lock Error log.Fatal(err) }