~ubuntu-branches/ubuntu/precise/libdbi-drivers/precise

« back to all changes in this revision

Viewing changes to drivers/firebird/dbd_firebird.c

  • Committer: Stefano Rivera
  • Date: 2010-08-07 14:06:29 UTC
  • mfrom: (5.1.1 libdbi-drivers)
  • Revision ID: stefanor@ubuntu.com-20100807140629-dshfwn5j6v34pqrd
Tags: 0.8.3-1-0ubuntu1
New upstream release. -- Fixes ABORT problems with sqlite3+rrdtool

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
#include <stdlib.h>
43
43
#include <string.h>
44
44
#include <time.h>
45
 
 
46
 
 
47
45
#include <ibase.h>
48
 
#include <gds.h>
49
 
 
50
46
 
51
47
#include "dbd_firebird.h"
52
48
#include "firebird_charsets.h"
53
49
#include "utility.h"
54
50
 
 
51
/* is this correct? Firebird 1.5 used this instead:
 
52
   #define FB_ALIGN(n,b) ((n+b-1)&~(b-1)) */
 
53
#ifndef FB_ALIGN
 
54
#  define FB_ALIGN(n,b) ((n+1) & ~1)
 
55
/* #define FB_ALIGN(n,b) ((n+b-1)&~(b-1)) */
 
56
#endif
55
57
 
 
58
/* firebird versions prior to 2.0 do not typedef ISC_SCHAR but use TEXT
 
59
   instead. ISC_SCHAR's presence is checked for by the configure
 
60
   script */
 
61
#ifndef HAVE_ISC_SCHAR
 
62
#define ISC_SCHAR TEXT
 
63
#endif
 
64
        
56
65
static const dbi_info_t driver_info = {
57
66
        "firebird",
58
67
        "Firebird/Interbase database support",
79
88
 
80
89
int dbd_initialize(dbi_driver_t *driver) 
81
90
{
82
 
         return 0;
 
91
        _dbd_register_driver_cap(driver, "safe_dlclose", 0);
 
92
        return 0;
83
93
}
84
94
 
85
95
int dbd_connect(dbi_conn_t *conn) 
90
100
 
91
101
int dbd_disconnect(dbi_conn_t *conn) 
92
102
{
93
 
        
94
103
        ibase_conn_t *iconn = conn->connection;
95
104
    
96
105
        if(iconn != NULL) {
97
 
                isc_commit_transaction(iconn->status, &(iconn->trans));
98
 
                isc_detach_database(iconn->status, &(iconn->db));
 
106
                isc_commit_transaction(iconn->status_vector, &(iconn->trans));
 
107
                isc_detach_database(iconn->status_vector, &(iconn->db));
99
108
                
100
109
                dealocate_iconn(iconn);
101
110
        }
123
132
 
124
133
int dbd_free_query(dbi_result_t *result) 
125
134
{
126
 
        ISC_STATUS_ARRAY status;
 
135
        dbi_conn_t *conn = dbi_result_get_conn(result);
 
136
        ibase_conn_t *iconn = conn->connection;
127
137
        ibase_stmt_t *istmt = result->result_handle;
128
138
        
129
139
        if(istmt != NULL) {
130
 
                isc_dsql_free_statement(status, &(istmt->stmt), DSQL_drop);
 
140
                isc_dsql_free_statement(iconn->status_vector, &(istmt->stmt), DSQL_drop);
131
141
                free(istmt->osqlda);
132
142
                free(istmt);
133
143
        }
204
214
        char *stop;
205
215
 
206
216
        /* Firebird make some easy things hard ... this is one of them ... */
207
 
        isc_version(&(iconn->db), _get_firebird_version, NULL);
 
217
        isc_version(&(iconn->db), (isc_callback)_get_firebird_version, NULL);
208
218
 
209
219
        /* version now contains something like:
210
220
           Firebird/linux Intel (access method), version "LI-V1.5.1.4500 Firebird 1.5"
333
343
        long statement_type;
334
344
        short num_cols, i;
335
345
        short length, alignment, type, offset;
336
 
        long buffer[MAXLEN];
 
346
/*      long buffer[MAXLEN*8]; */
 
347
        void* buffer = NULL;
337
348
        unsigned long long numrows = 0, affectedrows = 0;
338
349
        ibase_conn_t *iconn = conn->connection;
339
350
 
340
 
       if (isc_dsql_allocate_statement(iconn->status, &(iconn->db), &stmt)) {
 
351
       if (isc_dsql_allocate_statement(iconn->status_vector, &(iconn->db), &stmt)) {
 
352
               if (iconn->status_vector[0] == 1 && iconn->status_vector[1]) {
 
353
                       char msg[512];
 
354
                       long* pvector = iconn->status_vector;
 
355
                       isc_interprete(msg, &pvector);
 
356
                       _dbd_internal_error_handler(conn, msg, DBI_ERROR_CLIENT);
 
357
               }
341
358
               return NULL;
342
359
       }
343
360
       
344
 
       sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH (1));
 
361
       sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
345
362
       sqlda->sqln = 1;
346
363
       sqlda->version = 1;
347
364
 
348
 
       if (isc_dsql_prepare(iconn->status, &(iconn->trans), &stmt, 0, (char *)statement, 3, sqlda)) {
 
365
       if (isc_dsql_prepare(iconn->status_vector, &(iconn->trans), &stmt, 0, (char *)statement, 3, sqlda)) {
 
366
               if (iconn->status_vector[0] == 1 && iconn->status_vector[1]) {
 
367
                       char msg[512];
 
368
                       long* pvector = iconn->status_vector;
 
369
                       isc_interprete(msg, &pvector);
 
370
                       _dbd_internal_error_handler(conn, msg, DBI_ERROR_CLIENT);
 
371
               }
349
372
               free(sqlda);
350
 
               isc_dsql_free_statement(iconn->status, &stmt, DSQL_drop);
 
373
               isc_dsql_free_statement(iconn->status_vector, &stmt, DSQL_drop);
351
374
               return NULL;
352
375
       }
353
376
 
354
 
       if (!isc_dsql_sql_info(iconn->status, &stmt, sizeof(stmt_info), stmt_info,
 
377
       if (!isc_dsql_sql_info(iconn->status_vector, &stmt, sizeof(stmt_info), stmt_info,
355
378
                              sizeof(info_buffer), info_buffer)) {
356
379
               l = (short) isc_vax_integer((char *) info_buffer + 1, 2);
357
380
               statement_type = isc_vax_integer((char *) info_buffer + 3, l); 
358
381
       }
 
382
 
359
383
       /* Execute a non-select statement.*/
360
384
       if (!sqlda->sqld) {
361
 
               if (isc_dsql_execute(iconn->status, &(iconn->trans), &stmt , SQL_DIALECT_V6, NULL)) {
 
385
               if (isc_dsql_execute(iconn->status_vector, &(iconn->trans), &stmt , SQL_DIALECT_V6, NULL)) {
 
386
                       if (iconn->status_vector[0] == 1 && iconn->status_vector[1]) {
 
387
                               char msg[512];
 
388
                               long* pvector = iconn->status_vector;
 
389
                               isc_interprete(msg, &pvector);
 
390
                               _dbd_internal_error_handler(conn, msg, DBI_ERROR_CLIENT);
 
391
                       }
362
392
                       free(sqlda);
363
 
                       isc_dsql_free_statement(iconn->status, &stmt, DSQL_drop);
 
393
                       isc_dsql_free_statement(iconn->status_vector, &stmt, DSQL_drop);
364
394
                       return NULL;
365
395
               }
366
396
               /* Commit DDL statements if that is what sql_info says */
367
397
               if (iconn->trans && (statement_type == isc_info_sql_stmt_ddl)) {
368
398
 
369
 
                       if (isc_commit_transaction(iconn->status, &(iconn->trans))) {
 
399
                       if (isc_commit_transaction(iconn->status_vector, &(iconn->trans))) {
 
400
                               if (iconn->status_vector[0] == 1 && iconn->status_vector[1]) {
 
401
                                       char msg[512];
 
402
                                       long* pvector = iconn->status_vector;
 
403
                                       isc_interprete(msg, &pvector);
 
404
                                       _dbd_internal_error_handler(conn, msg, DBI_ERROR_CLIENT);
 
405
                               }
370
406
                               free(sqlda);
371
 
                               isc_dsql_free_statement(iconn->status, &stmt, DSQL_drop);
 
407
                               isc_dsql_free_statement(iconn->status_vector, &stmt, DSQL_drop);
372
408
                               return NULL;
373
409
                       }
374
 
                       isc_start_transaction(iconn->status, &(iconn->trans), 1, &(iconn->db), 0, NULL);
 
410
                       isc_start_transaction(iconn->status_vector, &(iconn->trans), 1, &(iconn->db), 0, NULL);
375
411
               }
 
412
 
 
413
 
 
414
       /* Process select statements. */
376
415
       } else {
377
416
               
378
 
               /* Process select statements. */
379
417
               
380
418
               num_cols = sqlda->sqld;
381
419
               numrows = 1; /*  Firebird  can't say how many rows there is, in this early stage. 
382
420
                                We need to fetch all rows and count them :( */
383
 
         
 
421
 
 
422
               /* HACK HACK HACK MH:2008-01-02 */
 
423
               /* I don't really know how much needs to be allocated
 
424
                  here. The Firebird example code and the docs won't
 
425
                  tell me. I just know that the previously used hard
 
426
                  limit (4096) is not enough to run the test program
 
427
                  successfully. I'm assuming here that in the worst
 
428
                  case num_cols columns contain strings of the maximum
 
429
                  allowed length, and that this is just about
 
430
                  sufficient. I may be wasting memory here, or the
 
431
                  code just so happens to work for the tests
 
432
                  applied. If crashes or strange results are reported,
 
433
                  revisit this issue */
 
434
               buffer = malloc(32768*num_cols);
384
435
 
385
436
               /* Need more room. */
386
437
               if (sqlda->sqln < num_cols) {
388
439
                       sqlda->sqln = num_cols;
389
440
                       sqlda->version = 1;
390
441
                       
391
 
                       if (isc_dsql_describe(iconn->status, &stmt, SQL_DIALECT_V6, sqlda)) {
 
442
                       if (isc_dsql_describe(iconn->status_vector, &stmt, SQL_DIALECT_V6, sqlda)) {
 
443
                               if (iconn->status_vector[0] == 1 && iconn->status_vector[1]) {
 
444
                                       char msg[512];
 
445
                                       long* pvector = iconn->status_vector;
 
446
                                       isc_interprete(msg, &pvector);
 
447
                                       _dbd_internal_error_handler(conn, msg, DBI_ERROR_CLIENT);
 
448
                               }
392
449
                               free(sqlda);
393
 
                               isc_dsql_free_statement(iconn->status, &stmt, DSQL_drop);
 
450
                               isc_dsql_free_statement(iconn->status_vector, &stmt, DSQL_drop);
394
451
                               return NULL;
395
452
                       }
396
453
                       
414
471
                       offset += sizeof  (short);
415
472
               }
416
473
               
417
 
               if (isc_dsql_execute(iconn->status, &(iconn->trans), &stmt, SQL_DIALECT_V6, NULL)) {
 
474
               if (isc_dsql_execute(iconn->status_vector, &(iconn->trans), &stmt, SQL_DIALECT_V6, NULL)) {
418
475
                       free(sqlda);
419
 
                       isc_dsql_free_statement(iconn->status, &stmt, DSQL_drop);
 
476
                       if (iconn->status_vector[0] == 1 && iconn->status_vector[1]) {
 
477
                               char msg[512];
 
478
                               long* pvector = iconn->status_vector;
 
479
                               isc_interprete(msg, &pvector);
 
480
                               _dbd_internal_error_handler(conn, msg, DBI_ERROR_CLIENT);
 
481
                       }
 
482
                       isc_dsql_free_statement(iconn->status_vector, &stmt, DSQL_drop);
420
483
                       return NULL;
421
484
               }       
422
485
       }
430
493
       _dbd_result_set_numfields(result, res->osqlda->sqld);
431
494
       _get_field_info(result);
432
495
       
 
496
       if (buffer) {
 
497
               free(buffer);
 
498
       }
433
499
       return result;
434
500
}
435
501
 
443
509
        }
444
510
 
445
511
        if (iconn) {
446
 
                isc_commit_transaction(iconn->status, &(iconn->trans));
447
 
                isc_detach_database(iconn->status, &(iconn->db));
 
512
                isc_commit_transaction(iconn->status_vector, &(iconn->trans));
 
513
                isc_detach_database(iconn->status_vector, &(iconn->db));
448
514
                if(conn->current_db) free(conn->current_db);
449
515
                free(iconn);
450
516
                iconn = NULL;
460
526
 
461
527
int dbd_geterror(dbi_conn_t *conn, int *errno, char **errstr) 
462
528
{
463
 
        ibase_conn_t *iconn = conn->connection;
464
 
        
465
 
        TEXT errbuf[MAXLEN];
466
 
        long sqlcode;
467
 
 
468
 
        if ( conn->connection == NULL) {
469
 
                *errstr = strdup("Unable to connect to database.");
470
 
                return 1;
471
 
        }
472
 
        
473
 
         
474
 
        sqlcode = isc_sqlcode(iconn->status); 
475
 
        isc_sql_interprete(sqlcode, errbuf, sizeof(errbuf)); 
476
 
        *errstr = strdup(errbuf);
477
 
          
 
529
        /* error_message and error_number were already set by calls to _dbd_internal_error_handler */
 
530
        *errno = conn->error_number;
 
531
        *errstr = (conn->error_message) ? strdup(conn->error_message):NULL;
478
532
        return 1;
479
533
}
480
534
 
495
549
        char buf[100];
496
550
        ibase_conn_t *iconn = conn->connection;
497
551
        
498
 
        if (isc_database_info(iconn->status, &(iconn->db), 0, NULL, sizeof(buf), buf)) {
 
552
        if (isc_database_info(iconn->status_vector, &(iconn->db), 0, NULL, sizeof(buf), buf)) {
499
553
                free(iconn);
500
554
                if (conn->current_db ) free(conn->current_db);
501
555
                if(! dbd_connect(conn)) return 0;