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

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

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

Line 
1/***************************************************************************
2 *            dataBasePostgresql.cc
3 *
4 *  Fri Jan  13 2006
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 POSTGRESQL_EXT
33#include <libpq-fe.h>
34#include <stdlib.h>
35#include <string.h>
36
37#include <libdodo/dataBasePostgresql.h>
38#include <libdodo/toolsString.h>
39#include <libdodo/toolsMisc.h>
40#include <libdodo/dataBasePostgresqlEx.h>
41#include <libdodo/xexec.h>
42
43namespace dodo {
44    namespace data {
45        namespace base {
46            /**
47             * @struct __postgresql__
48             * @brief defines internal handlers for MySQL DBMS interaction
49             */
50            struct __postgresql__ {
51                /**
52                 * constructor
53                 */
54                __postgresql__() : handle(NULL),
55                                   result(NULL)
56                {
57                }
58
59                PGconn             *handle; ///< DB handle
60                PGresult           *result; ///< handlde to result
61            };
62        };
63    };
64};
65
66using namespace dodo::data::base;
67
68#ifdef POSTGRESQL_NO_ENCODINGTOCHAR
69const dodo::string postgresql::encodingStatements[] = {
70    "SQL_ASCII",
71    "EUC_JP",
72    "EUC_CN",
73    "EUC_KR",
74    "EUC_TW",
75    "JOHAB",
76    "UTF8",
77    "MULE_INTERNAL",
78    "LATIN1",
79    "LATIN2",
80    "LATIN3",
81    "LATIN4",
82    "LATIN5",
83    "LATIN6",
84    "LATIN7",
85    "LATIN8",
86    "LATIN9",
87    "LATIN10",
88    "WIN1256",
89    "WIN1258",
90    "WIN866",
91    "WIN874",
92    "KOI8",
93    "WIN1251",
94    "WIN1252",
95    "ISO_8859_5",
96    "ISO_8859_6",
97    "ISO_8859_7",
98    "ISO_8859_8",
99    "WIN1250",
100    "WIN1253",
101    "WIN1254",
102    "WIN1255",
103    "WIN1257",
104    "SJIS",
105    "BIG5",
106    "GBK",
107    "UHC",
108    "GB18030"
109};
110#endif
111
112//-------------------------------------------------------------------
113
114postgresql::__connection_options__::__connection_options__(const dodo::string &db,
115                                                           const dodo::string &host,
116                                                           const dodo::string &user,
117                                                           const dodo::string &password,
118                                                           unsigned int     port) : db(db),
119                                                                                    host(host),
120                                                                                    user(user),
121                                                                                    password(password),
122                                                                                    port(port)
123{
124}
125
126//-------------------------------------------------------------------
127
128postgresql::__connection_options__::__connection_options__()
129{
130}
131
132//-------------------------------------------------------------------
133
134postgresql::postgresql() : handle(new __postgresql__)
135{
136#ifndef DATABASE_WO_XEXEC
137    collectedData.setExecObject(xexec::OBJECT_DATABASEPOSTGRESQL);
138#endif
139}
140
141//-------------------------------------------------------------------
142
143postgresql::postgresql(const data::base::__connection_options__ &a_info) : handle(new __postgresql__),
144                                                                           info(*dynamic_cast<const postgresql::__connection_options__ *>(&a_info))
145{
146#ifndef DATABASE_WO_XEXEC
147    collectedData.setExecObject(xexec::OBJECT_DATABASEPOSTGRESQL);
148#endif
149
150    handle->handle = PQsetdbLogin(
151        info.host.size() == 0 ? NULL : info.host.data(),
152        tools::string::uiToString(info.port).data(),
153        NULL,
154        NULL,
155        info.db.size() == 0 ? NULL : info.db.data(),
156        info.user.size() == 0 ? NULL : info.user.data(),
157        info.password.size() == 0 ? NULL : info.password.data());
158
159    int status = PQstatus(handle->handle);
160
161    dodo_try {
162        if (status != CONNECTION_OK) {
163            dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_POSTGRESQL, exception::ERRNO_MYSQL, status, PQerrorMessage(handle->handle), __LINE__, __FILE__);
164        }
165    } dodo_catch (exception::basic *e UNUSED) {
166        delete handle;
167
168        dodo_rethrow;
169    }
170}
171
172//-------------------------------------------------------------------
173
174postgresql::postgresql(postgresql &)
175{
176}
177
178//-------------------------------------------------------------------
179
180postgresql::~postgresql()
181{
182    if (handle->handle != NULL) {
183        if (handle->result)
184            PQclear(handle->result);
185
186        PQfinish(handle->handle);
187    }
188
189    delete handle;
190}
191
192//-------------------------------------------------------------------
193
194void
195postgresql::connect(const data::base::__connection_options__ &a_info)
196{
197#ifndef DATABASE_WO_XEXEC
198    performPreExec(OPERATION_CONNECT);
199#endif
200
201    info = *dynamic_cast<const postgresql::__connection_options__ *>(&a_info);
202
203    if (handle->handle != NULL) {
204        if (handle->result) {
205            PQclear(handle->result);
206            handle->result = NULL;
207        }
208
209        PQfinish(handle->handle);
210
211        handle->handle = NULL;
212    }
213
214    handle->handle = PQsetdbLogin(
215        info.host.size() == 0 ? NULL : info.host.data(),
216        tools::string::uiToString(info.port).data(),
217        NULL,
218        NULL,
219        info.db.size() == 0 ? NULL : info.db.data(),
220        info.user.size() == 0 ? NULL : info.user.data(),
221        info.password.size() == 0 ? NULL : info.password.data());
222
223    int status = PQstatus(handle->handle);
224
225    if (status != CONNECTION_OK) {
226        handle->handle = NULL;
227
228        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_CONNECT, exception::ERRNO_MYSQL, status, PQerrorMessage(handle->handle), __LINE__, __FILE__);
229    }
230
231#ifndef DATABASE_WO_XEXEC
232    performPostExec(OPERATION_CONNECT);
233#endif
234}
235
236//-------------------------------------------------------------------
237
238void
239postgresql::disconnect()
240{
241    if (handle->handle != NULL) {
242#ifndef DATABASE_WO_XEXEC
243        performPreExec(OPERATION_DISCONNECT);
244#endif
245
246        if (handle->result) {
247            PQclear(handle->result);
248            handle->result = NULL;
249        }
250
251        PQfinish(handle->handle);
252
253#ifndef DATABASE_WO_XEXEC
254        performPostExec(OPERATION_DISCONNECT);
255#endif
256
257        handle->handle = NULL;
258    }
259}
260
261//-------------------------------------------------------------------
262
263void
264postgresql::fetchedRows(data::base::rows &a_rows) const
265{
266    sql::rows *rows = dynamic_cast<sql::rows *>(&a_rows);
267
268#ifndef DATABASE_WO_XEXEC
269    performPreExec(OPERATION_FETCHEDROWS);
270#endif
271
272    rows->fields.clear();
273    rows->values.clear();
274
275    if (!handle->result) // FIXME: dodo_throw exception?
276        return;
277
278    int rowsNum = PQntuples(handle->result);
279    int fieldsNum = PQnfields(handle->result);
280
281    rows->fields.reserve(fieldsNum);
282    rows->values.reserve(rowsNum);
283
284    dodoStringArray values;
285
286    values.reserve(fieldsNum);
287
288    for (int i(0); i < fieldsNum; ++i)
289        rows->fields.push_back(PQfname(handle->result, i));
290
291    int j;
292    for (int i(0); i < rowsNum; ++i) {
293        for (j = 0; j < fieldsNum; ++j) {
294            if (PQgetisnull(handle->result, i, j) == 1)
295                values.push_back(statements[sql::constructor::STATEMENT_NULL]);
296            else
297                values.push_back(dodo::string(PQgetvalue(handle->result, i, j), PQgetlength(handle->result, i, j)));
298        }
299
300        rows->values.push_back(values);
301
302        values.clear();
303    }
304
305#ifndef DATABASE_WO_XEXEC
306    performPostExec(OPERATION_FETCHEDROWS);
307#endif
308}
309
310//-------------------------------------------------------------------
311
312unsigned int
313postgresql::fetchedRows() const
314{
315    if (handle->result == NULL)
316        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_FETCHEDROWS, exception::ERRNO_LIBDODO, POSTGRESQLEX_NOTOPENED, DATABASEPOSTGRESQLEX_NOTOPENED_STR, __LINE__, __FILE__);
317
318    return PQntuples(handle->result);
319}
320
321//-------------------------------------------------------------------
322
323unsigned int
324postgresql::affectedRows() const
325{
326    if (handle->result == NULL)
327        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_AFFECTEDROWS, exception::ERRNO_LIBDODO, POSTGRESQLEX_NOTOPENED, DATABASEPOSTGRESQLEX_NOTOPENED_STR, __LINE__, __FILE__);
328
329    return atoi(PQcmdTuples(handle->result));
330}
331
332//-------------------------------------------------------------------
333
334void
335postgresql::requestFieldsTypes(const dodo::string &table)
336{
337    if (handle->handle == NULL)
338        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_REQUESTFIELDSTYPES, exception::ERRNO_LIBDODO, POSTGRESQLEX_NOTOPENED, DATABASEPOSTGRESQLEX_NOTOPENED_STR, __LINE__, __FILE__);
339
340    dodoMap<dodo::string, dodoMap<dodo::string, short, dodoMapICaseStringCompare>, dodoMapICaseStringCompare>::iterator types = fieldTypes.find(table);
341
342    if (types == fieldTypes.end())
343        types = fieldTypes.insert(std::make_pair(table, dodoMap<dodo::string, short, dodoMapICaseStringCompare>())).first;
344
345    dodo::string request = "select column_name, data_type from information_schema.columns where table_name='" + table + "'";
346
347    if (handle->result)
348        PQclear(handle->result);
349
350    handle->result = PQexecParams(handle->handle, request.data(), 0, NULL, NULL, NULL, NULL, 1);
351    if (handle->result == NULL)
352        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_REQUESTFIELDSTYPES, exception::ERRNO_MYSQL, PGRES_FATAL_ERROR, PQerrorMessage(handle->handle), __LINE__, __FILE__, request);
353
354    int status = PQresultStatus(handle->result);
355
356    switch (status) {
357        case PGRES_EMPTY_QUERY:
358        case PGRES_BAD_RESPONSE:
359        case PGRES_NONFATAL_ERROR:
360        case PGRES_FATAL_ERROR:
361
362            dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_REQUESTFIELDSTYPES, exception::ERRNO_MYSQL, status, PQerrorMessage(handle->handle), __LINE__, __FILE__);
363    }
364
365    int rowsNum = PQntuples(handle->result);
366
367    const char *columnType, *columnName;
368
369    dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator field, fieldsEnd = types->second.end();
370
371    dodoStringArray rowsPart;
372
373    for (int i(0); i < rowsNum; ++i) {
374        columnName = PQgetvalue(handle->result, i, 0);
375        columnType = PQgetvalue(handle->result, i, 1);
376
377        field = types->second.find(columnName);
378
379        if (field == fieldsEnd) {
380            if (strcasestr(columnType, "char") != NULL ||
381                strcasestr(columnType, "date") != NULL ||
382                strcasestr(columnType, "text") != NULL) {
383                types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_TEXT));
384            } else {
385                if (strcasestr(columnType, "bytea") != NULL ||
386                    strcasestr(columnType, "array") != NULL ||
387                    strcasestr(columnType, "cidr") != NULL ||
388                    strcasestr(columnType, "macaddrcd") != NULL ||
389                    strcasestr(columnType, "inet") != NULL)
390                    types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_BINARY));
391                else
392                    types->second.insert(std::make_pair(dodo::string(columnName), sql::FIELD_NUMERIC));
393            }
394        } else {
395            if (strcasestr(columnType, "char") != NULL ||
396                strcasestr(columnType, "date") != NULL ||
397                strcasestr(columnType, "text") != NULL) {
398                field->second = sql::FIELD_TEXT;
399            } else {
400                if (strcasestr(columnType, "bytea") != NULL ||
401                    strcasestr(columnType, "array") != NULL ||
402                    strcasestr(columnType, "cidr") != NULL ||
403                    strcasestr(columnType, "macaddrcd") != NULL ||
404                    strcasestr(columnType, "inet") != NULL)
405                    field->second = sql::FIELD_BINARY;
406                else
407                    field->second = sql::FIELD_NUMERIC;
408            }
409        }
410    }
411
412    PQclear(handle->result);
413    handle->result = NULL;
414}
415
416//-------------------------------------------------------------------
417
418void
419postgresql::exec()
420{
421    exec(sql::query(construct()));
422}
423
424//-------------------------------------------------------------------
425
426void
427postgresql::exec(const query &a_query)
428{
429    dodo_try {
430        collectedData.query = dynamic_cast<const sql::query *>(&a_query);
431
432        if (handle->handle == NULL)
433            dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_EXEC, exception::ERRNO_LIBDODO, POSTGRESQLEX_NOTOPENED, DATABASEPOSTGRESQLEX_NOTOPENED_STR, __LINE__, __FILE__);
434
435#ifndef DATABASE_WO_XEXEC
436        performPreExec(OPERATION_EXEC);
437#endif
438
439        int status;
440
441        if (handle->result)
442            PQclear(handle->result);
443
444        unsigned long size = blobs.size();
445
446        if (size > 0) {
447            char **values = new char*[size];
448            int *lengths = new int[size];
449            int *formats = new int[size];
450
451            dodo::slList<__blob__>::iterator i(blobs.begin()), j(blobs.end());
452            for (int o = 0; i != j; ++i, ++o) {
453                values[o] = (char *)i->value->data();
454                lengths[o] = i->value->size();
455                formats[o] = 1;
456            }
457
458            handle->result = PQexecParams(handle->handle, collectedData.query->sql.data(), size, NULL, values, lengths, formats, 0);
459
460            blobs.clear();
461        } else {
462            handle->result = PQexecParams(handle->handle, collectedData.query->sql.data(), 0, NULL, NULL, NULL, NULL, 1);
463        }
464
465        if (handle->result == NULL)
466            dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_EXEC, exception::ERRNO_MYSQL, PGRES_FATAL_ERROR, PQerrorMessage(handle->handle), __LINE__, __FILE__, collectedData.query->sql);
467
468        status = PQresultStatus(handle->result);
469        switch (status) {
470            case PGRES_EMPTY_QUERY:
471            case PGRES_BAD_RESPONSE:
472            case PGRES_NONFATAL_ERROR:
473            case PGRES_FATAL_ERROR:
474
475                dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_EXEC, exception::ERRNO_MYSQL, status, PQerrorMessage(handle->handle), __LINE__, __FILE__);
476
477            /* case PGRES_COMMAND_OK: */
478
479            /*     PQclear(handle->result); */
480            /*     handle->result = NULL; */
481
482            /*     break; */
483        }
484
485#ifndef DATABASE_WO_XEXEC
486        performPostExec(OPERATION_EXEC);
487#endif
488
489        collectedData.clear();
490    } dodo_catch (exception::basic *e UNUSED) {
491        collectedData.clear();
492
493        dodo_rethrow;
494    }
495}
496
497//-------------------------------------------------------------------
498
499void
500postgresql::insert(const data::base::rows      &rows,
501                   const data::base::condition &condition)
502{
503    constructor::insert(rows, condition);
504}
505
506//-------------------------------------------------------------------
507
508void
509postgresql::update(const data::base::rows      &rows,
510                   const data::base::condition &condition)
511{
512    constructor::update(rows, condition);
513}
514
515//-------------------------------------------------------------------
516
517dodo::string
518postgresql::update()
519{
520    dodo::string request = statements[sql::constructor::STATEMENT_UPDATE];
521    request += dodo::string(collectedData.condition._table);
522    request += dodo::string(statements[sql::constructor::STATEMENT_SET]);
523
524    dodoArray<dodoStringArray>::iterator v = collectedData.rows.values.begin();
525    if (v != collectedData.rows.values.end()) {
526        unsigned int fn(collectedData.rows.fields.size()), fv(v->size());
527
528        unsigned int o(fn <= fv ? fn : fv);
529
530        dodoStringArray::const_iterator i(collectedData.rows.fields.begin()), j(v->begin());
531        if (i != j) {
532            dodoMap<dodo::string, dodoMap<dodo::string, short, dodoMapICaseStringCompare>, dodoMapICaseStringCompare>::iterator types = fieldTypes.find(collectedData.condition._table);
533            if (types != fieldTypes.end()) {
534                dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator type;
535                dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator typesEnd = types->second.end();
536
537                __blob__ blob;
538
539                unsigned int k = 1;
540                for (; k < o; ++i, ++k, ++j) {
541                    request += dodo::string(*i);
542
543                    type = types->second.find(*i);
544                    if (type != typesEnd) {
545                        if (type->second == sql::FIELD_TEXT) {
546                            request += dodo::string(statements[sql::constructor::STATEMENT_EQUALAPOSTROPHE]);
547                            request += dodo::string(escapeFields(*j));
548                            request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
549                        } else {
550                            if (type->second == sql::FIELD_BINARY) {
551                                request += dodo::string(statements[sql::constructor::STATEMENT_EQUAL]);
552                                request += dodo::string("$" + tools::string::uiToString(k));
553                                request += dodo::string(statements[sql::constructor::STATEMENT_COMA]);
554
555                                blob.reference = k;
556                                blob.value = &(*j);
557
558                                blobs.push(blob);
559                            } else {
560                                request += dodo::string(statements[sql::constructor::STATEMENT_EQUAL]);
561                                request += dodo::string(*j);
562                                request += dodo::string(statements[sql::constructor::STATEMENT_COMA]);
563                            }
564                        }
565                    } else {
566                        request += dodo::string(statements[sql::constructor::STATEMENT_EQUALAPOSTROPHE]);
567                        request += dodo::string(escapeFields(*j));
568                        request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
569                    }
570                }
571                request += dodo::string(*i);
572
573                type = types->second.find(*i);
574                if (type != typesEnd) {
575                    if (type->second == sql::FIELD_TEXT) {
576                        request += dodo::string(statements[sql::constructor::STATEMENT_EQUALAPOSTROPHE]);
577                        request += dodo::string(escapeFields(*j));
578                        request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE]);
579                    } else {
580                        if (type->second == sql::FIELD_BINARY) {
581                            request += dodo::string(statements[sql::constructor::STATEMENT_EQUAL]);
582                            request += dodo::string("$" + tools::string::uiToString(k));
583                            request += dodo::string(statements[sql::constructor::STATEMENT_COMA]);
584
585                            blob.reference = k;
586                            blob.value = &(*j);
587
588                            blobs.push(blob);
589                        } else {
590                            request += dodo::string(statements[sql::constructor::STATEMENT_EQUAL]);
591                            request += dodo::string(*j);
592                            request += dodo::string(statements[sql::constructor::STATEMENT_COMA]);
593                        }
594                    }
595                } else {
596                    request += dodo::string(statements[sql::constructor::STATEMENT_EQUALAPOSTROPHE]);
597                    request += dodo::string(escapeFields(*j));
598                    request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE]);
599                }
600            } else {
601                for (unsigned int k(1); k < o; ++i, ++k, ++j) {
602                    request += dodo::string(*i);
603                    request += dodo::string(statements[sql::constructor::STATEMENT_EQUALAPOSTROPHE]);
604                    request += dodo::string(escapeFields(*j));
605                    request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
606                }
607                request += dodo::string(*i);
608                request += dodo::string(statements[sql::constructor::STATEMENT_EQUALAPOSTROPHE]);
609                request += dodo::string(escapeFields(*j));
610                request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE]);
611            }
612        }
613    }
614
615    return request;
616}
617
618//-------------------------------------------------------------------
619
620dodo::string
621postgresql::insert()
622{
623    dodo::string request = statements[sql::constructor::STATEMENT_INSERT];
624    request += dodo::string(statements[sql::constructor::STATEMENT_INTO]);
625    request += dodo::string(collectedData.condition._table);
626    if (collectedData.rows.fields.size() != 0) {
627        request += dodo::string(statements[sql::constructor::STATEMENT_LEFTBRACKET]);
628        request += dodo::string(tools::misc::join(collectedData.rows.fields, statements[sql::constructor::STATEMENT_COMA]));
629        request += dodo::string(statements[sql::constructor::STATEMENT_RIGHTBRACKET]);
630    }
631    request += dodo::string(statements[sql::constructor::STATEMENT_VALUES]);
632
633    dodoArray<dodoStringArray>::iterator k(collectedData.rows.values.begin()), l(collectedData.rows.values.end());
634    if (k != l) {
635        dodoMap<dodo::string, dodoMap<dodo::string, short, dodoMapICaseStringCompare>, dodoMapICaseStringCompare>::iterator types = fieldTypes.find(collectedData.condition._table);
636        if (types != fieldTypes.end()) {
637            dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator type;
638            dodoMap<dodo::string, short, dodoMapICaseStringCompare>::iterator typesEnd = types->second.end();
639
640            dodoStringArray::iterator t;
641
642            __blob__ blob;
643
644            unsigned int o = 0;
645
646            --l;
647            for (; k != l; ++k) {
648                request += dodo::string(statements[sql::constructor::STATEMENT_LEFTBRACKET]);
649
650                t = collectedData.rows.fields.begin();
651
652                dodoStringArray::const_iterator i(k->begin()), j(k->end() - 1);
653                for (; i != j; ++i, ++t) {
654                    type = types->second.find(*t);
655                    if (type != typesEnd) {
656                        if (type->second == sql::FIELD_TEXT)
657                            request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
658                        else {
659                            if (type->second == sql::FIELD_BINARY) {
660                                ++o;
661
662                                request += dodo::string("$" + tools::string::uiToString(o));
663                                request += dodo::string(statements[sql::constructor::STATEMENT_COMA]);
664
665                                blob.reference = o;
666                                blob.value = &(*i);
667
668                                blobs.push(blob);
669                            } else
670                                request += dodo::string(*i + statements[sql::constructor::STATEMENT_COMA]);
671                        }
672                    } else
673                        request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
674                }
675                type = types->second.find(*t);
676                if (type != typesEnd) {
677                    if (type->second == sql::FIELD_TEXT)
678                        request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHE]);
679                    else {
680                        if (type->second == sql::FIELD_BINARY) {
681                            ++o;
682
683                            request += dodo::string("$" + tools::string::uiToString(o));
684
685                            blob.reference = o;
686                            blob.value = &(*i);
687
688                            blobs.push(blob);
689                        } else
690                            request += dodo::string(*i);
691                    }
692                } else
693                    request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHE]);
694
695                request += dodo::string(statements[sql::constructor::STATEMENT_RIGHTBRACKETCOMA]);
696            }
697            request += dodo::string(statements[sql::constructor::STATEMENT_LEFTBRACKET]);
698
699            t = collectedData.rows.fields.begin();
700
701            dodoStringArray::const_iterator i(k->begin()), j(k->end() - 1);
702            for (; i != j; ++i, ++t) {
703                type = types->second.find(*t);
704                if (type != typesEnd) {
705                    if (type->second == sql::FIELD_TEXT)
706                        request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
707                    else {
708                        if (type->second == sql::FIELD_BINARY) {
709                            ++o;
710
711                            request += dodo::string("$" + tools::string::uiToString(o));
712                            request += dodo::string(statements[sql::constructor::STATEMENT_COMA]);
713
714                            blob.reference = o;
715                            blob.value = &(*i);
716
717                            blobs.push(blob);
718                        } else
719                            request += dodo::string(*i + statements[sql::constructor::STATEMENT_COMA]);
720                    }
721                } else
722                    request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHECOMA]);
723            }
724            type = types->second.find(*t);
725            if (type != typesEnd) {
726                if (type->second == sql::FIELD_TEXT)
727                    request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHE]);
728                else {
729                    if (type->second == sql::FIELD_BINARY) {
730                        ++o;
731
732                        request += dodo::string("$" + tools::string::uiToString(o));
733
734                        blob.reference = o;
735                        blob.value = &(*i);
736
737                        blobs.push(blob);
738                    } else
739                        request += dodo::string(*i);
740                }
741            } else
742                request += dodo::string(statements[sql::constructor::STATEMENT_APOSTROPHE] + escapeFields(*i) + statements[sql::constructor::STATEMENT_APOSTROPHE]);
743
744            request += dodo::string(statements[sql::constructor::STATEMENT_RIGHTBRACKET]);
745        } else {
746            --l;
747            for (; k != l; ++k) {
748                request += dodo::string(statements[sql::constructor::STATEMENT_LEFTBRACKET]);
749                request += dodo::string(joinFields(*k, statements[sql::constructor::STATEMENT_COMA], statements[sql::constructor::STATEMENT_APOSTROPHE]));
750                request += dodo::string(statements[sql::constructor::STATEMENT_RIGHTBRACKETCOMA]);
751            }
752            request += dodo::string(statements[sql::constructor::STATEMENT_LEFTBRACKET]);
753            request += dodo::string(joinFields(*k, statements[sql::constructor::STATEMENT_COMA], statements[sql::constructor::STATEMENT_APOSTROPHE]));
754            request += dodo::string(statements[sql::constructor::STATEMENT_RIGHTBRACKET]);
755        }
756    }
757
758    return request;
759}
760
761//-------------------------------------------------------------------
762
763void
764postgresql::setCharset(const dodo::string &charset)
765{
766    if (handle->handle == NULL)
767        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_SETCHARSET, exception::ERRNO_LIBDODO, POSTGRESQLEX_NOTOPENED, DATABASEPOSTGRESQLEX_NOTOPENED_STR, __LINE__, __FILE__);
768
769    int status = PQsetClientEncoding(handle->handle, charset.data());
770    if (status == -1)
771        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_SETCHARSET, exception::ERRNO_MYSQL, status, PQerrorMessage(handle->handle), __LINE__, __FILE__);
772}
773
774//-------------------------------------------------------------------
775
776dodo::string
777postgresql::charset() const
778{
779    if (handle->handle == NULL)
780        dodo_throw exception::basic(exception::MODULE_DATABASEPOSTGRESQL, POSTGRESQLEX_CHARSET, exception::ERRNO_LIBDODO, POSTGRESQLEX_NOTOPENED, DATABASEPOSTGRESQLEX_NOTOPENED_STR, __LINE__, __FILE__);
781
782#ifdef POSTGRESQL_NO_ENCODINGTOCHAR
783    int encoding = PQclientEncoding(handle->handle);
784
785    if (encoding >= 0 && encoding < ENCODING_ENUMSIZE)
786        return encodingStatements[encoding];
787
788    return __dodostring__;
789#else
790    return pg_encoding_to_char(PQclientEncoding(handle->handle));
791#endif
792}
793#endif
794
795//-------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.