// Open an environment at the given home path.
func OpenEnvironment(home string, config *EnvironmentConfig) (env Environment, err error) {
	err = check(C.db_env_create(&env.ptr, 0))
	if err == nil {
		defer func() {
			if err != nil && env.ptr != nil {
				C.db_env_close(env.ptr, 0)
				env.ptr = nil
			}
		}()
	} else {
		return
	}

	var mode C.int = 0
	var flags C.u_int32_t = C.DB_THREAD
	var chome, cpassword *C.char

	chome = C.CString(home)
	defer C.free(unsafe.Pointer(chome))

	if config != nil {
		if config.Create {
			flags |= C.DB_CREATE
		}
		if config.Mode != 0 {
			mode = C.int(config.Mode)
		}
		if len(config.Password) > 0 {
			cpassword := C.CString(config.Password)
			C.free(unsafe.Pointer(cpassword))
		}
		if config.Recover {
			flags |= C.DB_REGISTER | C.DB_FAILCHK | C.DB_RECOVER
		}
		if config.Transactional {
			flags |= C.DB_INIT_TXN | C.DB_INIT_MPOOL
		}
		if config.NoSync {
			flags |= C.DB_TXN_NOSYNC
		}
		if config.WriteNoSync {
			flags |= C.DB_TXN_WRITE_NOSYNC
		}
	}

	if cpassword != nil {
		err = check(C.db_env_set_encrypt(env.ptr, cpassword, 0))
		if err != nil {
			return
		}
	}

	err = check(C.db_env_open(env.ptr, chome, flags, mode))

	return
}
func NewEnvironment(home string, flags DbFlag, mode int) (*Environment, error) {
	ret := new(Environment)

	err := Err(C.db_env_create(&ret.ptr, 0))
	if err != nil {
		return nil, err
	}

	cHome := C.CString(home)
	defer C.free(unsafe.Pointer(cHome))

	err = Err(C.db_env_open(ret.ptr, cHome, C.u_int32_t(flags), C.int(mode)))
	if err != nil {
		ret.Close(0)
		return nil, err
	}

	return ret, ok
}