You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gnucash/src/engine/sql/design.txt

144 lines
5.7 KiB

SQL Tables
----------
These mostly parallel the data structures in the gnc engine.
See table-create.sql for more info.
Session Table, Session Modes
----------------------------
There are four basic modes for accessing the database: "Single User
File Mode", "Single User Update Mode", "Polled Multi-User" and
"Event-Driven Multi-User". The session table in the database
indicates which mode the database is functioning.
-- "Single User File Mode" --
mode=single-file
Only one user can have access to the database at a time. The
database is used as a glorified file: engine data is 'saved' to
the database only when the user selects 'save' from the GUI
dialog. Just as it would be for a file, this mode erases the
contents of the database and over-writes it with the new data.
This mode exists because it is easy to implement, easy
to debug, and has reasonable demands on the database for small
datasets. It is not efficeint for large datasets, and has
a certain amount of risk in its use: because it erases the
old data before writing the new data, it is prone to any
problems during the 'save'. For example, if the database
crashes during the write (very unlikely), data could be lost.
If gnucash has some certain kind of bug (possible), not all
of the data may be saved. If gnucash crashes before a save,
then any changes since the last save would be lost.
This mode is mutually exclusive of any other access mode:
a lockout mechanism prevents other users from accessing the
database while it is open in single-user mode.
-- "Single User Update Mode" --
mode=single-update
Only one user can have access to the database at a time. Updates
to data are stored in the DB as they are made in the GUI; there
is no need to perform a mass-save at the end of a session.
This mode is more robust in that there is minimal/no data loss in
the event of a crash.
-- "Multi-User Polled" --
mode=multi-user-poll
Multiple users are assumed, GnuCash polls the database to detect
changes in the data. Partially Implemented.
-- "Multi-User Events" --
mode=multi-user
GnuCash uses the SQL LISTEN/NOTIFY async message delivery routines.
Not implemented.
Safety Lockout
--------------
There is a safety lockout that prevents a single-user mode database from
being accessed by another user, and from having a multi-user mode
database from being accessed by a single-user-mode client.
Session Design Notes
--------------------
The pgendSyncSingleFile() subroutine performs the equivalent of 'file
save'. Note that it does this by deleting the entire contents of the
database, and then writing out the entire contents of the engine. It
works this way (needs to work this way) in order to make sure that
deleted transactions,etc. are really deleted from the database. This
is because in this mode, the backend never finds out about deletions.
If you want incremental deletion, then use the 'Single Update' mode.
Connecting to Postgres
----------------------
The postgres API requires a database to connect to. The initial
connect is made using the "template1" database, which is the default
database that is always created when Postgres is installed. Thus,
we assume its always present.
m4 macros
---------
Some of the code is auto-gen'ed from m4 macros. This mostly just
simplifies some rather repetitive, cut-n-paste code that's identical
from function to function. If you can think of a better way ...
String escapes
--------------
Any string is valid; the builder.c routine sqlBuilder_escape() converts
single-quotes and backslashes to escaped quotes & backslashes to prevent
sql corruption.
KVP frames
----------
Storage of KVP values in the sql database is treated more or less as
described in the main KVP docs. The hierarchical structure is converted
into 'paths' by concatenating key names, and using / as the separator.
(Thus, paths look like file-paths). The root of each frame is
associated with a guid (and thus, a url kvp://12341234/some/kvp/keys,
where 12341234 is the guid).
The implementation caches the paths, associating a 32-bit inode number
with each path. Caching is done because the same path names will recur
frequently for different guids (e.g. /reconcile-info/last-date will
occur in most accounts).
The implementation also caches guids (associating a unique 32-bit int
with each), although the utility of this is a bit dubious. But hey, it
works. It saves a little bit of storage.
The actual values are stored in one of 6 different tables, depending on
the type. Note that the binary type and the glist type are not currently
implemented. The glist type could be implemented, as long as the glist
only stored strings ... The binary type could be implemented with blobs.
Version Numbers
---------------
Both the Account structure, and the Transaction structure, have version
numbers in them. These are used to compare the sql and the engine
contents, and update the one or the other as appropriate. Version
numbers would not be necessary for single-user access, but are important
for multi-user access, where several engines must be kept in sync with
the database contents. An alternative to version numbers might have
been the date of the last update. However, version numbers are better
than dates in the case where the engines reside on machines whose clocks
are not closely synchronized. (e.g. which may happen if the machines
are not using NTP for time synchronization; or, e.g. if one machine failed
to have daylight-savings time set correctly: its transactions would be
an hour newer/older than the others, leading to bad updates).
Balances
--------
UPDATE tx
SET (balance )= (SELECT expr from .... WHERE )
WHERE txdate between today - 7 and today