source: sources/src/dataBaseSqlite.cc @ 1500:872b0b69e0d5

Revision 1500:872b0b69e0d5, 31.0 KB checked in by niam, 12 months ago (diff)

{issue #103} added implementation of sl- and dl- lists

Line 
1/***************************************************************************
2 *            dataBaseSqlite.cc
3 *
4 *  Thu Apr  30 2005
5 *  Copyright  2005  Dmytro Milinevskyy
6 *  milinevskyy@gmail.com
7 ****************************************************************************/
8
9/*
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License version 2.1 as published by
12 *  the Free Software Foundation;
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Lesser General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24/**
25 * vim indentation settings
26 * set tabstop=4
27 * set shiftwidth=4
28 */
29
30#include <libdodo/directives.h>
31
32#ifdef SQLITE3_EXT
33#include <sqlite3.h>
34#include <string.h>
35
36#include <libdodo/dataBaseSqlite.h>
37#include <libdodo/toolsMisc.h>
38#include <libdodo/dataBaseSqliteEx.h>
39#include <libdodo/xexec.h>
40#include <libdodo/toolsString.h>
41
42namespace dodo {
43    namespace data {
44        namespace base {
45            /**
46             * @struct __sqlite__
47             * @brief defines internal handlers for SQLite DBMS interaction
48             */
49            struct __sqlite__ {
50                /**
51                 * constructor
52                 */
53                __sqlite__() : handle(NULL),
54                               result(NULL)
55                {
56                }
57
58                sqlite3        *handle; ///< DB handle
59                sqlite3_stmt   *result; ///< handlde to result
60            };
61        };
62    };
63};
64
65using namespace dodo::data::base;
66
67sqlite::__connection_options__::__connection_options__(const dodo::string &path) : path(path)
68{
69}
70
71//-------------------------------------------------------------------
72
73sqlite::__connection_options__::__connection_options__()
74{
75}
76
77//-------------------------------------------------------------------
78
79sqlite::sqlite() : handle(new __sqlite__)
80{
81#ifndef DATABASE_WO_XEXEC
82    collectedData.setExecObject(xexec::OBJECT_DATABASESQLITE);
83#endif
84}
85
86//-------------------------------------------------------------------
87
88sqlite::sqlite(const data::base::__connection_options__ &a_info) : handle(new __sqlite__),
89                                                         info(*dynamic_cast<const sqlite::__connection_options__ *>(&a_info))
90{
91#ifndef DATABASE_WO_XEXEC
92    collectedData.setExecObject(xexec::OBJECT_DATABASESQLITE);
93#endif
94
95    dodo_try {
96        if (sqlite3_open(info.path.data(), &handle->handle) != SQLITE_OK) {
97            sqlite3_close(handle->handle);
98
99            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_SQLITE, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
100        }
101    } dodo_catch (exception::basic *e UNUSED) {
102        delete handle;
103
104        dodo_rethrow;
105    }
106}
107
108//-------------------------------------------------------------------
109
110sqlite::sqlite(sqlite &)
111{
112}
113
114//-------------------------------------------------------------------
115
116sqlite::~sqlite()
117{
118    if (handle->handle != NULL) {
119        if (handle->result)
120            sqlite3_finalize(handle->result);
121
122        sqlite3_close(handle->handle);
123    }
124
125    delete handle;
126}
127
128//-------------------------------------------------------------------
129
130void
131sqlite::connect(const data::base::__connection_options__ &a_info)
132{
133    info = *dynamic_cast<const sqlite::__connection_options__ *>(&a_info);
134
135#ifndef DATABASE_WO_XEXEC
136    performPreExec(OPERATION_CONNECT);
137#endif
138
139    if (handle->handle != NULL) {
140        if (handle->result) {
141            sqlite3_finalize(handle->result);
142            handle->result = NULL;
143        }
144
145        if (sqlite3_close(handle->handle) != SQLITE_OK)
146            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_CONNECT, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
147
148        handle->handle = NULL;
149    }
150
151    if (sqlite3_open(info.path.data(), &handle->handle) != SQLITE_OK) {
152        sqlite3_close(handle->handle);
153
154        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_CONNECT, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
155    }
156
157#ifndef DATABASE_WO_XEXEC
158    performPostExec(OPERATION_CONNECT);
159#endif
160}
161
162//-------------------------------------------------------------------
163
164void
165sqlite::disconnect()
166{
167    if (handle->handle != NULL) {
168#ifndef DATABASE_WO_XEXEC
169        performPreExec(OPERATION_DISCONNECT);
170#endif
171
172        if (handle->result) {
173            sqlite3_finalize(handle->result);
174            handle->result = NULL;
175        }
176
177        if (sqlite3_close(handle->handle) != SQLITE_OK)
178            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_DISCONNECT, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
179
180#ifndef DATABASE_WO_XEXEC
181        performPostExec(OPERATION_DISCONNECT);
182#endif
183
184        handle->handle = NULL;
185    }
186}
187
188//-------------------------------------------------------------------
189
190void
191sqlite::fetchedRows(data::base::rows &a_rows) const
192{
193    sql::rows *rows = dynamic_cast<sql::rows *>(&a_rows);
194
195    if (handle->handle == NULL || handle->result == NULL)
196        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_FETCHEDROWS, exception::ERRNO_LIBDODO, SQLITEEX_NOTOPENED, DATABASESQLITEEX_NOTOPENED_STR, __LINE__, __FILE__);
197
198#ifndef DATABASE_WO_XEXEC
199    performPreExec(OPERATION_FETCHEDROWS);
200#endif
201
202    rows->fields.clear();
203    rows->values.clear();
204
205    sqlite3_reset(handle->result);
206
207    unsigned int numFields = sqlite3_column_count(handle->result);
208
209    if (numFields == 0)
210        return;
211
212    bool iterate = true;
213    unsigned int i = 0;
214
215    rows->fields.reserve(numFields);
216
217    for (i = 0; i < numFields; ++i)
218        rows->fields.push_back(sqlite3_column_name(handle->result, i));
219
220    dodoStringArray values;
221
222    while (iterate) {
223        switch (sqlite3_step(handle->result)) {
224            case SQLITE_BUSY:
225
226                continue;
227
228            case SQLITE_DONE:
229
230                iterate = false;
231
232                break;
233
234            case SQLITE_ERROR:
235
236                dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_FETCHEDROWS, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
237
238            case SQLITE_ROW:
239
240                values.clear();
241                values.reserve(numFields);
242
243                for (i = 0; i < numFields; ++i) {
244                    switch (sqlite3_column_type(handle->result, i)) {
245                        case SQLITE_INTEGER:
246
247                            values.push_back(tools::string::iToString(sqlite3_column_int(handle->result, i)));
248
249                            break;
250
251                        case SQLITE_FLOAT:
252
253                            values.push_back(tools::string::dToString(sqlite3_column_double(handle->result, i)));
254
255                            break;
256
257                        case SQLITE_TEXT:
258
259                            values.push_back(dodo::string((const char *)sqlite3_column_text(handle->result, i), sqlite3_column_bytes(handle->result, i)));
260
261                            break;
262
263                        case SQLITE_BLOB:
264
265                            values.push_back(dodo::string((const char *)sqlite3_column_blob(handle->result, i), sqlite3_column_bytes(handle->result, i)));
266
267                            break;
268
269                        case SQLITE_NULL:
270                        default:
271
272                            values.push_back(statements[STATEMENT_NULL]);
273
274                            break;
275                    }
276                }
277
278                rows->values.push_back(values);
279
280                break;
281        }
282    }
283
284#ifndef DATABASE_WO_XEXEC
285    performPostExec(OPERATION_FETCHEDROWS);
286#endif
287}
288
289//-------------------------------------------------------------------
290
291unsigned int
292sqlite::fetchedRows() const
293{
294    if (handle->result == NULL)
295        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_FETCHEDROWS, exception::ERRNO_LIBDODO, SQLITEEX_NOTOPENED, DATABASESQLITEEX_NOTOPENED_STR, __LINE__, __FILE__);
296
297    sqlite3_reset(handle->result);
298
299    if (sqlite3_column_count(handle->result) == 0) /// FIXME: dodo_throw exception?
300        return 0;
301
302    bool iterate = true;
303    unsigned int numRows = 0;
304
305    while (iterate) {
306        switch (sqlite3_step(handle->result)) {
307            case SQLITE_BUSY:
308
309                continue;
310
311            case SQLITE_DONE:
312
313                iterate = false;
314
315                break;
316
317            case SQLITE_ERROR:
318
319                dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_FETCHEDROWS, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
320
321            case SQLITE_ROW:
322
323                ++numRows;
324
325                break;
326        }
327    }
328
329    return numRows;
330}
331
332//-------------------------------------------------------------------
333
334unsigned int
335sqlite::affectedRows() const
336{
337    if (handle->handle == NULL)
338        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_AFFECTEDROWS, exception::ERRNO_LIBDODO, SQLITEEX_NOTOPENED, DATABASESQLITEEX_NOTOPENED_STR, __LINE__, __FILE__);
339
340    return sqlite3_changes(handle->handle);
341}
342
343//-------------------------------------------------------------------
344
345void
346sqlite::requestFieldsTypes(const dodo::string &table)
347{
348    if (handle->handle == NULL)
349        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_LIBDODO, SQLITEEX_NOTOPENED, DATABASESQLITEEX_NOTOPENED_STR, __LINE__, __FILE__);
350
351    dodoMap<dodo::string, dodoMap<dodo::string, short, dodoMapICaseStringCompare>, dodoMapICaseStringCompare>::iterator types = fieldTypes.find(table);
352
353    if (types == fieldTypes.end())
354        types = fieldTypes.insert(std::make_pair(table, dodoMap<dodo::string, short, dodoMapICaseStringCompare>())).first;
355
356    if (handle->result) {
357        sqlite3_finalize(handle->result);
358        handle->result = NULL;
359    }
360
361#ifdef SQLITE_ENABLE_COLUMN_METADATA
362    dodo::string request = "select * from " + table + " limit 1";
363
364    if (sqlite3_prepare(handle->handle, request.data(), request.size(), &handle->result, NULL) != SQLITE_OK)
365        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__, request);
366
367    if (handle->result == NULL)
368        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
369
370    unsigned int numFields = sqlite3_column_count(handle->result);
371
372    const char *columnType, *columnName;
373
374    dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator field, fieldsEnd = types->second.end();
375
376    for (unsigned int i(0); i < numFields; ++i) {
377        columnName = sqlite3_column_name(handle->result, i);
378
379        if (sqlite3_table_column_metadata(handle->handle,
380                                          NULL,
381                                          table.data(),
382                                          columnName,
383                                          &columnType,
384                                          NULL,
385                                          NULL,
386                                          NULL,
387                                          NULL) != SQLITE_OK) {
388            sqlite3_finalize(handle->result);
389
390            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__, request);
391        }
392
393        field = types->second.find(columnName);
394
395        if (field == fieldsEnd) {
396            if (strcasestr(columnType, "char") != NULL ||
397                strcasestr(columnType, "date") != NULL ||
398                strcasestr(columnType, "time") != NULL ||
399                strcasestr(columnType, "text") != NULL ||
400                strcasestr(columnType, "enum") != NULL ||
401                strcasestr(columnType, "set") != NULL)
402                types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_TEXT));
403            else {
404                if (strcasestr(columnType, "blob") != NULL)
405                    types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_BINARY));
406                else
407                    types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_NUMERIC));
408            }
409        } else {
410            if (strcasestr(columnType, "char") != NULL ||
411                strcasestr(columnType, "date") != NULL ||
412                strcasestr(columnType, "time") != NULL ||
413                strcasestr(columnType, "text") != NULL ||
414                strcasestr(columnType, "enum") != NULL ||
415                strcasestr(columnType, "set") != NULL)
416                field->second = sql::FIELD_TEXT;
417            else {
418                if (strcasestr(columnType, "blob") != NULL)
419                    field->second = sql::FIELD_BINARY;
420                else
421                    field->second = sql::FIELD_NUMERIC;
422            }
423        }
424    }
425#else
426    dodo::string request = "pragma table_info(" + table + ")";
427
428    if (sqlite3_prepare(handle->handle, request.data(), request.size(), &handle->result, NULL) != SQLITE_OK)
429        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__, request);
430
431    if (handle->result == NULL)
432        dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
433
434    bool iterate = true;
435
436    const char *columnType, *columnName;
437
438    dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator field, fieldsEnd = types->second.end();
439
440    while (iterate) {
441        switch (sqlite3_step(handle->result)) {
442            case SQLITE_BUSY:
443
444                continue;
445
446            case SQLITE_DONE:
447
448                iterate = false;
449
450                break;
451
452            case SQLITE_ERROR:
453
454                dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_REQUESTFIELDSTYPES, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
455
456            case SQLITE_ROW:
457
458                columnName = (const char *)sqlite3_column_text(handle->result, 1);
459                columnType = (const char *)sqlite3_column_text(handle->result, 2);
460
461                field = types->second.find(columnName);
462
463                if (field == fieldsEnd) {
464                    if (strcasestr(columnType, "char") != NULL ||
465                        strcasestr(columnType, "date") != NULL ||
466                        strcasestr(columnType, "time") != NULL ||
467                        strcasestr(columnType, "text") != NULL ||
468                        strcasestr(columnType, "enum") != NULL ||
469                        strcasestr(columnType, "set") != NULL)
470                        types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_TEXT));
471                    else {
472                        if (strcasestr(columnType, "blob") != NULL)
473                            types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_BINARY));
474                        else
475                            types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_NUMERIC));
476                    }
477                } else {
478                    if (strcasestr(columnType, "char") != NULL ||
479                        strcasestr(columnType, "date") != NULL ||
480                        strcasestr(columnType, "time") != NULL ||
481                        strcasestr(columnType, "text") != NULL ||
482                        strcasestr(columnType, "enum") != NULL ||
483                        strcasestr(columnType, "set") != NULL)
484                        field->second = sql::FIELD_TEXT;
485                    else {
486                        if (strcasestr(columnType, "blob") != NULL)
487                            field->second = sql::FIELD_BINARY;
488                        else
489                            field->second = sql::FIELD_NUMERIC;
490                    }
491                }
492
493                break;
494        }
495    }
496#endif
497
498    sqlite3_finalize(handle->result);
499    handle->result = NULL;
500}
501
502//-------------------------------------------------------------------
503
504void
505sqlite::exec()
506{
507    exec(sql::query(construct()));
508}
509
510//-------------------------------------------------------------------
511
512void
513sqlite::exec(const query &a_query)
514{
515    dodo_try {
516        collectedData.query = dynamic_cast<const sql::query *>(&a_query);
517
518        if (handle->handle == NULL)
519            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_EXEC, exception::ERRNO_LIBDODO, SQLITEEX_NOTOPENED, DATABASESQLITEEX_NOTOPENED_STR, __LINE__, __FILE__);
520
521#ifndef DATABASE_WO_XEXEC
522        performPreExec(OPERATION_EXEC);
523#endif
524
525        if (handle->result) {
526            sqlite3_finalize(handle->result);
527            handle->result = NULL;
528        }
529
530        if (sqlite3_prepare(handle->handle, collectedData.query->sql.data(), collectedData.query->sql.size(), &handle->result, NULL) != SQLITE_OK)
531            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_EXEC, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__, collectedData.query->sql);
532
533        dodo::slList<__blob__>::iterator i(blobs.begin()), j(blobs.end());
534        for (; i != j; ++i) {
535            if (sqlite3_bind_blob(handle->result, i->reference, i->value->data(), i->value->size(), SQLITE_TRANSIENT) != SQLITE_OK) {
536                blobs.clear();
537
538                dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_EXEC, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
539            }
540        }
541
542        blobs.clear();
543
544        if (handle->result == NULL)
545            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_EXEC, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
546
547        int status = sqlite3_step(handle->result);
548        if (status != SQLITE_DONE && status != SQLITE_ROW)
549            dodo_throw exception::basic(exception::MODULE_DATABASESQLITE, SQLITEEX_EXEC, exception::ERRNO_SQLITE, sqlite3_errcode(handle->handle), sqlite3_errmsg(handle->handle), __LINE__, __FILE__);
550
551#ifndef DATABASE_WO_XEXEC
552        performPostExec(OPERATION_EXEC);
553#endif
554        collectedData.clear();
555    } dodo_catch (exception::basic *e UNUSED) {
556        collectedData.clear();
557
558        dodo_rethrow;
559    }
560}
561
562//-------------------------------------------------------------------
563
564void
565sqlite::insert(const data::base::rows      &rows,
566                   const data::base::condition &condition)
567{
568    constructor::insert(rows, condition);
569}
570
571//-------------------------------------------------------------------
572
573void
574sqlite::update(const data::base::rows      &rows,
575                   const data::base::condition &condition)
576{
577    constructor::update(rows, condition);
578}
579
580//-------------------------------------------------------------------
581
582dodo::string
583sqlite::update()
584{
585    dodo::string request = statements[STATEMENT_UPDATE];
586    request += dodo::string(collectedData.condition._table);
587    request += dodo::string(statements[STATEMENT_SET]);
588
589    dodoArray<dodoStringArray>::iterator v = collectedData.rows.values.begin();
590    if (v != collectedData.rows.values.end()) {
591        unsigned int fn(collectedData.rows.fields.size()), fv(v->size());
592
593        unsigned int o(fn <= fv ? fn : fv);
594
595        dodoStringArray::const_iterator i(collectedData.rows.fields.begin()), j(v->begin());
596        if (i != j) {
597            dodoMap<dodo::string, dodoMap<dodo::string, short, dodoMapICaseStringCompare>, dodoMapICaseStringCompare>::iterator types = fieldTypes.find(collectedData.condition._table);
598            if (types != fieldTypes.end()) {
599                dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator type;
600                dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator typesEnd = types->second.end();
601
602                __blob__ blob;
603
604                unsigned int k = 1;
605                for (; k < o; ++i, ++k, ++j) {
606                    request += dodo::string(*i);
607
608                    type = types->second.find(*i);
609                    if (type != typesEnd) {
610                        if (type->second == sql::FIELD_TEXT) {
611                            request += dodo::string(statements[STATEMENT_EQUALAPOSTROPHE]);
612                            request += dodo::string(escapeFields(*j));
613                            request += dodo::string(statements[STATEMENT_APOSTROPHECOMA]);
614                        } else {
615                            if (type->second == sql::FIELD_BINARY) {
616                                request += dodo::string(statements[STATEMENT_EQUAL]);
617                                request += dodo::string("$" + tools::string::uiToString(k));
618                                request += dodo::string(statements[STATEMENT_COMA]);
619
620                                blob.reference = k;
621                                blob.value = &(*j);
622
623                                blobs.push(blob);
624                            } else {
625                                request += dodo::string(statements[STATEMENT_EQUAL]);
626                                request += dodo::string(*j);
627                                request += dodo::string(statements[STATEMENT_COMA]);
628                            }
629                        }
630                    } else {
631                        request += dodo::string(statements[STATEMENT_EQUALAPOSTROPHE]);
632                        request += dodo::string(escapeFields(*j));
633                        request += dodo::string(statements[STATEMENT_APOSTROPHECOMA]);
634                    }
635                }
636                request += dodo::string(*i);
637
638                type = types->second.find(*i);
639                if (type != typesEnd) {
640                    if (type->second == sql::FIELD_TEXT) {
641                        request += dodo::string(statements[STATEMENT_EQUALAPOSTROPHE]);
642                        request += dodo::string(escapeFields(*j));
643                        request += dodo::string(statements[STATEMENT_APOSTROPHE]);
644                    } else {
645                        if (type->second == sql::FIELD_BINARY) {
646                            request += dodo::string(statements[STATEMENT_EQUAL]);
647                            request += dodo::string("$" + tools::string::uiToString(k));
648                            request += dodo::string(statements[STATEMENT_COMA]);
649
650                            blob.reference = k;
651                            blob.value = &(*j);
652
653                            blobs.push(blob);
654                        } else {
655                            request += dodo::string(statements[STATEMENT_EQUAL]);
656                            request += dodo::string(*j);
657                            request += dodo::string(statements[STATEMENT_COMA]);
658                        }
659                    }
660                } else {
661                    request += dodo::string(statements[STATEMENT_EQUALAPOSTROPHE]);
662                    request += dodo::string(escapeFields(*j));
663                    request += dodo::string(statements[STATEMENT_APOSTROPHE]);
664                }
665            } else {
666                for (unsigned int k(1); k < o; ++i, ++k, ++j) {
667                    request += dodo::string(*i);
668                    request += dodo::string(statements[STATEMENT_EQUALAPOSTROPHE]);
669                    request += dodo::string(escapeFields(*j));
670                    request += dodo::string(statements[STATEMENT_APOSTROPHECOMA]);
671                }
672                request += dodo::string(*i);
673                request += dodo::string(statements[STATEMENT_EQUALAPOSTROPHE]);
674                request += dodo::string(escapeFields(*j));
675                request += dodo::string(statements[STATEMENT_APOSTROPHE]);
676            }
677        }
678    }
679
680    return request;
681}
682
683//-------------------------------------------------------------------
684
685dodo::string
686sqlite::insert()
687{
688    dodo::string request = statements[STATEMENT_INSERT];
689    request += dodo::string(statements[STATEMENT_INTO]);
690    request += dodo::string(collectedData.condition._table);
691    if (collectedData.rows.fields.size() != 0) {
692        request += dodo::string(statements[STATEMENT_LEFTBRACKET]);
693        request += dodo::string(tools::misc::join(collectedData.rows.fields, statements[STATEMENT_COMA]));
694        request += dodo::string(statements[STATEMENT_RIGHTBRACKET]);
695    }
696    request += dodo::string(statements[STATEMENT_VALUES]);
697
698    dodoArray<dodoStringArray>::iterator k(collectedData.rows.values.begin()), l(collectedData.rows.values.end());
699    if (k != l) {
700        dodoMap<dodo::string, dodoMap<dodo::string, short, dodoMapICaseStringCompare>, dodoMapICaseStringCompare>::iterator types = fieldTypes.find(collectedData.condition._table);
701        if (types != fieldTypes.end()) {
702            dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator type;
703            dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator typesEnd = types->second.end();
704
705            dodoStringArray::iterator t;
706
707            __blob__ blob;
708
709            unsigned int o = 0;
710
711            --l;
712            for (; k != l; ++k) {
713                request += dodo::string(statements[STATEMENT_LEFTBRACKET]);
714
715                t = collectedData.rows.fields.begin();
716
717                dodoStringArray::const_iterator i(k->begin()), j(k->end() - 1);
718                for (; i != j; ++i, ++t) {
719                    type = types->second.find(*t);
720                    if (type != typesEnd) {
721                        if (type->second == sql::FIELD_TEXT)
722                            request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHECOMA]);
723                        else {
724                            if (type->second == sql::FIELD_BINARY) {
725                                ++o;
726
727                                request += dodo::string("$" + tools::string::uiToString(o));
728                                request += dodo::string(statements[STATEMENT_COMA]);
729
730                                blob.reference = o;
731                                blob.value = &(*i);
732
733                                blobs.push(blob);
734                            } else
735                                request += dodo::string(*i + statements[STATEMENT_COMA]);
736                        }
737                    } else
738                        request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHECOMA]);
739                }
740                type = types->second.find(*t);
741                if (type != typesEnd) {
742                    if (type->second == sql::FIELD_TEXT)
743                        request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHE]);
744                    else {
745                        if (type->second == sql::FIELD_BINARY) {
746                            ++o;
747
748                            request += dodo::string("$" + tools::string::uiToString(o));
749
750                            blob.reference = o;
751                            blob.value = &(*i);
752
753                            blobs.push(blob);
754                        } else
755                            request += dodo::string(*i);
756                    }
757                } else
758                    request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHE]);
759
760                request += dodo::string(statements[STATEMENT_RIGHTBRACKETCOMA]);
761            }
762            request += dodo::string(statements[STATEMENT_LEFTBRACKET]);
763
764            t = collectedData.rows.fields.begin();
765
766            dodoStringArray::const_iterator i(k->begin()), j(k->end() - 1);
767            for (; i != j; ++i, ++t) {
768                type = types->second.find(*t);
769                if (type != typesEnd) {
770                    if (type->second == sql::FIELD_TEXT)
771                        request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHECOMA]);
772                    else {
773                        if (type->second == sql::FIELD_BINARY) {
774                            ++o;
775
776                            request += dodo::string("$" + tools::string::uiToString(o));
777                            request += dodo::string(statements[STATEMENT_COMA]);
778
779                            blob.reference = o;
780                            blob.value = &(*i);
781
782                            blobs.push(blob);
783                        } else
784                            request += dodo::string(*i + statements[STATEMENT_COMA]);
785                    }
786                } else
787                    request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHECOMA]);
788            }
789            type = types->second.find(*t);
790            if (type != typesEnd) {
791                if (type->second == sql::FIELD_TEXT)
792                    request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHE]);
793                else {
794                    if (type->second == sql::FIELD_BINARY) {
795                        ++o;
796
797                        request += dodo::string("$" + tools::string::uiToString(o));
798
799                        blob.reference = o;
800                        blob.value = &(*i);
801
802                        blobs.push(blob);
803                    } else
804                        request += dodo::string(*i);
805                }
806            } else
807                request += dodo::string(statements[STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[STATEMENT_APOSTROPHE]);
808
809            request += dodo::string(statements[STATEMENT_RIGHTBRACKET]);
810        } else {
811            --l;
812            for (; k != l; ++k) {
813                request += dodo::string(statements[STATEMENT_LEFTBRACKET]);
814                request += dodo::string(joinFields(*k, statements[STATEMENT_COMA], statements[STATEMENT_APOSTROPHE]));
815                request += dodo::string(statements[STATEMENT_RIGHTBRACKETCOMA]);
816            }
817            request += dodo::string(statements[STATEMENT_LEFTBRACKET]);
818            request += dodo::string(joinFields(*k, statements[STATEMENT_COMA], statements[STATEMENT_APOSTROPHE]));
819            request += dodo::string(statements[STATEMENT_RIGHTBRACKET]);
820        }
821    }
822
823    return request;
824}
825#endif
826
827//-------------------------------------------------------------------
828
Note: See TracBrowser for help on using the repository browser.