mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
documentation updates
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@742 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
0305aa09c6
commit
e2bbbee623
@ -48,8 +48,8 @@ The engine includes support for non-currency-denominated assets,
|
||||
such as stocks, bonds, mutual funds, inventory. This is done with
|
||||
two values in the Split structure:
|
||||
|
||||
double share_price;
|
||||
double damount;
|
||||
double share_price;
|
||||
double damount;
|
||||
|
||||
"damount" is the number of shares/items. It is an "immutable" quantity,
|
||||
in that it cannot change except by transfer (sale/purchase). It is the
|
||||
@ -67,17 +67,83 @@ Currency accounts should use a share price of 1.0 for all splits.
|
||||
To maintain the double-entry consistency, one must have the following
|
||||
hold true:
|
||||
|
||||
(source_split->damount) * (source_split->share_price) ==
|
||||
sum of all ((dest_split->damount) * (dest_split->share_price))
|
||||
0.0 ==
|
||||
(source_split->damount) * (source_split->share_price) +
|
||||
sum of all ((dest_split->damount) * (dest_split->share_price))
|
||||
|
||||
Thus, for example, the purchase of shares can be represented as:
|
||||
|
||||
source:
|
||||
debit ABC Bank for $1045 (1045 dollars * dollar "price" of 1.00)
|
||||
source:
|
||||
debit ABC Bank for $1045 (1045 dollars * dollar "price" of 1.00)
|
||||
|
||||
destination:
|
||||
credit PQR Stock for $1000 (100 shares at $10 per share)
|
||||
credit StockBroker category $45 in fees
|
||||
destination:
|
||||
credit PQR Stock for $1000 (100 shares at $10 per share)
|
||||
credit StockBroker category $45 in fees
|
||||
|
||||
|
||||
Error Reporting
|
||||
---------------
|
||||
The error reporting architecture (partially implemented), uses a globally
|
||||
visible subroutine to return an error. In the naivest possible implementation,
|
||||
the error reporting mechanism would look like this:
|
||||
|
||||
int error_num; /* global error number */
|
||||
|
||||
int xaccGetError (void) { return error_num; }
|
||||
|
||||
void xaccSomeFunction (Args *various_args) {
|
||||
if (bad_thing_happened) error_num = 42;
|
||||
}
|
||||
|
||||
Many programmers are used to a different interface, e.g.
|
||||
|
||||
int xaccSomeFunction (Args *various_args) {
|
||||
if (bad_thing_happened) return (42);
|
||||
}
|
||||
|
||||
Because of this, it is important to explain why the former design was choosen over
|
||||
the latter. Let us begin by listing how the choosen design is as good as, and in
|
||||
many ways can be better to the later design.
|
||||
|
||||
(1) Allows programmer to check for errors asynchronously, e.g. outside
|
||||
of a performance critical loop, or far away, after the return of
|
||||
several subroutines.
|
||||
(2) (with the right implementation) Allows reporting of multiple, complex
|
||||
errors. For example, it can be used to implement a trace mechanism.
|
||||
(3) (with the right implementation) Can be thread safe.
|
||||
(4) Allows errors that occurred deep in the implementation to be reported
|
||||
up to much higher levels without requireing bagagge inthe middle.
|
||||
|
||||
The right implementation for (2) is to implement not a single variable, but a stack
|
||||
or a ring (circular queue) on which error codes are placed, and from which error
|
||||
codes can be retreived. The right implementation for (3) is the use
|
||||
pthread_getspecific() to define a per-thread global and/or ring/queue.
|
||||
|
||||
|
||||
Engine Isolation
|
||||
----------------
|
||||
Some half-finished thoughts about the engine API:
|
||||
|
||||
-- The engine structures should not be accessible to any code outside of the engine.
|
||||
Thus, the engine structures have been moved to AccountP.h, TransactionP.h, etc.
|
||||
The *P.h files should not be included by code outside of the engine.
|
||||
|
||||
-- The goal of hiding the engine internals behind an API is to allow the engine
|
||||
to be replaced by a variety of back ends, e.g. an SQL and/or CORBA back-end.
|
||||
|
||||
-- The down-side of hiding is that it can hurt performance. Even trivial data
|
||||
accesses require a subroutine call. Maybe a smarter idea would be to leave
|
||||
the structures exposed, allow direct manipulation, and then "copy-in" and
|
||||
"copy-out" the structures into parallel structures when a hidden back end
|
||||
needs to be invoked.
|
||||
|
||||
-- the upside of hiding behind an API is that the engine can be instrumented
|
||||
with extension language (perl, scheme, tcl, python) hooks for pre/post processing
|
||||
of the data. To further enable such hooks, we should probably surround all
|
||||
operations on structures with "begin-edit" and "end-edit" calls.
|
||||
|
||||
-- begin/end braces could potentially be useful for two-phase commit schemes.
|
||||
where "end-edit" is replaced by "commeit-edit" or "reject-edit".
|
||||
|
||||
|
||||
|
||||
@ -89,4 +155,4 @@ big banks use this for various consistency reasons.
|
||||
|
||||
|
||||
|
||||
|
||||
March 1998
|
||||
|
Loading…
Reference in New Issue
Block a user