d_store Documentation

0.2

D_store is a dynamic storage and query engine; think of it as a programmatic spreadsheet where you put information into rows and columns. d_store is mostly row oriented. Queries go like this: give me the rows where column number x looks like this, and column number y looks like this.

Results of a query are always d_stores themselves, so you can query them again. You can also run set operations on stores, like getting the difference, or the union.

In d_store a row has an index, and rows can be referenced like that. A column is called a field. What you store in each field is a d_value, which is how you put in and get back the data from d_store. A field contains either NULL or a d_value. Non existing fields always contain NULL.

As a programmers interface, d_store tries to elleviate memory management from the user.

d_value, if using the D_STRING or D_INT macros, the values you get are oneshot, don't reuse them but you also don't have too (may not) free them. Any value you create using d_value_create_from_string() or alike, you can keep and use as much as you want, but you need to free these in the end.

d_values you get from the d_store, you can only use locally, there is no guarentee the value will remain valid if you modify the d_store in any way. Same goes for the data you get from d_value_get_string() or equavalent. If you want to keep on to the values use d_value_copy, or copy the data directly.

As a convenience, all d_store functions with variable arguments can take a string directly as a d_value. Except for the empty string "".

Unless you never put a newly created d_row in a store, don't free the rows; instead use d_row_delete. Notice the difference between deleting a row, and d_store_remove, which just removes the row from one d_store (so from only the set of rows that one d_store represents)!

Any d_row you receive from the store you can only use locally, same as the d_values. But d_row's never become invalid unless somewhere you call d_row_delete from somewhere.

d_stores you always have to free, regardless of how you got them. Freeing d_stores never deletes any data, rows (and therefor the d_values they contain) will always stay until you free the last d_store, or you use d_row_delete.

Freeing the last d_store will free all other housekeeping associated with it, even if that store represents only a small subset of all the rows available. After freeing the last d_store, don't reference any d_values or d_rows again, they will be invalid.

It is essential to understand that though most d_stores will represent a subset of all rows, they do have a reference to all rows. So when you use d_store_create(store), you can use any d_store as an argument, the result is a new d_store that will represent all rows available in that database. Use d_store_create_empty(store) if you want to create a new d_store but with zero rows, or use d_store_copy(store) if you want to copy a specific d_store. If the argument is NULL for any of these cases, then a new database is created.

Notice that it is perfectly valid to put a d_value from one database into a row of another database. However, you cannot add rows to a d_store that belongs to a different database.

guidelines

D_values are atomic, they cannot be modified. This is because any two the same d_values for a field become shared. Any value is only stored once, and that makes handling a value pretty efficient.

A query for a field being equal to a value (except for the NULL value) is an efficient operation (using d_select()). Any other query will need to iterate the d_store you query. So as a rule, start queries by equality queries, then run other needed queries on the resulting d_store.

Same goes for the sorter or nodup, only set a sorter on the final result d_store, the later you set a sorter, the more efficient. After you set a sorter, modifying rows, or adding or removing rows is more efficient then making a new store with the same sorter. So use the mutating d_store_sub(), instead of d_sub().

and when to use

D_store is middle ground between SQL databases and berkeley db alike databases. Berekely db alikes cannot store relationships well. SQL requires you to use SQL queries as the access point to your data, and if you want to express relations, you have to use tables and keys. Translating data into and back from the database is cumbersome, also, any dynamic data is not easily modeled.

D_store fits in between berkely and SQL. As d_store uses set operations, you can model any SQL query with d_store. But d_store is a lot more dynamic then SQL. This comes at a cost of-course, d_store needs to keep all its data in memory to operate well. This means, depending your application, you are limited by your physical memory. So don't use d_store when gigabytes of storage is required.

If you can live with that size limit, then d_store will perform better then SQL in most situations. Because the data is more shared, more indexes are available to d_store. Also d_store is a very direct interface to the C programming language or any language binding. Which removes the need for a some layer inbetween the data model and the programmer.

Author:
Onne Gorter <o.gorter@gmail.com> GPL

Generated on Fri Jan 19 13:06:23 2007 for d_store by  doxygen 1.5.1