// Open opens the named DB file for reading/writing. If successful, methods on // the returned DB can be used for I/O; the associated file descriptor has mode // os.O_RDWR. If there is an error, it will be of type *os.PathError. // // For the meaning of opts please see documentation of Options. func Open(name string, opts *Options) (db *DB, err error) { defer func() { lock := opts.lock if err != nil && lock != nil { n := lock.Name() lock.Close() os.Remove(n) db = nil } if err != nil { if db != nil { db.Close() db = nil } } }() if err = opts.check(name, false, true); err != nil { return } f, err := os.OpenFile(name, os.O_RDWR, 0666) if err != nil { return } filer := lldb.Filer(lldb.NewSimpleFileFiler(f)) sz, err := filer.Size() if err != nil { return } if sz%16 != 0 { return nil, &os.PathError{Op: "dbm.Open:", Path: name, Err: fmt.Errorf("file size %d(%#x) is not 0 (mod 16)", sz, sz)} } var b [16]byte if n, err := filer.ReadAt(b[:], 0); n != 16 || err != nil { return nil, &os.PathError{Op: "dbm.Open.ReadAt", Path: name, Err: err} } var h header if err = h.rd(b[:]); err != nil { return nil, &os.PathError{Op: "dbm.Open:validate header", Path: name, Err: err} } db = &DB{f: f, lock: opts.lock, closed: make(chan bool)} if filer, err = opts.acidFiler(db, filer); err != nil { return nil, err } db.filer = filer switch h.ver { default: return nil, &os.PathError{Op: "dbm.Open", Path: name, Err: fmt.Errorf("unknown dbm file format version %#x", h.ver)} case 0x00: return open00(name, db) } }
// Open opens the named DB file for reading/writing. If successful, methods on // the returned DB can be used for I/O; the associated file descriptor has mode // os.O_RDWR. If there is an error, it will be of type *os.PathError. // // Note: While a DB is opened, it is locked and cannot be simultaneously opened // again. // // For the meaning of opts please see documentation of Options. func Open(name string, opts *Options) (db *DB, err error) { opts = opts.clone() opts._ACID = _ACIDFull defer func() { lock := opts.lock if err != nil && lock != nil { lock.Close() db = nil } if err != nil { if db != nil { db.Close() db = nil } } }() if err = opts.check(name, false, true); err != nil { return } f, err := os.OpenFile(name, os.O_RDWR, 0666) if err != nil { return } filer := lldb.Filer(lldb.NewSimpleFileFiler(f)) sz, err := filer.Size() if err != nil { return } if sz%16 != 0 { return nil, &os.PathError{Op: "kv.Open:", Path: name, Err: fmt.Errorf("file size %d(%#x) is not 0 (mod 16)", sz, sz)} } var b [16]byte if n, err := filer.ReadAt(b[:], 0); n != 16 || err != nil { return nil, &os.PathError{Op: "kv.Open.ReadAt", Path: name, Err: err} } var h header if err = h.rd(b[:]); err != nil { return nil, &os.PathError{Op: "kv.Open:validate header", Path: name, Err: err} } db = &DB{f: f, lock: opts.lock} if filer, err = opts.acidFiler(db, filer); err != nil { return nil, err } db.filer = filer switch h.ver { default: return nil, &os.PathError{Op: "kv.Open", Path: name, Err: fmt.Errorf("unknown/unsupported kv file format version %#x", h.ver)} case 0x00: if _, err = open00(name, db); err != nil { return nil, err } } db.root, err = lldb.OpenBTree(db.alloc, opts.Compare, 1) db.wal = opts.wal return }