func Open(cfg *config.Config) (*Nodb, error) { if len(cfg.DataDir) == 0 { cfg.DataDir = config.DefaultDataDir } ldb, err := store.Open(cfg) if err != nil { return nil, err } l := new(Nodb) l.quit = make(chan struct{}) l.jobs = new(sync.WaitGroup) l.ldb = ldb if cfg.BinLog.MaxFileNum > 0 && cfg.BinLog.MaxFileSize > 0 { l.binlog, err = NewBinLog(cfg) if err != nil { return nil, err } } else { l.binlog = nil } for i := uint8(0); i < MaxDBNumber; i++ { l.dbs[i] = l.newDB(i) } l.activeExpireCycle() return l, nil }
func TestBinLog(t *testing.T) { cfg := new(config.Config) cfg.BinLog.MaxFileNum = 1 cfg.BinLog.MaxFileSize = 1024 cfg.DataDir = "/tmp/ledis_binlog" os.RemoveAll(cfg.DataDir) b, err := NewBinLog(cfg) if err != nil { t.Fatal(err) } if err := b.Log(make([]byte, 1024)); err != nil { t.Fatal(err) } if err := b.Log(make([]byte, 1024)); err != nil { t.Fatal(err) } if fs, err := ioutil.ReadDir(b.LogPath()); err != nil { t.Fatal(err) } else if len(fs) != 2 { t.Fatal(len(fs)) } }
func TestDump(t *testing.T) { cfgM := new(config.Config) cfgM.DataDir = "/tmp/test_ledis_master" os.RemoveAll(cfgM.DataDir) master, err := Open(cfgM) if err != nil { t.Fatal(err) } cfgS := new(config.Config) cfgS.DataDir = "/tmp/test_ledis_slave" os.RemoveAll(cfgM.DataDir) var slave *Nodb if slave, err = Open(cfgS); err != nil { t.Fatal(err) } db, _ := master.Select(0) db.Set([]byte("a"), []byte("1")) db.Set([]byte("b"), []byte("2")) db.Set([]byte("c"), []byte("3")) if err := master.DumpFile("/tmp/testdb.dump"); err != nil { t.Fatal(err) } if _, err := slave.LoadDumpFile("/tmp/testdb.dump"); err != nil { t.Fatal(err) } it := master.ldb.RangeLimitIterator(nil, nil, store.RangeClose, 0, -1) for ; it.Valid(); it.Next() { key := it.Key() value := it.Value() if v, err := slave.ldb.Get(key); err != nil { t.Fatal(err) } else if !bytes.Equal(v, value) { t.Fatal("load dump error") } } }
// Init initializes nodb session provider. func (p *NodbProvider) Init(expire int64, configs string) error { p.expire = expire cfg := new(config.Config) cfg.DataDir = configs dbs, err := nodb.Open(cfg) if err != nil { return fmt.Errorf("session/nodb: error opening db: %v", err) } p.c, err = dbs.Select(0) return err }
func (c *NodbCacher) new() (err error) { if c.db != nil { return ErrDBExists } cfg := new(config.Config) cfg.DataDir = c.filepath c.dbs, err = nodb.Open(cfg) if err != nil { return fmt.Errorf("cache/nodb: error opening db: %v", err) } c.db, err = c.dbs.Select(0) return err }
func getTestDB() *DB { f := func() { cfg := new(config.Config) cfg.DataDir = "/tmp/test_ledis" // cfg.BinLog.MaxFileSize = 1073741824 // cfg.BinLog.MaxFileNum = 3 os.RemoveAll(cfg.DataDir) var err error testLedis, err = Open(cfg) if err != nil { println(err.Error()) panic(err) } } testLedisOnce.Do(f) db, _ := testLedis.Select(0) return db }
func TestStore(t *testing.T) { cfg := new(config.Config) cfg.DataDir = "/tmp/testdb" cfg.LMDB.MapSize = 10 * 1024 * 1024 ns := driver.ListStores() for _, s := range ns { cfg.DBName = s os.RemoveAll(getStorePath(cfg)) db, err := Open(cfg) if err != nil { t.Fatal(err) } testStore(db, t) testClear(db, t) testTx(db, t) db.Close() } }
func TestReplication(t *testing.T) { var master *Nodb var slave *Nodb var err error cfgM := new(config.Config) cfgM.DataDir = "/tmp/test_repl/master" cfgM.BinLog.MaxFileNum = 10 cfgM.BinLog.MaxFileSize = 50 os.RemoveAll(cfgM.DataDir) master, err = Open(cfgM) if err != nil { t.Fatal(err) } cfgS := new(config.Config) cfgS.DataDir = "/tmp/test_repl/slave" os.RemoveAll(cfgS.DataDir) slave, err = Open(cfgS) if err != nil { t.Fatal(err) } db, _ := master.Select(0) db.Set([]byte("a"), []byte("value")) db.Set([]byte("b"), []byte("value")) db.Set([]byte("c"), []byte("value")) if tx, err := db.Begin(); err == nil { tx.HSet([]byte("a"), []byte("1"), []byte("value")) tx.HSet([]byte("b"), []byte("2"), []byte("value")) tx.HSet([]byte("c"), []byte("3"), []byte("value")) tx.Commit() } else { db.HSet([]byte("a"), []byte("1"), []byte("value")) db.HSet([]byte("b"), []byte("2"), []byte("value")) db.HSet([]byte("c"), []byte("3"), []byte("value")) } m, _ := db.Multi() m.Set([]byte("a1"), []byte("value")) m.Set([]byte("b1"), []byte("value")) m.Set([]byte("c1"), []byte("value")) m.Close() for _, name := range master.binlog.LogNames() { p := path.Join(master.binlog.LogPath(), name) err = slave.ReplicateFromBinLog(p) if err != nil { t.Fatal(err) } } if err = checkLedisEqual(master, slave); err != nil { t.Fatal(err) } slave.FlushAll() db.Set([]byte("a1"), []byte("value")) db.Set([]byte("b1"), []byte("value")) db.Set([]byte("c1"), []byte("value")) db.HSet([]byte("a1"), []byte("1"), []byte("value")) db.HSet([]byte("b1"), []byte("2"), []byte("value")) db.HSet([]byte("c1"), []byte("3"), []byte("value")) if tx, err := db.Begin(); err == nil { tx.HSet([]byte("a1"), []byte("1"), []byte("value1")) tx.HSet([]byte("b1"), []byte("2"), []byte("value1")) tx.HSet([]byte("c1"), []byte("3"), []byte("value1")) tx.Rollback() } info := new(BinLogAnchor) info.LogFileIndex = 1 info.LogPos = 0 var buf bytes.Buffer var n int for { buf.Reset() n, err = master.ReadEventsTo(info, &buf) if err != nil { t.Fatal(err) } else if info.LogFileIndex == -1 { t.Fatal("invalid log file index -1") } else if info.LogFileIndex == 0 { t.Fatal("invalid log file index 0") } else { if err = slave.ReplicateFromReader(&buf); err != nil { t.Fatal(err) } if n == 0 { break } } } if err = checkLedisEqual(master, slave); err != nil { t.Fatal(err) } }