You should create an instance of the database class and make it accessible to
all application modules.
Before you can do something with your database, you should open it.
Checking the dbDatabase::open()
return code, you can
find out, if the database was successfully opened. Errors during database
opening do not terminate the application (but they are reported)
even with the default error handler.
Once you are certain that the database is normally opened, you can start
to work with the database. If your application is multithreaded and several threads
will work with the same database, you should attach each thread to the
database by the dbDatabase::attach
method. Before thread termination,
it should detach itself from the database by invoking the
dbDatabase::detach()
method. If your application uses navigation
through database objects by references, you need some kind of root object
which can be located without any references. The best candidate for the root
object is the first record of the table. FastDB guarantees that new
records are always inserted at the end of the table. So the first table record
is also the oldest record in the table.
To access database data, you should create a number of dbQuery
and dbCursor
objects. If several threads are working with the
database, each thread should have its own instances of query and
cursor objects. Usually it is enough to have one cursor for each table
(or two if your application also can update table records). But in case
of nested queries, using several cursors may be needed.
Query objects are usually created for each type of queries. Query objects are
used also for caching compiled queries, so it will be a good idea to
extend the life span of query variables (may be make them static).
There are four main operations with database: insert, select, update, remove.
The first is done without using cursors, by means of the global overloaded
template function insert
. Selection, updating and deleting of
records is performed using cursors. To be able to modify a table you should
use a cursor for update. A cursor in FastDB is typed and contains an instance
of an object of the table class. The overloaded 'operator->
'
of the cursor can be used to access components of the current record
and also to update these components. The method update
copies data from the cursor's object to the current table record.
The cursor's method remove
will remove the current cursor record,
the method removeAllSelected
will remove all selected records and
the method removeAll
will remove all records in the table.
Each transaction should be either committed by
the dbDatabase::commit()
or aborted by
the dbDatabase::rollback()
method. A transaction is started
automatically when the first select, insert or remove operation is executed.
Before exiting from your application do not forget to close the database.
Also remember, that the method dbDatabase::close()
will automatically
commit the last transaction, so if this is not what you want, then explicitly perform
a dbDatabase::rollback
before exit.
So a template for a FastDB application can look like this:
// // Header file // #include "fastdb.h" extern dbDatabase db; // create database object class MyTable { char const* someField; ... public: TYPE_DESCRIPTOR((FIELD(someField))); }; // // Implementation // REGISTER(MyTable); int main() { if (db.open("mydatabase")) { dbCursor<MyTable> cursor; dbQuery q; char value[bufSize]; q = "someField=",value; gets(value); if (cursor.select(q) > 0) { do { printf("%s\n", cursor->someField); } while (cursor.next()); } db.close(); return EXIT_SUCCESS; } else { return EXIT_FAILURE; } }To compile a FastDB application you have to include the header file
"fastdb.h"
. This header file includes other FastDB header files,
so make sure that the FastDB directory is in the compiler's include path. To
link a FastDB application, you need the FastDB library ("fastdb.lib"
for Windows or "libfastdb.a"
for Unix). You can either
specify the full path to this library or place it in some default
library catalog (for example /usr/lib
for Unix).
To build the FastDB library, just type make
in the FastDB directory.
There is no autoconfiguration utility included
in the FastDB distribution. Most system dependent parts of the code are compiled using
conditional compilation. There are two makefiles in the FastDB distribution.
One for MS Windows with MS Visual C++ (makefile.mvc
)
and another one for generic Unix with a gcc compiler(makefile
).
If you want to use Posix threads or some other compiler, you
should edit this makefile.
There is also a make.bat
file, which just spawns a
nmake -f makefile.mvc
command.
The install
target in the
Unix makefile will copy FastDB header files, the FastDB library and the subsql utility
to directories specified by the INCSPATH, LIBSPATH
and
BINSPATH makefile variables correspondingly.
Default values of these variables are the following:
INCSPATH=/usr/include LIBSPATH=/usr/lib BINSPATH=/usr/bin
Once your application starts to work, you will be busy with
support and extension of your application. FastDB is able to perform
automatic schema evaluation for such cases as adding a new field to the table and
changing the type of a field. The programmer can also add new indices or remove
rarely used indices. The database trace can be switched on (by (re-)compiling the
FastDB library with the -DDEBUG=DEBUG_TRACE
option) to
perform analysis of database functionality and efficiency of using indices.
The SUBSQL utility can be used for database browsing and inspection, performing online backups, importing data to and exporting data from the database. FastDB will perform automatic recovery after system or application crash; you should not worry about it. The only thing you perhaps have to do manually is stopping all database applications if one of them crashes, leaving the database blocked.
FastDB allows to declare queries as static variables.
But in this case destructors of these queries can be called after destructors of the static
objects from the FastDB library itself (because order of invoking destructors for different modules is
not specified. To solve this problem, in FastDB some global objects are replaced with references.
As a result destructors are never called for these objects. But it leads to memory leaks
in application. These memory leaks can not actually cause some problems (like memory exhaustion),
but it case warning in some memory-checking utilities. And many C++ programmers like to use such utilities
to check if all memory is correctly deallocated. To avoid these warning for FastDB objects you can
register with atexit
system function static method dbTableDescriptor::cleanup()
,
which will delete all objects allocated by FastDB.
dbDefaultInitDatabaseSize
parameter. Reducing the initial database size can only cause only additional database
reallocations when the database is growing. Reallocation is expensive operation (it requires
unmapping the file and mapping it to the new location, as a result the modified pages are
first saved to the disk, and then has to be reloaded from the disk), so reducing number
of reallocations is significant. FastDB duplicates the virtual memory size used by the
database during reallocation.
By changing dbDefaultInitDatabaseSize
you could not make database
file to become smaller than 1Mb. This is because of another parameter -
dbDefaultInitIndexSize
, which specify size of object index.
Default value is 64k, each entry is 4 bytes long and there two instances of the index -
primary and shadow. So only the index occupies 512k of memory. Another 512k is reserved for
storing data. So the initial size of the database can be reduced by decreasing
dbDefaultInitIndexSize
parameter. But I do not recommend to do it, because
it is unlikely that there will be less than several thousands objects in the database.
It is important to notice that unlike normal mode, FastDB is not able to extend database in diskless
mode. To be able to reallocate memory mapped object (to extend its size), FastDB will have
to create somewhere (in memory) temporary buffer to hold all database data, copy all data to this buffer,
destruct original memory mapping object, create new memory mapping object, copy data from buffer to the
new memory mapping object and then destruct the buffer. So if database size was N
, then
reallocation requires 3*N
free memory and copying of all database data two times.
I think this is too large memory and CPU overhead.
So in diskless mode it is necessary to specify maximal database size in the constructor of
dbDatabase
(dbInitSize
parameter). Specifying large size will not cause
some significant system overhead, because physical pages will be in any case allocated on demand.
So it is not so difficult to avoid exhaustion of database size by specifying very large
value in dbInitSize
parameter). The only restriction is that specified size should not
be greater than size of virtual memory in the system (usually size of swap + physical memory).
In addition to DISKLESS_CONFIGURATION switch, FastDB also provides additional
switches to control used OS API: USE_POSIX_MMAP, USE_POSIX_SEMAPHORES, NO_MMAP
.
Use them only if mechanism used by FastDB by default doesn't work (or work inefficiently
at your system. Some of these switches and enables implicitly once you have
choose particular configuration. The following table summarize usage of these switches:
| Set macrors | Implies | Data file | Monitor | Description |
|---|---|---|---|---|
| USE_POSIX_MMAP=0 | NO_MMAP=1 | shmat | shmat | normal access to database without mmap |
| USE_POSIX_MMAP=1 | mmap | mmap | private process database | |
| NO_MMAP | malloc | shmat | normal access | |
| DISKLESS_CONFIGURATION | USE_POSIX_MMAP=0 | shmat | shmat | transient public database |
| DISKLESS_CONFIGURATION USE_POSIX_MMAP=1 | mmap | mmap | transient private database |
All combinations not defined in this table are considered to be invalid. Also it is not recommended to set these macros explicitly and use configuration switches (like DISKLESS_CONFIGURATION) instead.
REGISTER_UNASSIGNED
macro.
dbCursor
constructor.
insert
is now member of dbDatabase class (if
C++ compiler doesn't support member templates, you should define
NO_MEMBER_TEMPLATES
macro and path pointer to database as first parameter).
For examle:
class MyClass { ... }; REGISTER_UNASSIGNED(MyClass); dbDatabase* db; dbCursor<MyClass> cursor(db); MyClass rec; if (cursor.select(q) == 0) { db->insert(rec); }
I will provide e-mail support and help you with development of FastDB applications.
Look for new version at my homepage | E-Mail me about bugs and problems


<learningBasebody>
The <learningBasebody>
element is the main body-level element in a
<learningBase>
topic. The <learningBase>
topic
provides a set of base elements for use in the other specialized learning types. It is
not generally intended for creating actual content. As such, each of the body sections
in <learningBase>
are optional.
Category: Learning and training: topic elements


Goa is a state in western India with coastlines stretching along the Arabian Sea. Its long history as a Portuguese colony prior to 1961 is evident in its preserved 17th-century churches and the area's tropical spice plantations.
Goa is a state in western India with coastlines stretching along the Arabian Sea. Its long history as a Portuguese colony prior to 1961 is evident in its preserved 17th-century churches and the area's tropical spice plantations.
Goa is a state in western India with coastlines stretching along the Arabian Sea. Its long history as a Portuguese colony prior to 1961 is evident in its preserved 17th-century churches and the area's tropical spice plantations.
Goa is a state in western India with coastlines stretching along the Arabian Sea. Its long history as a Portuguese colony prior to 1961 is evident in its preserved 17th-century churches and the area's tropical spice plantations.
Goa is a state in western India with coastlines stretching along the Arabian Sea. Its long history as a Portuguese colony prior to 1961 is evident in its preserved 17th-century churches and the area's tropical spice plantations.
Goa is a state in western India with coastlines stretching along the Arabian Sea. Its long history as a Portuguese colony prior to 1961 is evident in its preserved 17th-century churches and the area's tropical spice plantations.


Digital Mayhem
Damage from fireworks Congenital lobster foot Bad case of frostbitten fingers Decomposing toes Mangled right hand Pair of severed legs Deliberate mutilation by a meat grinder Fingers sliced by lawnmower Circular saw injury to left wrist


--- layout: default title: Home ---
Hey,I am Yongbo, a 28 years old frontend && backend dev from China. Feel free to follow me.
{{ post.content | strip_html | strip_newlines | truncate: 250 }}


This is a paragraph. Well, it's a useless paragraph, but a paragraph nonetheless. I don't like paragraphs.Look! I started a new line. I'm so smart.
If I use a separate p tag instead, it creates this weird gap in between the lines.