00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "config.h"
00040 #include <glib.h>
00041 #include <string.h>
00042
00043 #include "qof.h"
00044 #include "escape.h"
00045 #include "builder.h"
00046 #include "gnc-engine.h"
00047
00048 static QofLogModule log_module = GNC_MOD_BACKEND;
00049
00050
00051
00052 struct _builder {
00053 sqlBuild_QType qtype;
00054
00055
00056 char * ptag;
00057 char * pval;
00058
00059
00060 short tag_need_comma;
00061 short val_need_comma;
00062 short where_need_and;
00063
00064
00065 char * tag_base;
00066 char * val_base;
00067 size_t buflen;
00068
00069
00070 sqlEscape *escape;
00071 };
00072
00073
00074
00075 #define INITIAL_BUFSZ 16300
00076
00077 sqlBuilder *
00078 sqlBuilder_new (void)
00079 {
00080 sqlBuilder *b = g_new (sqlBuilder, 1);
00081
00082 b->qtype = SQL_INSERT;
00083
00084 b->tag_base = g_malloc (INITIAL_BUFSZ);
00085 b->val_base = g_malloc (INITIAL_BUFSZ);
00086 b->buflen = INITIAL_BUFSZ;
00087
00088 b->ptag = b->tag_base;
00089 b->pval = b->val_base;
00090
00091
00092 *(b->ptag) = 0x0;
00093 *(b->pval) = 0x0;
00094
00095 b->tag_need_comma = 0;
00096 b->val_need_comma = 0;
00097 b->where_need_and = 0;
00098
00099
00100 b->escape = sqlEscape_new ();
00101 return (b);
00102 }
00103
00104
00105
00106 void
00107 sqlBuilder_destroy (sqlBuilder *b)
00108 {
00109 if (!b) return;
00110 g_free (b->tag_base); b->tag_base = NULL;
00111 g_free (b->val_base); b->val_base = NULL;
00112 sqlEscape_destroy (b->escape); b->escape = NULL;
00113 g_free (b);
00114 }
00115
00116
00117
00118 void
00119 sqlBuild_Table (sqlBuilder *b, const char *tablename, sqlBuild_QType qt)
00120 {
00121 if (!b || !tablename) return;
00122 b->qtype = qt;
00123
00124 b->ptag = b->tag_base;
00125 b->pval = b->val_base;
00126
00127
00128 *(b->ptag) = 0x0;
00129 *(b->pval) = 0x0;
00130
00131 b->tag_need_comma = 0;
00132 b->val_need_comma = 0;
00133 b->where_need_and = 0;
00134
00135 switch (qt)
00136 {
00137 case SQL_INSERT:
00138 b->ptag = stpcpy(b->ptag, "INSERT INTO ");
00139 b->ptag = stpcpy(b->ptag, tablename);
00140 b->ptag = stpcpy(b->ptag, " (");
00141
00142 b->pval = stpcpy(b->pval, ") VALUES (");
00143 break;
00144
00145 case SQL_UPDATE:
00146 b->ptag = stpcpy(b->ptag, "UPDATE ");
00147 b->ptag = stpcpy(b->ptag, tablename);
00148 b->ptag = stpcpy(b->ptag, " SET ");
00149
00150 b->pval = stpcpy(b->pval, " WHERE ");
00151 break;
00152
00153 case SQL_SELECT:
00154 b->ptag = stpcpy(b->ptag, "SELECT ");
00155
00156 b->pval = stpcpy(b->pval, " FROM ");
00157 b->pval = stpcpy(b->pval, tablename);
00158 b->pval = stpcpy(b->pval, " WHERE ");
00159 break;
00160
00161 case SQL_DELETE:
00162 b->ptag = stpcpy(b->ptag, "DELETE ");
00163
00164 b->pval = stpcpy(b->pval, " FROM ");
00165 b->pval = stpcpy(b->pval, tablename);
00166 b->pval = stpcpy(b->pval, " WHERE ");
00167 break;
00168
00169 };
00170
00171 }
00172
00173
00174
00175
00176 void
00177 sqlBuild_Set_Str (sqlBuilder *b, const char *tag, const char *val)
00178 {
00179 if (!b || !tag) return;
00180 if (!val) val= "";
00181
00182 val = sqlEscapeString (b->escape, val);
00183
00184 if (b->tag_need_comma) b->ptag = stpcpy(b->ptag, ", ");
00185 b->tag_need_comma = 1;
00186
00187 switch (b->qtype)
00188 {
00189 case SQL_INSERT:
00190 b->ptag = stpcpy(b->ptag, tag);
00191
00192 if (b->val_need_comma) b->pval = stpcpy(b->pval, ", ");
00193 b->val_need_comma = 1;
00194 b->pval = stpcpy(b->pval, "'");
00195 b->pval = stpcpy(b->pval, val);
00196 b->pval = stpcpy(b->pval, "'");
00197 break;
00198
00199 case SQL_UPDATE:
00200 b->ptag = stpcpy(b->ptag, tag);
00201 b->ptag = stpcpy(b->ptag, "='");
00202 b->ptag = stpcpy(b->ptag, val);
00203 b->ptag = stpcpy(b->ptag, "' ");
00204 break;
00205
00206 case SQL_SELECT:
00207 b->ptag = stpcpy(b->ptag, tag);
00208 break;
00209
00210 case SQL_DELETE:
00211 break;
00212
00213 default:
00214 PERR ("mustn't happen");
00215 };
00216
00217 }
00218
00219
00220
00221 void
00222 sqlBuild_Set_Char (sqlBuilder *b, const char *tag, char val)
00223 {
00224 char buf[2];
00225 buf[0] = val;
00226 buf[1] = 0x0;
00227 sqlBuild_Set_Str (b, tag, buf);
00228 }
00229
00230
00231
00232 void
00233 sqlBuild_Set_GUID (sqlBuilder *b, const char *tag, const GUID *val)
00234 {
00235 if (val) {
00236 char guid_str[GUID_ENCODING_LENGTH+1];
00237 guid_to_string_buff(val, guid_str);
00238 sqlBuild_Set_Str (b, tag, guid_str);
00239 } else {
00240
00241 sqlBuild_Set_Str (b, tag, "");
00242 }
00243 }
00244
00245
00246
00247 void
00248 sqlBuild_Set_Date (sqlBuilder *b, const char *tag, Timespec ts)
00249 {
00250 char buf[120];
00251 gnc_timespec_to_iso8601_buff (ts, buf);
00252 sqlBuild_Set_Str (b, tag, buf);
00253 }
00254
00255
00256
00257 void
00258 sqlBuild_Set_Double (sqlBuilder *b, const char *tag, double flt)
00259 {
00260 char buf[120];
00261 snprintf (buf, 120, SQL_DBL_FMT, flt);
00262 sqlBuild_Set_Str (b, tag, buf);
00263 }
00264
00265
00266
00267 void
00268 sqlBuild_Set_Int64 (sqlBuilder *b, const char *tag, gint64 nval)
00269 {
00270 char val[100];
00271 if (!b || !tag) return;
00272
00273 snprintf (val, 100, "%" G_GINT64_FORMAT, nval);
00274 if (b->tag_need_comma) b->ptag = stpcpy(b->ptag, ", ");
00275 b->tag_need_comma = 1;
00276
00277 switch (b->qtype)
00278 {
00279 case SQL_INSERT:
00280 b->ptag = stpcpy(b->ptag, tag);
00281
00282 if (b->val_need_comma) b->pval = stpcpy(b->pval, ", ");
00283 b->val_need_comma = 1;
00284 b->pval = stpcpy(b->pval, val);
00285 break;
00286
00287 case SQL_UPDATE:
00288 b->ptag = stpcpy(b->ptag, tag);
00289 b->ptag = stpcpy(b->ptag, "=");
00290 b->ptag = stpcpy(b->ptag, val);
00291 break;
00292
00293 case SQL_SELECT:
00294 b->ptag = stpcpy(b->ptag, tag);
00295 break;
00296
00297 case SQL_DELETE:
00298 break;
00299
00300 default:
00301 PERR ("mustn't happen");
00302 };
00303 }
00304
00305
00306
00307 void
00308 sqlBuild_Set_Int32 (sqlBuilder *b, const char *tag, gint32 nval)
00309 {
00310 sqlBuild_Set_Int64 (b, tag, (gint64) nval);
00311 }
00312
00313
00314
00315 void
00316 sqlBuild_Where_Str (sqlBuilder *b, const char *tag, const char *val)
00317 {
00318 if (!b || !tag || !val) return;
00319
00320 switch (b->qtype)
00321 {
00322 case SQL_INSERT:
00323
00324 sqlBuild_Set_Str (b, tag, val);
00325 break;
00326
00327 case SQL_UPDATE:
00328 case SQL_SELECT:
00329 case SQL_DELETE:
00330 val = sqlEscapeString (b->escape, val);
00331
00332 if (b->where_need_and) b->pval = stpcpy(b->pval, " AND ");
00333 b->where_need_and = 1;
00334
00335 b->pval = stpcpy(b->pval, tag);
00336 b->pval = stpcpy(b->pval, "='");
00337 b->pval = stpcpy(b->pval, val);
00338 b->pval = stpcpy(b->pval, "'");
00339
00340 break;
00341
00342 default:
00343 PERR ("mustn't happen");
00344 };
00345 }
00346
00347
00348
00349 void
00350 sqlBuild_Where_GUID (sqlBuilder *b, const char *tag, const GUID *val)
00351 {
00352 char guid_str[GUID_ENCODING_LENGTH+1];
00353 guid_to_string_buff(val, guid_str);
00354 sqlBuild_Where_Str (b, tag, guid_str);
00355 }
00356
00357
00358
00359 void
00360 sqlBuild_Where_Int32 (sqlBuilder *b, const char *tag, gint32 val)
00361 {
00362 char str[40];
00363 snprintf (str, 40, "%d", val);
00364 sqlBuild_Where_Str (b, tag, str);
00365 }
00366
00367
00368
00369 const char *
00370 sqlBuild_Query (sqlBuilder *b)
00371 {
00372 if (!b) return NULL;
00373
00374 switch (b->qtype)
00375 {
00376 case SQL_INSERT:
00377 b->ptag = stpcpy(b->ptag, b->val_base);
00378 b->ptag = stpcpy(b->ptag, ");");
00379 break;
00380
00381 case SQL_UPDATE:
00382 case SQL_SELECT:
00383 case SQL_DELETE:
00384 b->ptag = stpcpy(b->ptag, b->val_base);
00385 b->ptag = stpcpy(b->ptag, ";");
00386 break;
00387
00388 default:
00389 PERR ("mustn't happen");
00390 };
00391
00392 PINFO ("%s\n", b->tag_base);
00393 return b->tag_base;
00394 }
00395
00396