Example #1
0
 /** Finds a record by looking up the key. */
 record &find(txn *t, key *k, record *r, uint32_t flags = 0) {
   ham_status_t st = ham_db_find(m_db,
             t ? t->get_handle() : 0,
             k ? k->get_handle() : 0,
             r->get_handle(), flags);
   if (st)
     throw error(st);
   return (*r);
 }
Example #2
0
 /** Finds a record by looking up the key. */
 record find(txn *t, key *k, uint32_t flags = 0) {
   record r;
   ham_status_t st = ham_db_find(m_db,
             t ? t->get_handle() : 0,
             k ? k->get_handle() : 0,
             r.get_handle(), flags);
   if (st)
     throw error(st);
   return (r);
 }
Example #3
0
int CDbxKV::GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic)
{
	if (szSetting == NULL || szModule == NULL)
		return 1;

	// the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name
	int settingNameLen = (int)strlen(szSetting);
	int moduleNameLen = (int)strlen(szModule);
	if (settingNameLen > 0xFE) {
#ifdef _DEBUG
		OutputDebugStringA("GetContactSettingWorker() got a > 255 setting name length. \n");
#endif
		return 1;
	}
	if (moduleNameLen > 0xFE) {
#ifdef _DEBUG
		OutputDebugStringA("GetContactSettingWorker() got a > 255 module name length. \n");
#endif
		return 1;
	}

	mir_cslock lck(m_csDbAccess);

LBL_Seek:
	char *szCachedSettingName = m_cache->GetCachedSetting(szModule, szSetting, moduleNameLen, settingNameLen);

	DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 0);
	if (pCachedValue != NULL) {
		if (pCachedValue->type == DBVT_ASCIIZ || pCachedValue->type == DBVT_UTF8) {
			int cbOrigLen = dbv->cchVal;
			char *cbOrigPtr = dbv->pszVal;
			memcpy(dbv, pCachedValue, sizeof(DBVARIANT));
			if (isStatic) {
				int cbLen = 0;
				if (pCachedValue->pszVal != NULL)
					cbLen = (int)strlen(pCachedValue->pszVal);

				cbOrigLen--;
				dbv->pszVal = cbOrigPtr;
				if (cbLen < cbOrigLen)
					cbOrigLen = cbLen;
				memcpy(dbv->pszVal, pCachedValue->pszVal, cbOrigLen);
				dbv->pszVal[cbOrigLen] = 0;
				dbv->cchVal = cbLen;
			}
			else {
				dbv->pszVal = (char*)mir_alloc(strlen(pCachedValue->pszVal) + 1);
				strcpy(dbv->pszVal, pCachedValue->pszVal);
			}
		}
		else memcpy(dbv, pCachedValue, sizeof(DBVARIANT));

		return (pCachedValue->type == DBVT_DELETED) ? 1 : 0;
	}

	// never look db for the resident variable
	if (szCachedSettingName[-1] != 0)
		return 1;

	DBCachedContact *cc = (contactID) ? m_cache->GetCachedContact(contactID) : NULL;

	DBSettingSortingKey keySearch;
	keySearch.dwContactID = contactID;
	keySearch.dwOfsModule = GetModuleNameOfs(szModule);
	strncpy_s(keySearch.szSettingName, szSetting, _TRUNCATE);

	ham_key_t key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch };
	ham_record_t rec = { 0 };
	if (ham_db_find(m_dbSettings, NULL, &key, &rec, 0)) {
		// try to get the missing mc setting from the active sub
		if (cc && cc->IsMeta() && ValidLookupName(szModule, szSetting)) {
			if (contactID = db_mc_getDefault(contactID)) {
				if (szModule = GetContactProto(contactID)) {
					moduleNameLen = (int)strlen(szModule);
					goto LBL_Seek;
				}
			}
		}
		return 1;
	}

	BYTE *pBlob = (BYTE*)rec.data;
	if (isStatic && (pBlob[0] & DBVTF_VARIABLELENGTH) && VLT(dbv->type) != VLT(pBlob[0]))
		return 1;

	int varLen;
	BYTE iType = dbv->type = pBlob[0]; pBlob++;
	switch (iType) {
	case DBVT_DELETED: /* this setting is deleted */
		dbv->type = DBVT_DELETED;
		return 2;

	case DBVT_BYTE:  dbv->bVal = *pBlob; break;
	case DBVT_WORD:  dbv->wVal = *(WORD*)pBlob; break;
	case DBVT_DWORD: dbv->dVal = *(DWORD*)pBlob; break;

	case DBVT_UTF8:
	case DBVT_ASCIIZ:
		varLen = *(WORD*)pBlob;
		pBlob += 2;
		if (isStatic) {
			dbv->cchVal--;
			if (varLen < dbv->cchVal)
				dbv->cchVal = varLen;
			memmove(dbv->pszVal, pBlob, dbv->cchVal); // decode
			dbv->pszVal[dbv->cchVal] = 0;
			dbv->cchVal = varLen;
		}
		else {
			dbv->pszVal = (char*)mir_alloc(1 + varLen);
			memmove(dbv->pszVal, pBlob, varLen);
			dbv->pszVal[varLen] = 0;
		}
		break;

	case DBVT_BLOB:
		varLen = *(WORD*)pBlob;
		pBlob += 2;
		if (isStatic) {
			if (varLen < dbv->cpbVal)
				dbv->cpbVal = varLen;
			memmove(dbv->pbVal, pBlob, dbv->cpbVal);
		}
		else {
			dbv->pbVal = (BYTE *)mir_alloc(varLen);
			memmove(dbv->pbVal, pBlob, varLen);
		}
		dbv->cpbVal = varLen;
		break;

	case DBVT_ENCRYPTED:
		if (m_crypto == NULL)
			return 1;

		varLen = *(WORD*)pBlob;
		pBlob += 2;
		
		size_t realLen;
		ptrA decoded(m_crypto->decodeString(pBlob, varLen, &realLen));
		if (decoded == NULL)
			return 1;

		varLen = (WORD)realLen;
		dbv->type = DBVT_UTF8;
		if (isStatic) {
			dbv->cchVal--;
			if (varLen < dbv->cchVal)
				dbv->cchVal = varLen;
			memmove(dbv->pszVal, decoded, dbv->cchVal);
			dbv->pszVal[dbv->cchVal] = 0;
			dbv->cchVal = varLen;
		}
		else {
			dbv->pszVal = (char*)mir_alloc(1 + varLen);
			memmove(dbv->pszVal, decoded, varLen);
			dbv->pszVal[varLen] = 0;
		}
		break;
	}

	/**** add to cache **********************/
	if (iType != DBVT_BLOB && iType != DBVT_ENCRYPTED) {
		DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1);
		if (pCachedValue != NULL)
			m_cache->SetCachedVariant(dbv, pCachedValue);
	}

	return 0;
}
Example #4
0
int
main(int argc, char **argv) {
  int i;
  ham_status_t st;      /* status variable */
  ham_env_t *env;       /* hamsterdb Environment object */
  ham_db_t *db;         /* hamsterdb Database object */
  ham_key_t key = {0};     /* the structure for a key */
  ham_record_t record = {0};   /* the structure for a record */

  /*
   * Connect to the server which should listen at 8080. The server is
   * implemented in server1.c.
   */
  st = ham_env_create(&env, "ham://localhost:8080/env1.db", 0, 0, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_create", st);

  /* now open a Database in this Environment */
  st = ham_env_open_db(env, &db, 13, 0, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_open_db", st);

  /* now we can insert, delete or lookup values in the database */
  for (i = 0; i < LOOP; i++) {
    key.data = &i;
    key.size = sizeof(i);

    record.size = key.size;
    record.data = key.data;

    st = ham_db_insert(db, 0, &key, &record, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_insert", st);
  }

  /* now lookup all values */
  for (i = 0; i < LOOP; i++) {
    key.data = &i;
    key.size = sizeof(i);

    st = ham_db_find(db, 0, &key, &record, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_find", st);

    /* check if the value is ok */
    if (*(int *)record.data != i) {
      printf("ham_db_find() ok, but returned bad value\n");
      return (-1);
    }
  }

  /* erase everything */
  for (i = 0; i < LOOP; i++) {
    key.data = &i;
    key.size = sizeof(i);

    st = ham_db_erase(db, 0, &key, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_erase", st);
  }

  /* and make sure that the database is empty */
  for (i = 0; i < LOOP; i++) {
    key.data = &i;
    key.size = sizeof(i);

    st = ham_db_find(db, 0, &key, &record, 0);
    if (st != HAM_KEY_NOT_FOUND)
      error("ham_db_find", st);
  }

  /* close the database handle */
  st = ham_db_close(db, 0);
  if (st != HAM_SUCCESS)
    error("ham_db_close", st);

  /* close the environment handle */
  st = ham_env_close(env, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_close", st);

  printf("success!\n");
  return (0);
}
Example #5
0
int
main(int argc, char **argv) {
  uint32_t i;
  ham_status_t st;             /* status variable */
  ham_env_t *env;              /* hamsterdb environment object */
  ham_db_t *db;                /* hamsterdb database object */
  ham_key_t key = {0};         /* the structure for a key */
  ham_record_t record = {0};   /* the structure for a record */
  ham_parameter_t params[] = { /* parameters for ham_env_create_db */
    {HAM_PARAM_KEY_TYPE, HAM_TYPE_UINT32},
    {HAM_PARAM_RECORD_SIZE, sizeof(uint32_t)},
    {0, }
  };

  /* First create a new hamsterdb Environment */
  st = ham_env_create(&env, "test.db", 0, 0664, 0);
  if (st != HAM_SUCCESS)
    error("ham_create", st);

  /* And in this Environment we create a new Database for uint32-keys
   * and uint32-records. */
  st = ham_env_create_db(env, &db, DATABASE_NAME, 0, &params[0]);
  if (st != HAM_SUCCESS)
    error("ham_create", st);

  /*
   * now we can insert, delete or lookup values in the database
   *
   * for our test program, we just insert a few values, then look them
   * up, then delete them and try to look them up again (which will fail).
   */
  for (i = 0; i < LOOP; i++) {
    key.data = &i;
    key.size = sizeof(i);

    record.size = key.size;
    record.data = key.data;

    st = ham_db_insert(db, 0, &key, &record, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_insert", st);
  }

  /*
   * now lookup all values
   *
   * for ham_db_find(), we could use the flag HAM_RECORD_USER_ALLOC, if WE
   * allocate record.data (otherwise the memory is automatically allocated
   * by hamsterdb)
   */
  for (i = 0; i < LOOP; i++) {
    key.data = &i;
    key.size = sizeof(i);

    st = ham_db_find(db, 0, &key, &record, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_find", st);

    /*
     * check if the value is ok
     */
    if (*(int *)record.data != i) {
      printf("ham_db_find() ok, but returned bad value\n");
      return (-1);
    }
  }

  /*
   * close the database handle, then re-open it (to demonstrate how to open
   * an Environment and a Database)
   */
  st = ham_db_close(db, 0);
  if (st != HAM_SUCCESS)
    error("ham_db_close", st);
  st = ham_env_close(env, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_close", st);

  st = ham_env_open(&env, "test.db", 0, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_open", st);
  st = ham_env_open_db(env, &db, DATABASE_NAME, 0, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_open_db", st);

  /* now erase all values */
  for (i = 0; i < LOOP; i++) {
    key.size = sizeof(i);
    key.data = &i;

    st = ham_db_erase(db, 0, &key, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_erase", st);
  }

  /*
   * once more we try to find all values... every ham_db_find() call must
   * now fail with HAM_KEY_NOT_FOUND
   */
  for (i = 0; i < LOOP; i++) {
    key.size = sizeof(i);
    key.data = &i;

    st = ham_db_find(db, 0, &key, &record, 0);
    if (st != HAM_KEY_NOT_FOUND)
      error("ham_db_find", st);
  }

  /* we're done! close the handles. HAM_AUTO_CLEANUP will also close the
   * 'db' handle */
  st = ham_env_close(env, HAM_AUTO_CLEANUP);
  if (st != HAM_SUCCESS)
    error("ham_env_close", st);

  printf("success!\n");
  return (0);
}
Example #6
0
File: env2.c Project: ziposoft/ac1
int
main(int argc, char **argv) {
  int i;
  ham_status_t st;    /* status variable */
  ham_db_t *db[MAX_DBS];  /* hamsterdb database objects */
  ham_env_t *env;     /* hamsterdb environment */
  ham_cursor_t *cursor[MAX_DBS]; /* a cursor for each database */
  ham_key_t key, cust_key, ord_key, c2o_key;
  ham_record_t record, cust_record, ord_record, c2o_record;

  customer_t customers[MAX_CUSTOMERS] = {
    { 1, "Alan Antonov Corp." },
    { 2, "Barry Broke Inc." },
    { 3, "Carl Caesar Lat." },
    { 4, "Doris Dove Brd." }
  };

  order_t orders[MAX_ORDERS] = {
    { 1, 1, "Joe" },
    { 2, 1, "Tom" },
    { 3, 3, "Joe" },
    { 4, 4, "Tom" },
    { 5, 3, "Ben" },
    { 6, 3, "Ben" },
    { 7, 4, "Chris" },
    { 8, 1, "Ben" }
  };

  memset(&key, 0, sizeof(key));
  memset(&record, 0, sizeof(record));
  memset(&cust_key, 0, sizeof(cust_key));
  memset(&cust_record, 0, sizeof(cust_record));
  memset(&ord_key, 0, sizeof(ord_key));
  memset(&ord_record, 0, sizeof(ord_record));
  memset(&c2o_key, 0, sizeof(c2o_key));
  memset(&c2o_record, 0, sizeof(c2o_record));

  /* Now create a new database file for the Environment */
  st = ham_env_create(&env, "test.db", 0, 0664, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_create", st);

  /*
   * Then create the two Databases in this Environment; each Database
   * has a name - the first is our "customer" Database, the second
   * is for the "orders"; the third manages our 1:n relation and
   * therefore needs to enable duplicate keys
   */
  st = ham_env_create_db(env, &db[DBIDX_CUSTOMER], DBNAME_CUSTOMER, 0, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_create_db(customer)", st);
  st = ham_env_create_db(env, &db[DBIDX_ORDER], DBNAME_ORDER, 0, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_create_db(order)", st);
  st = ham_env_create_db(env, &db[DBIDX_C2O], DBNAME_C2O,
        HAM_ENABLE_DUPLICATES, 0);
  if (st != HAM_SUCCESS)
    error("ham_env_create_db(c2o)", st);

  /* Create a Cursor for each Database */
  for (i = 0; i < MAX_DBS; i++) {
    st = ham_cursor_create(&cursor[i], db[i], 0, 0);
    if (st != HAM_SUCCESS)
      error("ham_cursor_create" , st);
  }

  /*
   * Insert the customers in the customer table
   *
   * INSERT INTO customers VALUES (1, "Alan Antonov Corp.");
   * INSERT INTO customers VALUES (2, "Barry Broke Inc.");
   * etc
   */
  for (i = 0; i < MAX_CUSTOMERS; i++) {
    key.size = sizeof(int);
    key.data = &customers[i].id;

    record.size = sizeof(customer_t);
    record.data = &customers[i];

    st = ham_db_insert(db[0], 0, &key, &record, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_insert (customer)", st);
  }

  /*
   * And now the orders in the second Database; contrary to env1,
   * we only store the assignee, not the whole structure
   *
   * INSERT INTO orders VALUES (1, "Joe");
   * INSERT INTO orders VALUES (2, "Tom");
   */
  for (i = 0; i < MAX_ORDERS; i++) {
    key.size = sizeof(int);
    key.data = &orders[i].id;

    record.size = sizeof(orders[i].assignee);
    record.data = orders[i].assignee;

    st = ham_db_insert(db[1], 0, &key, &record, 0);
    if (st != HAM_SUCCESS)
      error("ham_db_insert (order)", st);
  }

  /*
   * And now the 1:n relationships; the flag HAM_DUPLICATE creates
   * a duplicate key, if the key already exists
   *
   * INSERT INTO c2o VALUES (1, 1);
   * INSERT INTO c2o VALUES (2, 1);
   * etc
   */
  for (i = 0; i < MAX_ORDERS; i++) {
    key.size = sizeof(int);
    key.data = &orders[i].customer_id;

    record.size = sizeof(int);
    record.data = &orders[i].id;

    st = ham_db_insert(db[2], 0, &key, &record, HAM_DUPLICATE);
    if (st != HAM_SUCCESS)
      error("ham_db_insert(c2o)", st);
  }

  /*
   * Now start the query - we want to dump each customer with his
   * orders
   *
   * loop over the customer; for each customer, loop over the 1:n table
   * and pick those orders with the customer id. then load the order
   * and print it
   *
   * the outer loop is similar to:
   *  SELECT * FROM customers WHERE 1;
   */
  while (1) {
    customer_t *customer;

    st = ham_cursor_move(cursor[0], &cust_key, &cust_record, HAM_CURSOR_NEXT);
    if (st != HAM_SUCCESS) {
      /* reached end of the database? */
      if (st == HAM_KEY_NOT_FOUND)
        break;
      else
        error("ham_cursor_next(customer)", st);
    }

    customer = (customer_t *)cust_record.data;

    /* print the customer id and name */
    printf("customer %d ('%s')\n", customer->id, customer->name);

    /*
     * loop over the 1:n table
     *
     * before we start the loop, we move the cursor to the
     * first duplicate key
     *
     * SELECT * FROM customers, orders, c2o
     *   WHERE c2o.customer_id=customers.id AND
     *    c2o.order_id=orders.id;
     */
    c2o_key.data = &customer->id;
    c2o_key.size = sizeof(int);
    st = ham_cursor_find(cursor[2], &c2o_key, 0, 0);
    if (st != HAM_SUCCESS) {
      if (st == HAM_KEY_NOT_FOUND)
        continue;
      error("ham_cursor_find(c2o)", st);
    }
    st = ham_cursor_move(cursor[2], 0, &c2o_record, 0);
    if (st != HAM_SUCCESS)
      error("ham_cursor_move(c2o)", st);

    do {
      int order_id;

      order_id = *(int *)c2o_record.data;
      ord_key.data = &order_id;
      ord_key.size = sizeof(int);

      /*
       * load the order
       * SELECT * FROM orders WHERE id = order_id;
       */
      st = ham_db_find(db[1], 0, &ord_key, &ord_record, 0);
      if (st != HAM_SUCCESS)
        error("ham_db_find(order)", st);

      printf("  order: %d (assigned to %s)\n",
          order_id, (char *)ord_record.data);

      /*
       * The flag HAM_ONLY_DUPLICATES restricts the cursor
       * movement to the duplicate list.
       */
      st = ham_cursor_move(cursor[2], &c2o_key,
          &c2o_record, HAM_CURSOR_NEXT|HAM_ONLY_DUPLICATES);
      if (st != HAM_SUCCESS) {
        /* reached end of the database? */
        if (st == HAM_KEY_NOT_FOUND)
          break;
        else
          error("ham_cursor_next(c2o)", st);
      }
    } while (1);
  }

  /*
   * Now close the Environment handle; the flag
   * HAM_AUTO_CLEANUP will automatically close all Databases and
   * Cursors
   */
  st = ham_env_close(env, HAM_AUTO_CLEANUP);
  if (st != HAM_SUCCESS)
    error("ham_env_close", st);

  printf("success!\n");
  return (0);
}