static object current_key_string; static object current_key_string_1; static object current_key_string_2; static object current_value_string; DBT * string_to_dbt (object s, DBT *datum) { if (s != Cnil) { datum->size = s->st.st_fillp; datum->data = s->st.st_self; } return datum; } void dbt_to_string (DBT *datum, object s) { s->st.st_dim = s->st.st_fillp = datum->size; s->st.st_self = datum->data; return s; } int dbt_to_uint (DBT *datum) { int i, result = 0; for (i = 0; i < datum->size; ++i) { result *= 10; result += (int) (((char *) datum->data)[i] - '0'); } return result; } int compare_uint (DB *db, DBT *a, DBT *b) { return (dbt_to_uint (a) - dbt_to_uint (b)); } void db_status (int status) { if (status != 0) FEerror ("Berkeley DB error: ~a", 1, make_simple_string (db_strerror (status))); } int db_open (const char *path, const char *key_type) { DB *db; db_status (db_create (&db, NULL, 0)); if (strcasecmp (key_type, "integer") == 0) db_status (db->set_bt_compare (db, compare_uint)); else if (strcasecmp (key_type, "t") == 0) db_status (db->set_bt_compare (db, btree_compare)); db_status (db->open (db, NULL, path, NULL, DB_BTREE, DB_CREATE, 0)); return ((int) db); } void db_close (int db) { db_status (((DB *) db)->close ((DB *) db, 0)); } object db_get (int db, object key_string) { DBT key, value; int status; memset (&key, 0, sizeof (DBT)); memset (&value, 0, sizeof (DBT)); status = ((DB *) db)->get ((DB *) db, NULL, string_to_dbt (key_string, &key), &value, 0); if (status == DB_NOTFOUND) return Cnil; else if (status != 0) db_status (status); dbt_to_string (&key, current_key_string); dbt_to_string (&value, current_value_string); return Ct; } void db_put (int db, object key_string, object value_string) { DBT key, value; memset (&key, 0, sizeof (DBT)); memset (&value, 0, sizeof (DBT)); db_status (((DB *) db)->put ((DB *) db, NULL, string_to_dbt (key_string, &key), string_to_dbt (value_string, &value), 0)); } void db_delete (int db, object key_string) { DBT key; int status; memset (&key, 0, sizeof (DBT)); status = ((DB *) db)->del ((DB *) db, NULL, string_to_dbt (key_string, &key), 0); if ((status != 0) && (status != DB_NOTFOUND)) db_status (status); } void db_sync (int db) { db_status (((DB *) db)->sync ((DB *) db, 0)); } int db_cursor (int db) { DBC *cursor; db_status (((DB *) db)->cursor ((DB *) db, NULL, &cursor, 0)); return ((int) cursor); } void db_cursor_close (int cursor) { db_status (((DBC *) cursor)->c_close ((DBC *) cursor)); } object db_cursor_move (int cursor, int flags, object key_string) { DBT key, value; int status; memset (&key, 0, sizeof (DBT)); memset (&value, 0, sizeof (DBT)); status = ((DBC *) cursor)->c_get ((DBC *) cursor, string_to_dbt (key_string, &key), &value, flags); if (status == DB_NOTFOUND) return Cnil; else if (status != 0) db_status (status); dbt_to_string (&key, current_key_string); dbt_to_string (&value, current_value_string); return Ct; }