~ubuntu-branches/ubuntu/hoary/gnucash/hoary

« back to all changes in this revision

Viewing changes to src/engine/sql/table.m4

  • Committer: Bazaar Package Importer
  • Author(s): James A. Treacy
  • Date: 2002-03-16 14:14:59 UTC
  • Revision ID: james.westby@ubuntu.com-20020316141459-wtkyyrpfovryhl1s
Tags: upstream-1.6.6
ImportĀ upstreamĀ versionĀ 1.6.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
divert(-1)
 
3
changecom(`/*', `*/')
 
4
 
 
5
/* data dictionary for the gnucash tables */
 
6
/* sql table description and manipulation macros */
 
7
 
 
8
define(`account', `gncAccount, Account, Account, a,
 
9
       accountName,    , char *, xaccAccountGetName(ptr),
 
10
       accountCode,    , char *, xaccAccountGetCode(ptr),
 
11
       description,    , char *, xaccAccountGetDescription(ptr),
 
12
       type,           , char *, xaccAccountTypeEnumAsString(xaccAccountGetType(ptr)),
 
13
       commodity,      , char *, gnc_commodity_get_unique_name(xaccAccountGetCommodity(ptr)),
 
14
       version,        , int32,  xaccAccountGetVersion(ptr),
 
15
       parentGUID,     , GUID *, xaccAccountGetGUID(xaccAccountGetParentAccount(ptr)),
 
16
       accountGUID, KEY, GUID *, xaccAccountGetGUID(ptr),
 
17
       ')
 
18
 
 
19
define(`split', `gncEntry, Split, Split, e,
 
20
       accountGUID,     , GUID *,   xaccAccountGetGUID(xaccSplitGetAccount(ptr)),
 
21
       transGUID,       , GUID *,   xaccTransGetGUID(xaccSplitGetParent(ptr)),
 
22
       memo,            , char *,   xaccSplitGetMemo(ptr),
 
23
       action,          , char *,   xaccSplitGetAction(ptr),
 
24
       reconciled,      , char,     xaccSplitGetReconcile(ptr),
 
25
       date_reconciled, , Timespec, xaccSplitRetDateReconciledTS(ptr),
 
26
       amount,          , int64,    gnc_numeric_num(xaccSplitGetAmount(ptr)),
 
27
       value,           , int64,    gnc_numeric_num(xaccSplitGetValue(ptr)),
 
28
       entryGUID,    KEY, GUID *,   xaccSplitGetGUID(ptr),
 
29
       ')
 
30
 
 
31
/* note that for the last_modified, we use the sql database     */
 
32
/* notion of 'current time'. This should help prevent clock     */
 
33
/* skew problems between different simultaneous users           */
 
34
/* Note also this means that the table entry is not             */
 
35
/* last_modified,    , Timespec, xaccTransRetDateModifiedTS(ptr), */
 
36
/* as one might have guessed                                    */
 
37
 
 
38
define(`transaction', `gncTransaction, Transaction, Transaction, t,
 
39
       num,            , char *,   xaccTransGetNum(ptr),
 
40
       description,    , char *,   xaccTransGetDescription(ptr),
 
41
       currency,       , commod,   gnc_commodity_get_unique_name(xaccTransGetCurrency(ptr)),
 
42
       last_modified,  , now,      "NOW",
 
43
       date_entered,   , Timespec, xaccTransRetDateEnteredTS(ptr),
 
44
       date_posted,    , Timespec, xaccTransRetDatePostedTS(ptr),
 
45
       version,        , int32,    xaccTransGetVersion(ptr),
 
46
       transGUID,   KEY, GUID *,   xaccTransGetGUID(ptr),
 
47
       ')
 
48
 
 
49
 
 
50
define(`modity', `gncCommodity, Commodity, gnc_commodity, c,
 
51
       namespace,    , char *, gnc_commodity_get_namespace(ptr),
 
52
       fullname,     , char *, gnc_commodity_get_fullname(ptr),
 
53
       mnemonic,     , char *, gnc_commodity_get_mnemonic(ptr),
 
54
       code,         , char *, gnc_commodity_get_exchange_code(ptr),
 
55
       fraction,     , int32,  gnc_commodity_get_fraction(ptr),
 
56
       commodity, KEY, char *, gnc_commodity_get_unique_name(ptr),
 
57
       ')
 
58
       
 
59
 
 
60
define(`price', `gncPrice, Price, GNCPrice, p,
 
61
       commodity,    , commod,   gnc_commodity_get_unique_name(gnc_price_get_commodity(ptr)),
 
62
       currency,     , commod,   gnc_commodity_get_unique_name(gnc_price_get_currency(ptr)),
 
63
       time,         , Timespec, gnc_price_get_time(ptr),
 
64
       source,       , char *,   gnc_price_get_source(ptr),
 
65
       type,         , char *,   gnc_price_get_type(ptr),
 
66
       valueNum,     , int64,    gnc_numeric_num(gnc_price_get_value(ptr)),
 
67
       valueDenom,   , int64,    gnc_numeric_denom(gnc_price_get_value(ptr)),
 
68
       version,      , int32,    gnc_price_get_version(ptr),
 
69
       priceGUID, KEY, GUID *,   gnc_price_get_guid(ptr),
 
70
       ')
 
71
       
 
72
 
 
73
define(`checkpoint', `gncCheckpoint, Checkpoint, Checkpoint, x,
 
74
       balance,             , int64,    ptr->balance,
 
75
       cleared_balance,     , int64,    ptr->cleared_balance,
 
76
       reconciled_balance,  , int64,    ptr->reconciled_balance,
 
77
       date_start,          , Timespec, ptr->date_start,
 
78
       date_end,            , Timespec, ptr->date_end,
 
79
       commodity,           , char *,   ptr->commodity,
 
80
       accountGuid,         , GUID *,   ptr->account_guid,
 
81
       ')
 
82
       
 
83
 
 
84
define(`session', `gncSession, Session, void, x,
 
85
       session_mode,        , char *, pgendSessionGetMode(be),
 
86
       hostname,            , char *, pgendGetHostname(be),
 
87
       login_name,          , char *, pgendGetUsername(be),
 
88
       gecos,               , char *, pgendGetUserGecos(be),
 
89
       time_on,             , now,    "NOW",
 
90
       time_off,            , now,    "INFINITY",
 
91
       sessionGUID,      KEY, GUID *, be->sessionGuid,
 
92
       ')
 
93
       
 
94
define(`kvp_gint64', `gncKVPvalue_int64, KVPint64, store_data_t, k,
 
95
       type,                , char *, ptr->stype,
 
96
       data,                , int64,  ptr->u.ival,
 
97
       iguid,            KEY, int32,  ptr->iguid,
 
98
       ipath,            KEY, int32,  ptr->ipath,
 
99
       ')
 
100
       
 
101
 
 
102
define(`kvp_double', `gncKVPvalue_dbl, KVPdouble, store_data_t, k,
 
103
       type,                , char *, ptr->stype,
 
104
       data,                , double, ptr->u.dbl,
 
105
       iguid,            KEY, int32,  ptr->iguid,
 
106
       ipath,            KEY, int32,  ptr->ipath,
 
107
       ')
 
108
       
 
109
define(`kvp_numeric', `gncKVPvalue_numeric, KVPnumeric, store_data_t, k,
 
110
       type,                , char *, ptr->stype,
 
111
       num,                 , int64,  ptr->u.numeric.num,
 
112
       denom,               , int64,  ptr->u.numeric.denom,
 
113
       iguid,            KEY, int32,  ptr->iguid,
 
114
       ipath,            KEY, int32,  ptr->ipath,
 
115
       ')
 
116
       
 
117
define(`kvp_string', `gncKVPvalue_str, KVPstring, store_data_t, k,
 
118
       type,                , char *, ptr->stype,
 
119
       data,                , char *, ptr->u.str,
 
120
       iguid,            KEY, int32,  ptr->iguid,
 
121
       ipath,            KEY, int32,  ptr->ipath,
 
122
       ')
 
123
       
 
124
define(`kvp_guid', `gncKVPvalue_guid, KVPguid, store_data_t, k,
 
125
       type,                , char *, ptr->stype,
 
126
       data,                , char *, ptr->u.str,
 
127
       iguid,            KEY, int32,  ptr->iguid,
 
128
       ipath,            KEY, int32,  ptr->ipath,
 
129
       ')
 
130
       
 
131
/* ------------------------------------------------------- */
 
132
/* symbolic names for the table accessors */
 
133
define(`tablename', $1)
 
134
define(`func_name', $2)
 
135
define(`xacc_type', $3)
 
136
define(`obj_type',  $4)
 
137
 
 
138
define(`firstrec', `shift(shift(shift(shift($@))))')
 
139
define(`nextrec', `shift(shift(shift(shift($@))))')
 
140
 
 
141
/* -------- */
 
142
/* macros that use the sql builder to build a query */
 
143
 
 
144
define(`sql_setter', `ifelse($2, `KEY',
 
145
                     `ifelse($1, `char *',   sqlBuild_Where_Str,
 
146
                             $1, `int32',    sqlBuild_Where_Int32,
 
147
                             $1, `GUID *',   sqlBuild_Where_GUID)',
 
148
 
 
149
                             $2,     ,
 
150
                     `ifelse($1, `char *',   sqlBuild_Set_Str,
 
151
                             $1, `now',      sqlBuild_Set_Str,
 
152
                             $1, `commod',   sqlBuild_Set_Str,
 
153
                             $1, `double',   sqlBuild_Set_Double,
 
154
                             $1, `int32',    sqlBuild_Set_Int32,
 
155
                             $1, `int64',    sqlBuild_Set_Int64,
 
156
                             $1, `GUID *',   sqlBuild_Set_GUID,
 
157
                             $1, `Timespec', sqlBuild_Set_Date,
 
158
                             $1, `char',     sqlBuild_Set_Char)')')
 
159
 
 
160
 
 
161
/* recursively walk the table, build the builders */
 
162
 
 
163
define(`set_fields_r', `ifelse($#, 1, , 
 
164
`   sql_setter($3,$2) (be->builder, "$1", $4);
 
165
set_fields_r(nextrec($@))')')
 
166
 
 
167
define(`set_fields', `set_fields_r(firstrec($@))')
 
168
 
 
169
/* -------- */
 
170
/* macros to compare a query result */
 
171
/* the commod type behaves just like a string, except it 
 
172
 * has its one compre function.  */
 
173
 
 
174
define(`cmp_value', `ifelse($1, `char *',   COMP_STR,
 
175
                            $1, `now',      COMP_NOW,
 
176
                            $1, `int32',    COMP_INT32,
 
177
                            $1, `int64',    COMP_INT64,
 
178
                            $1, `double',   COMP_DOUBLE,
 
179
                            $1, `GUID *',   COMP_GUID,
 
180
                            $1, `commod',   COMP_COMMODITY,
 
181
                            $1, `Timespec', COMP_DATE,
 
182
                            $1, `char',     COMP_CHAR)')
 
183
 
 
184
/* recursively walk the table, build compare functions,
 
185
 * but only for non-primary-keys */
 
186
 
 
187
define(`cmp_fields_r', `ifelse($#, 1, , 
 
188
`ifelse($2, `KEY',  ,
 
189
`    cmp_value($3,$2) ("$1", $4, ndiffs);
 
190
cmp_fields_r(nextrec($@))')')')
 
191
 
 
192
define(`cmp_fields', `cmp_fields_r(firstrec($@))')
 
193
 
 
194
/* -------- */
 
195
/* return the name of the sql field associcate with the primary key */
 
196
 
 
197
define(`key_fieldname_r', `ifelse($#, 1, , 
 
198
`ifelse($2, `KEY', $1,
 
199
`key_fieldname_r(nextrec($@))')')')
 
200
 
 
201
define(`key_fieldname', `key_fieldname_r(firstrec($@))')
 
202
 
 
203
/* -------- */
 
204
/* return the getter function that deals with the version number */
 
205
define(`version_function_r', `ifelse($#, 1, , 
 
206
`ifelse($1, `version', $4,
 
207
`version_function_r(nextrec($@))')')')
 
208
 
 
209
define(`version_function', `version_function_r(firstrec($@))')
 
210
 
 
211
/* -------- */
 
212
 
 
213
define(`store_one_only', 
 
214
`
 
215
/* ------------------------------------------------------ */
 
216
/* This routine stores/updates one record in the database.
 
217
 * It does not do any traversals, it does not lock.  
 
218
 * It just pokes the data in.
 
219
 */
 
220
 
 
221
void 
 
222
pgendStoreOne`'func_name($@)`'Only (PGBackend *be,
 
223
                     xacc_type($@) *ptr,
 
224
                     sqlBuild_QType update)
 
225
{
 
226
   const char *buf;
 
227
   ENTER ("be=%p, xacc_type($@)=%p", be, ptr);
 
228
   if (!be || !ptr) return;
 
229
 
 
230
   /* build the sql query */
 
231
   sqlBuild_Table (be->builder, "tablename($@)", update);
 
232
   set_fields($@)
 
233
 
 
234
   buf = sqlBuild_Query (be->builder);
 
235
   SEND_QUERY (be,buf, );
 
236
 
 
237
   /* complete/commit the transaction, check the status */
 
238
   FINISH_QUERY(be->connection);
 
239
   LEAVE (" ");
 
240
}
 
241
 
 
242
')
 
243
 
 
244
define(`compare_one_only', 
 
245
`
 
246
/* ------------------------------------------------------ */
 
247
/* This routine returns a positive int if the indicated object
 
248
 * differs from that in the SQL database.  It returns negative
 
249
 * number if theres an error.
 
250
 * It does not do any traversals, it does not lock.  
 
251
 */
 
252
 
 
253
int
 
254
pgendCompareOne`'func_name($@)`'Only (PGBackend *be, xacc_type($@) *ptr)
 
255
{
 
256
   const char *buf;
 
257
   PGresult *result;
 
258
   int i=0, nrows=0, ndiffs=0;
 
259
 
 
260
   ENTER ("be=%p, xacc_type($@)=%p", be, ptr);
 
261
   if (!be || !ptr) return -1;
 
262
 
 
263
   /* build the sql query */
 
264
   sqlBuild_Table (be->builder, "tablename($@)", SQL_SELECT);
 
265
   set_fields($@)
 
266
 
 
267
   buf = sqlBuild_Query (be->builder);
 
268
   SEND_QUERY (be,buf, -1);
 
269
 
 
270
   i=0; nrows=0;
 
271
   do {
 
272
      GET_RESULTS (be->connection, result);
 
273
      IF_ONE_ROW (result, nrows, i) {
 
274
 
 
275
         /* compared queried values to input values */
 
276
         cmp_fields($@)
 
277
      }
 
278
 
 
279
      PQclear (result);
 
280
      i++;
 
281
   } while (result);
 
282
 
 
283
   if (0 == nrows) ndiffs = -1;
 
284
   LEAVE ("ndiffs=%d", ndiffs);
 
285
   return ndiffs;
 
286
}
 
287
 
 
288
')
 
289
 
 
290
define(`put_one_only', 
 
291
`
 
292
/* ------------------------------------------------------ */
 
293
/* This routine inserts or updates, as appropriate
 
294
 * It does not do any traversals, it does not lock.  
 
295
 * It just updates.
 
296
 */
 
297
 
 
298
void 
 
299
pgendPutOne`'func_name($@)`'Only (PGBackend *be, xacc_type($@) *ptr)
 
300
{
 
301
   int ndiffs;
 
302
   ndiffs = pgendCompareOne`'func_name($@)`'Only (be, ptr);
 
303
 
 
304
   /* update the record if there are differences ... */
 
305
   if (0<ndiffs) 
 
306
   {
 
307
      pgendStoreOne`'func_name($@)`'Only (be, ptr, SQL_UPDATE);
 
308
      pgendStoreAudit`'func_name($@)`' (be, ptr, SQL_UPDATE);
 
309
   }
 
310
   /* insert the record if it doesnt exist */
 
311
   if (0>ndiffs)
 
312
   {
 
313
      pgendStoreOne`'func_name($@)`'Only (be, ptr, SQL_INSERT);
 
314
      pgendStoreAudit`'func_name($@)`' (be, ptr, SQL_INSERT);
 
315
   }
 
316
}
 
317
 
 
318
')
 
319
 
 
320
define(`compare_version', 
 
321
`
 
322
/* ------------------------------------------------------ */
 
323
/* This routine compares the version number of the object in 
 
324
 * the engine and the sql database. It returns a negative 
 
325
 * number if the sql version is older (or the item is not 
 
326
 * present in the sql db). It returns a positive number
 
327
 * if the sql version is newer.  It returns zero if the
 
328
 * two are equal.
 
329
 */
 
330
 
 
331
int 
 
332
pgend`'func_name($@)`'CompareVersion (PGBackend *be, xacc_type($@) *ptr)
 
333
{
 
334
   char *p;
 
335
   int sql_version = 0;
 
336
 
 
337
   p = be->buff; *p = 0;
 
338
   p = stpcpy (p, "SELECT version FROM tablename($@) WHERE key_fieldname($@) = ''`");
 
339
   p = guid_to_string_buff (&(ptr->guid), p);
 
340
   p = stpcpy (p, "''`;");
 
341
   SEND_QUERY (be,be->buff, -1);
 
342
   sql_version = (int) pgendGetResults (be, get_version_cb, (gpointer) -1);
 
343
 
 
344
   if (-1 == sql_version) return -1;
 
345
   return (sql_version - version_function($@));
 
346
}
 
347
 
 
348
')
 
349
 
 
350
define(`is_deleted',
 
351
`
 
352
/* ------------------------------------------------------ */
 
353
/* This routine looks at the audit trail to see if the
 
354
 * indicated object has been deleted. If it has been,
 
355
 * it returns the version number of the deleted object;
 
356
 * otherwise it returns -1.
 
357
 */ 
 
358
 
 
359
int 
 
360
pgend`'func_name($@)`'GetDeletedVersion (PGBackend *be, xacc_type($@) *ptr)
 
361
{
 
362
   char *p;
 
363
   int sql_version = -1;
 
364
 
 
365
   p = be->buff; *p = 0;
 
366
   p = stpcpy (p, "SELECT version FROM tablename($@)" "Trail WHERE key_fieldname($@) = ''`");
 
367
   p = guid_to_string_buff (&(ptr->guid), p);
 
368
   p = stpcpy (p, "''` AND change = ''`d''`;");
 
369
   SEND_QUERY (be,be->buff, -1);
 
370
   sql_version = (int) pgendGetResults (be, get_version_cb, (gpointer) -1);
 
371
 
 
372
   return sql_version;
 
373
}
 
374
 
 
375
')
 
376
 
 
377
define(`store_audit', 
 
378
`
 
379
/* ------------------------------------------------------ */
 
380
/* This routine stores one autdit record in the database.
 
381
 * It does not do any traversals, it does not lock.  
 
382
 * It just pokes the data in. 
 
383
 */
 
384
 
 
385
void 
 
386
pgendStoreAudit`'func_name($@)`' (PGBackend *be,
 
387
                     xacc_type($@) *ptr,
 
388
                     sqlBuild_QType update)
 
389
{
 
390
   const char *buf;
 
391
   ENTER ("be=%p, xacc_type($@)=%p", be, ptr);
 
392
   if (!be || !ptr) return;
 
393
 
 
394
   /* build the sql query */
 
395
   sqlBuild_Table (be->builder, "tablename($@)" "Trail", SQL_INSERT);
 
396
#define sqlBuild_Where_Str sqlBuild_Set_Str
 
397
#define sqlBuild_Where_GUID sqlBuild_Set_GUID
 
398
#define sqlBuild_Where_Int32 sqlBuild_Set_Int32
 
399
   set_fields($@)
 
400
#undef sqlBuild_Where_Str
 
401
#undef sqlBuild_Where_GUID
 
402
#undef sqlBuild_Where_Int32
 
403
   sqlBuild_Set_Str (be->builder, "date_changed", "NOW");
 
404
   /* sqlBuild_Set_GUID (be->builder, "sessionGUID", be->sessionGuid); */
 
405
   sqlBuild_Set_Str (be->builder, "sessionGUID", be->session_guid_str);
 
406
   sqlBuild_Set_Char (be->builder, "change", update);
 
407
   sqlBuild_Set_Char (be->builder, "objtype", ''`obj_type($@)''`);
 
408
 
 
409
   buf = sqlBuild_Query (be->builder);
 
410
   SEND_QUERY (be,buf, );
 
411
 
 
412
   /* complete/commit the transaction, check the status */
 
413
   FINISH_QUERY(be->connection);
 
414
   LEAVE (" ");
 
415
}
 
416
 
 
417
')
 
418
 
 
419
divert
 
420
/* DO NOT EDIT THIS FILE -- it is autogenerated -- edit table.m4 instead */