Beispiel #1
0
func New(path string) (s *Storage, err error) {
	kyoto := cabinet.New()
	if err = kyoto.Open(path, cabinet.KCOWRITER|cabinet.KCOCREATE); err != nil {
		return
	}

	s = &Storage{
		kyoto:    kyoto,
		counters: make(map[string]*counter),
	}
	s.loadState()
	go s.keepStatePersisted()

	return
}
Beispiel #2
0
func OpenKyotoDB(filename string, writemode bool) (KyotoDB, error) {
	db := KyotoDB{}
	db.kcdb = cabinet.New()
	mode := cabinet.KCOREADER
	if writemode {
		mode = cabinet.KCOWRITER | cabinet.KCOCREATE
	}
	err := db.kcdb.Open(filename, mode)
	if err != nil {
		db.kcdb.Del()
		db.kcdb = nil
		// errors returned by KC are pretty sparse ;-(
		return db, fmt.Errorf("could not open %s: %s", filename, err)
	}
	err = db.checkVersion(
		filename, writemode, CURRENT_VERSION, MIN_VERSION, MAX_VERSION)
	if err != nil {
		db.Close()
		return db, err
	}
	return db, nil
}
Beispiel #3
0
func Test_KyotoDB_checkVersion(t *testing.T) {
	cleanup := testutils.Chtemp()
	defer cleanup()

	// brand-new empty DB with no version number in it
	db := KyotoDB{}
	db.kcdb = cabinet.New()
	filename := "test.kch"
	err := db.kcdb.Open(filename, cabinet.KCOWRITER|cabinet.KCOCREATE)
	if err != nil {
		t.Fatal(err)
	}

	// checkVersion() on an empty DB in read-only mode fails, because
	// it can neither read nor write the version number
	err = db.checkVersion(filename, false, 0, 0, 0)
	expect := "database test.kch has no version number"
	if err == nil || err.Error() != expect {
		t.Errorf("expected error %s, but got %v", expect, err)
	}

	// in write mode it's OK, and sets the version number in the file
	err = db.checkVersion(filename, true, 513, 513, 513)
	assert.Nil(t, err)
	versionkey := makekey(PREFIX_META, "version")
	val, err := db.kcdb.Get(versionkey)
	assert.Nil(t, err)
	assert.Equal(t, "\x00\x00\x02\x01", string(val))

	// once the version number is in the file, write mode doesn't
	// matter -- now it's down to comparing with the supported range
	// of versions
	err = db.checkVersion(filename, false, 513, 134, 231)
	expect = "database test.kch is from the future (database version = 513, but max supported version = 231)"
	if err == nil || err.Error() != expect {
		t.Errorf("expected error\n%s\nbut got\n%v", expect, err)
	}

	err = db.checkVersion(filename, false, 513, 534, 546)
	expect = "database test.kch is too old (database version = 513, but min supported version = 534)"
	if err == nil || err.Error() != expect {
		t.Errorf("expected error\n%s\nbut got\n%v", expect, err)
	}

	err = db.checkVersion(filename, false, 513, 512, 514)
	assert.Nil(t, err)
	err = db.checkVersion(filename, false, 513, 513, 513)
	assert.Nil(t, err)
	err = db.checkVersion(filename, false, 513, 512, 513)
	assert.Nil(t, err)
	err = db.checkVersion(filename, false, 513, 513, 514)
	assert.Nil(t, err)

	// corrupt version number
	err = db.kcdb.Set(versionkey, []byte{0, 0x43, 0})
	assert.Nil(t, err)
	err = db.checkVersion(filename, false, 513, 513, 513)
	expect = "database test.kch: unable to decode version number (004300)"
	if err == nil || err.Error() != expect {
		t.Errorf("expected error\n%s\nbut got\n%v", expect, err)
	}
}