Example #1
0
func Open(s string) (*TrailDB, error) {
	ok, er := exists(s)
	if er != nil {
		return nil, er
	}
	if !ok {
		return nil, errors.New(s + ": Path doesn't exist")
	}
	db := C.tdb_init()
	cs := C.CString(s)
	defer C.free(unsafe.Pointer(cs))
	err := C.tdb_open(db, cs)
	if err != 0 {
		return nil, errors.New(s + ": Failed to open traildb: " + errToString(err))
	}
	numFields := uint64(C.tdb_num_fields(db))
	var fields []string
	fieldNameToId := make(map[string]uint64)
	// numFields contains timestamp too
	for i := uint64(0); i <= uint64(numFields)-1; i++ {
		fieldName := C.GoString(C.tdb_get_field_name(db, C.tdb_field(i)))
		fieldNameToId[fieldName] = uint64(i)
		fields = append(fields, fieldName)
	}
	return &TrailDB{
		db:            db,
		NumTrails:     uint64(C.tdb_num_trails(db)),
		NumEvents:     uint64(C.tdb_num_events(db)),
		NumFields:     numFields,
		minTimestamp:  uint64(C.tdb_min_timestamp(db)),
		maxTimestamp:  uint64(C.tdb_max_timestamp(db)),
		fieldNames:    fields,
		fieldNameToId: fieldNameToId,
	}, nil
}
Example #2
0
File: tdb.go Project: ypb/gotdb
// Open is used by New with some reasonable default initial values apart from
// path name. Following is a signature of libtdb's original C tdb_open() function
// written in cgo convention:
//
// func tdb_open(name const *C.char, hash_size, tdb_flags, open_flags C.int, mode C.mode_t) *C.struct_tdb_context
//
//  /* tdb_flags */
//  DEFAULT           /* just a readability place holder */
//  CLEAR_IF_FIRST    /* beats me... */
//  INTERNAL          /* don't store on disk */
//  NOLOCK            /* don't do any locking */
//  NOMMAP            /* don't use mmap */
//  CONVERT           /* convert endian (internal use) */
//  BIGENDIAN         /* header is big-endian (internal use) */
//  NOSYNC            /* don't use synchronous transactions */
//  SEQNUM            /* maintain a sequence number */
//  VOLATILE          /* Activate the per-hashchain freelist, default 5 */
//  ALLOW_NESTING     /* Allow transactions to nest */
//  DISALLOW_NESTING  /* Disallow transactions to nest */
//  INCOMPATIBLE_HASH /* Better hashing: can't be opened by tdb < 1.2.6. */
//
//  /* open_flags */
//  /* 'man 2 open' on *nix, but what of pkg/os? TOPONDER */
//  O_RDONLY
//  /* O_WRONLY *//* is invalid */
//  O_RDWR
//  O_CREAT, O_TRUNC, O_APPEND
//  /* well, Ay dunno... */
//  O_CLOEXEC, O_EXCL
//  /* O_NOATIME *//* #define __USE_GNU */
//  O_NOFOLLOW, O_NONBLOCK = O_NDELAY
//
//  /* O_CREAT mode */
//  USR_RW = (S_IWUSR | S_IRUSR) /* helpful shortcut */
//  USR_RWX                      /* 00700 user (file owner) has read, write and execute permission */
//  USR_R                        /* 00400 user has read permission */
//  USR_W                        /* 00200 user has write permission */
//  USR_X                        /* 00100 user has execute permission */
//  GRP_RWX                      /* 00070 group has read, write and execute permission */
//  GRP_R                        /* 00040 group has read permission */
//  GRP_W                        /* 00020 group has write permission */
//  GRP_X                        /* 00010 group has execute permission */
//  OTH_RWX                      /* 00007 others have read, write and execute permission */
//  OTH_R                        /* 00004 others have read permission */
//  OTH_W                        /* 00002 others have write permission */
//  OTH_X                        /* 00001 others have execute permission */
//
func Open(path string, hash_size, tdb_flags, open_flags int, mode uint32) (DB, Error) {
	name := C.CString(path)
	defer C.free(unsafe.Pointer(name))
	var ctx tdb_CTX
	if old := ns[path]; old != nil { // now, what do we do?
		// if db is still "here" in the ns but closed we
		if old.cld {
			ctx = C.tdb_open(name, C.int(hash_size), C.int(tdb_flags), C.int(open_flags), C.mode_t(mode))
			if ctx == nil {
				return DB{old}, mkError(1, "tdb.Open() tdb_open old failed")
			} else {
				old.cld = false
				old.ctx = ctx
				return DB{old}, nil
			}
			// if it's not closed perhaps we should to something "more"
			// intelligent, like closing and reopening with new params
			// TODO: later?
		} else {
			return DB{old}, nil
		}
	} else {
		var fresh *db
		ctx = C.tdb_open(name, C.int(hash_size), C.int(tdb_flags), C.int(open_flags), C.mode_t(mode))
		if ctx == nil {
			println("Open() new ctx == nil")
			fresh = &db{&path, false, true, ctx}
			ns[path] = fresh
			return DB{fresh}, mkError(1, "tdb.Open() tdb_open fresh failed")
		} else {
			fresh = &db{pth: &path, cld: false, dbg: false, ctx: ctx}
			ns[path] = fresh
			return DB{fresh}, nil
		}
	}
	panic("unreachable")
	// return &DB{path, false, ctx}
}