~ubuntu-branches/ubuntu/saucy/lcmaps-plugins-jobrep/saucy

« back to all changes in this revision

Viewing changes to src/api/jobrep_odbc_api.c

  • Committer: Package Import Robot
  • Author(s): Dennis van Dok
  • Date: 2013-05-23 11:38:59 UTC
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: package-import@ubuntu.com-20130523113859-m9rbnfk8f8zwuwnd
Tags: upstream-1.5.3
ImportĀ upstreamĀ versionĀ 1.5.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
68
68
    unsigned char  buf[250];
69
69
    unsigned char  sqlstate[15];
70
70
    unsigned char *search;
71
 
              int  i = 0;
 
71
    size_t  i = 0;
72
72
 
73
73
    if (where) {
74
74
        lcmaps_log(LOG_ERR, "Error detected in %s with return code: %s(%d)\n",
141
141
 
142
142
struct jr_db_handle_s *
143
143
ODBC_Connect (char *dsn, char *username, char *password) {
144
 
    long V_OD_erg = 0;
 
144
    SQLRETURN V_OD_erg = 0;
145
145
    unsigned char V_OD_msg[200];
146
146
    unsigned char V_OD_stat[10];
147
147
    SQLINTEGER V_OD_err;
160
160
 
161
161
    V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(jr_db_handle->jobrep_henv));
162
162
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) {
163
 
            lcmaps_log(LOG_ERR, "%s: Error AllocHandle", __func__);
 
163
            lcmaps_log(LOG_ERR, "%s: Error AllocHandle\n", __func__);
164
164
            goto failure;
165
165
    }
166
166
 
167
167
    V_OD_erg = SQLSetEnvAttr(jr_db_handle->jobrep_henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
168
168
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) {
169
 
            lcmaps_log(LOG_ERR, "%s: Error SetEnv", __func__);
 
169
            lcmaps_log(LOG_ERR, "%s: Error SetEnv\n", __func__);
170
170
            SQLFreeHandle(SQL_HANDLE_ENV, jr_db_handle->jobrep_henv);
171
171
            goto failure;
172
172
    }
173
173
 
174
174
    V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, jr_db_handle->jobrep_henv, &(jr_db_handle->jobrep_hdbc));
175
175
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) {
176
 
            lcmaps_log(LOG_ERR, "%s: Error AllocHDB", __func__);
 
176
            lcmaps_log(LOG_ERR, "%s: Error AllocHDB\n", __func__);
177
177
            SQLFreeHandle(SQL_HANDLE_ENV, jr_db_handle->jobrep_henv);
178
178
            goto failure;
179
179
    }
184
184
                          (SQLCHAR*) username, SQL_NTS,
185
185
                          (SQLCHAR*) password, SQL_NTS);
186
186
    if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO)) {
187
 
            lcmaps_log(LOG_ERR, "%s: Error SQLConnect", __func__);
 
187
            lcmaps_log(LOG_ERR, "%s: Error SQLConnect\n", __func__);
188
188
            SQLGetDiagRec(SQL_HANDLE_DBC, jr_db_handle->jobrep_hdbc, 1,
189
189
                          V_OD_stat, &V_OD_err, V_OD_msg, sizeof(V_OD_msg), &V_OD_mlen);
190
190
            ODBC_Errors(jr_db_handle, V_OD_erg, (char *)V_OD_msg);
256
256
 
257
257
int
258
258
SQL_BeginTransaction(struct jr_db_handle_s *db_handle) {
259
 
    int status = 0;
 
259
    SQLRETURN status = 0;
260
260
 
261
261
    if (db_handle == NULL) {
262
262
        return -1;
357
357
                    SQLUSMALLINT param_number,
358
358
                    SQLSMALLINT c_type, SQLSMALLINT sql_type,
359
359
                    SQLPOINTER data) {
360
 
    int res;
 
360
    SQLRETURN res;
361
361
 
362
362
    if (db_handle == NULL) {
363
363
        return -1;
393
393
******************************************************************************/
394
394
int
395
395
SQL_Prepare (struct jr_db_handle_s *db_handle, SQLCHAR *sql) {
396
 
    int res = 0;
 
396
    SQLRETURN res = 0;
397
397
 
398
398
    if ((db_handle == NULL) || (sql == NULL)) {
399
399
        return -1;
436
436
******************************************************************************/
437
437
int
438
438
SQL_Exec(struct jr_db_handle_s *db_handle) {
439
 
    int res = 0;
 
439
    SQLRETURN res = 0;
440
440
 
441
441
    if (db_handle == NULL) {
442
442
        return -1;
478
478
    -1 : failure
479
479
    -2 : failure
480
480
******************************************************************************/
481
 
int
 
481
SQLRETURN
482
482
SQL_Query(struct jr_db_handle_s *db_handle) {
483
 
    int      res = 0;
484
 
    int      i = 0;
485
 
    int      colNum = 0;
486
 
    int      rowNum = 0;
487
 
    char     colName[255];
488
 
    short    colType = 0;
489
 
    short    colCType = 0;
490
 
    UDWORD   colPrecision = 0;
491
 
    SDWORD   colIndicator = 0;
492
 
    short    colScale = 0;
493
 
    short    colNullable = 0;
494
 
    int      sts = SQL_NO_DATA_FOUND;
 
483
    SQLRETURN res = SQL_SUCCESS;
 
484
    SQLULEN   i = 0;
 
485
    SQLUSMALLINT colCnt,colNum=0;
 
486
    SQLULEN   rowCnt,rowNum=0;
 
487
    char      colName[255];
 
488
    short     colType = 0;
 
489
    short     colCType = 0;
 
490
    SQLULEN   colPrecision = 0;
 
491
    SQLLEN    colIndicator = 0;
 
492
    short     colScale = 0;
 
493
    short     colNullable = 0;
495
494
 
496
495
    if (db_handle == NULL) {
497
 
        res = -1;
498
 
        goto cleanup;
 
496
        res = SQL_INVALID_HANDLE;
 
497
        goto sql_query_cleanup;
499
498
    }
500
499
 
501
500
    if (db_handle->querystate != PREPARED) {
502
501
        lcmaps_log(LOG_ERR, "%s: SQL_Query() called without SQL_Prepare()\n", __func__);
503
 
        res = -1;
504
 
        goto cleanup;
 
502
        res = SQL_ERROR;
 
503
        goto sql_query_cleanup;
505
504
    }
506
505
    /* In Query */
507
506
    db_handle->querystate = QUERY;
509
508
    /* SQL Execute! */
510
509
    if ((res = SQLExecute (db_handle->jobrep_hstmt)) != SQL_SUCCESS) {
511
510
        ODBC_Errors(db_handle, res, "SQLExecute");
512
 
        res = -2;
513
 
        goto cleanup;
 
511
        goto sql_query_cleanup;
514
512
    }
515
513
 
516
514
    /* Got a Query, clean the ResultSet, if any is set. */
517
515
    if (db_handle->resultset != NULL) {
518
516
        lcmaps_log(LOG_ERR, "%s: The memory for the SQL resultset was not cleaned.\n", __func__);
519
 
        res = -3;
520
 
        goto cleanup;
 
517
        res = SQL_ERROR;
 
518
        goto sql_query_cleanup;
521
519
    }
522
520
 
523
521
    /* New resultset */
524
522
    db_handle->resultset = malloc(sizeof(TResultSet));
525
523
    if (db_handle->resultset == NULL) {
526
524
        lcmaps_log(LOG_ERR, "%s: Unable to allocate the resultset\n", __func__);
527
 
        res = -3;
528
 
        goto cleanup;
 
525
        res = SQL_ERROR;
 
526
        goto sql_query_cleanup;
529
527
    }
530
528
 
531
529
    /* Get column count */
532
530
    res = SQLNumResultCols(db_handle->jobrep_hstmt, &(db_handle->resultset->colCnt));
533
 
    if (res != SQL_SUCCESS) {
 
531
    if (res != SQL_SUCCESS || db_handle->resultset->colCnt<0) {
534
532
        ODBC_Errors(db_handle, res, "SQLNumResultCols");
535
 
        res = -3;
536
 
        goto cleanup;
 
533
        goto sql_query_cleanup;
537
534
    }
538
535
 
539
536
    /* Get the row count */
540
537
    res = SQLRowCount(db_handle->jobrep_hstmt, &(db_handle->resultset->rowCnt));
541
 
    if (res != SQL_SUCCESS) {
 
538
    if (res != SQL_SUCCESS || db_handle->resultset->rowCnt<0) {
542
539
        ODBC_Errors(db_handle, res, "SQLRowCount");
543
 
        res = -3;
544
 
        goto cleanup;
 
540
        goto sql_query_cleanup;
545
541
    }
546
542
 
547
 
    /* Build the ResultSet Grid */
548
 
    db_handle->resultset->columns = malloc(sizeof(TColumn) * db_handle->resultset->colCnt);
 
543
    /* Build the ResultSet Grid *
 
544
     * Note: colCnt is successfully retrieved, hence will be non-negative so
 
545
     * cast explicitly to unsigned */
 
546
    colCnt=(SQLUSMALLINT)db_handle->resultset->colCnt;
 
547
    rowCnt=(SQLULEN)db_handle->resultset->rowCnt;
 
548
 
 
549
    db_handle->resultset->columns = malloc(sizeof(TColumn) * colCnt);
549
550
    if (db_handle->resultset->columns == NULL) {
550
551
        lcmaps_log(LOG_ERR, "%s: Error in allocating %u bytes\n",
551
 
                            __func__, sizeof(TColumn) * db_handle->resultset->colCnt);
552
 
        goto done_with_filling_result_set;
 
552
                            __func__, sizeof(TColumn) * colCnt);
 
553
        res = SQL_ERROR;
 
554
        goto sql_query_cleanup;
553
555
    }
554
 
    memset(db_handle->resultset->columns, 0, sizeof(TColumn) * db_handle->resultset->colCnt);
555
 
 
556
 
    db_handle->resultset->data = malloc(sizeof(TRow) * db_handle->resultset->rowCnt);
 
556
    memset(db_handle->resultset->columns, 0, sizeof(TColumn) * colCnt);
 
557
 
 
558
 
 
559
    db_handle->resultset->data = malloc(sizeof(TRow) * rowCnt);
557
560
    if (db_handle->resultset->data == NULL) {
558
561
        lcmaps_log(LOG_ERR, "%s: Error in allocating %u bytes\n",
559
 
                            __func__, sizeof(TRow) * db_handle->resultset->rowCnt);
560
 
        goto done_with_filling_result_set;
 
562
                            __func__, sizeof(TRow) * rowCnt);
 
563
        res = SQL_ERROR;
 
564
        goto sql_query_cleanup;
561
565
    }
562
 
    memset(db_handle->resultset->data, 0, sizeof(TRow) * db_handle->resultset->rowCnt);
 
566
    memset(db_handle->resultset->data, 0, sizeof(TRow) * rowCnt);
563
567
 
564
 
    for (i = 0; i < db_handle->resultset->rowCnt; i++) {
565
 
        db_handle->resultset->data[i] = malloc(sizeof(TField) * db_handle->resultset->colCnt);
 
568
    for (i = 0; i < rowCnt; i++) {
 
569
        db_handle->resultset->data[i] = malloc(sizeof(TField) * colCnt);
566
570
        if (db_handle->resultset->data[i] == NULL) {
567
571
            lcmaps_log(LOG_ERR, "%s: Error in allocating %u bytes\n",
568
 
                                __func__, sizeof(TField) * db_handle->resultset->colCnt);
569
 
            goto done_with_filling_result_set;
 
572
                                __func__, sizeof(TField) * colCnt);
 
573
            res = SQL_ERROR;
 
574
            goto sql_query_cleanup;
570
575
        }
571
 
        memset(db_handle->resultset->data[i], 0, sizeof(TField) * db_handle->resultset->colCnt);
 
576
        memset(db_handle->resultset->data[i], 0, sizeof(TField) * colCnt);
572
577
    }
573
578
 
574
579
    /* Let's get us a dataset */
575
 
    rowNum = 0;
576
 
loop_for_a_new_row:
577
 
    sts = SQLFetch (db_handle->jobrep_hstmt);
578
 
    if (sts == SQL_NO_DATA_FOUND) {
579
 
        goto done_with_filling_result_set;
580
 
    }
581
 
    if (sts != SQL_SUCCESS) {
582
 
        ODBC_Errors(db_handle, sts, "SQLFetch");
583
 
        goto done_with_filling_result_set;
584
 
    }
585
 
 
586
 
    /* Read a row, column by column */
587
 
    for (colNum = 0; colNum < db_handle->resultset->colCnt; colNum++) {
588
 
        sts = SQLDescribeCol(db_handle->jobrep_hstmt, colNum + 1, (UCHAR *) colName, sizeof (colName),
589
 
                            NULL, &colType, &colPrecision,
590
 
                            &colScale, &colNullable);
591
 
        if (sts != SQL_SUCCESS) {
592
 
            ODBC_Errors(db_handle, sts, "SQLDescribeCol");
593
 
            goto done_with_filling_result_set;
594
 
        }
595
 
 
596
 
        void *data;
597
 
        unsigned long bufsize_bytes;
598
 
        bufsize_bytes = 0;
599
 
        data = NULL;
600
 
 
601
 
        switch(colType) {
602
 
            case SQL_UNKNOWN_TYPE    :
603
 
                /* Error? */
604
 
                break;
605
 
            case SQL_DECIMAL         :
606
 
            case SQL_NUMERIC         :
607
 
                colCType = SQL_C_CHAR;
608
 
                bufsize_bytes = sizeof(char) * 2;
609
 
                break;
610
 
            case SQL_BIGINT          :
611
 
            case SQL_INTEGER         :
612
 
                colCType = SQL_C_LONG;
613
 
                bufsize_bytes = sizeof(long);
614
 
                break;
615
 
            case SQL_SMALLINT        :
616
 
                colCType = SQL_C_SHORT;
617
 
                bufsize_bytes = sizeof(short);
618
 
                break;
619
 
            case SQL_FLOAT           :
620
 
            case SQL_REAL            :
621
 
                colCType = SQL_C_FLOAT;
622
 
                bufsize_bytes = sizeof(float);
623
 
                break;
624
 
            case SQL_DOUBLE          :
625
 
                colCType = SQL_C_DOUBLE;
626
 
                bufsize_bytes = sizeof(double);
627
 
                break;
 
580
    for (rowNum=0; rowNum<rowCnt; rowNum++) {
 
581
        res = SQLFetch (db_handle->jobrep_hstmt);
 
582
        if (res == SQL_NO_DATA_FOUND) {
 
583
            goto sql_query_cleanup;
 
584
        }
 
585
        if (res != SQL_SUCCESS) {
 
586
            ODBC_Errors(db_handle, res, "SQLFetch");
 
587
            goto sql_query_cleanup;
 
588
        }
 
589
 
 
590
        /* Read a row, column by column */
 
591
        for (colNum = 0; colNum < colCnt; colNum++) {
 
592
            res = SQLDescribeCol(db_handle->jobrep_hstmt, (SQLUSMALLINT)(colNum + 1),
 
593
                                (UCHAR *) colName, sizeof (colName),
 
594
                                NULL, &colType, &colPrecision,
 
595
                                &colScale, &colNullable);
 
596
            if (res != SQL_SUCCESS) {
 
597
                ODBC_Errors(db_handle, res, "SQLDescribeCol");
 
598
                goto sql_query_cleanup;
 
599
            }
 
600
 
 
601
            void *data;
 
602
            SQLLEN bufsize_bytes;
 
603
            bufsize_bytes = 0;
 
604
            data = NULL;
 
605
 
 
606
            switch(colType) {
 
607
                case SQL_UNKNOWN_TYPE    :
 
608
                    /* Error? */
 
609
                    break;
 
610
                case SQL_DECIMAL         :
 
611
                case SQL_NUMERIC         :
 
612
                    colCType = SQL_C_CHAR;
 
613
                    bufsize_bytes = sizeof(char) * 2;
 
614
                    break;
 
615
                case SQL_BIGINT          :
 
616
                case SQL_INTEGER         :
 
617
                    colCType = SQL_C_LONG;
 
618
                    bufsize_bytes = sizeof(long);
 
619
                    break;
 
620
                case SQL_SMALLINT        :
 
621
                    colCType = SQL_C_SHORT;
 
622
                    bufsize_bytes = sizeof(short);
 
623
                    break;
 
624
                case SQL_FLOAT           :
 
625
                case SQL_REAL            :
 
626
                    colCType = SQL_C_FLOAT;
 
627
                    bufsize_bytes = sizeof(float);
 
628
                    break;
 
629
                case SQL_DOUBLE          :
 
630
                    colCType = SQL_C_DOUBLE;
 
631
                    bufsize_bytes = sizeof(double);
 
632
                    break;
628
633
#if 0
629
 
        #if (ODBCVER >= 0x0300)
630
 
            case SQL_DATETIME        :
 
634
            #if (ODBCVER >= 0x0300)
 
635
                case SQL_DATETIME        :
631
636
 
632
 
                break;
633
 
        #endif
 
637
                    break;
 
638
            #endif
634
639
#endif
635
 
            case SQL_CHAR            :
636
 
            case SQL_VARCHAR         :
637
 
                colCType = SQL_C_CHAR;
638
 
                bufsize_bytes = sizeof(char) * 50;
639
 
                break;
640
 
            default :
641
 
                lcmaps_log(LOG_ERR, "%s: Unknown datatype of value %d\n", __func__, colType);
642
 
                res = -3;
643
 
                goto cleanup;
644
 
        }
645
 
 
646
 
 
647
 
        /********************************
648
 
        Start of getting data with SQLGetData() The data will be read and made
649
 
        available in the 'data_final' field. This can be casted to what ever
650
 
        the colCType indicates.
651
 
        ********************************/
652
 
        data = malloc(bufsize_bytes);
653
 
 
654
 
        void *data_final = NULL;
655
 
 
656
 
        void *data2 = NULL;
657
 
        void *data3 = NULL;
658
 
        int   total_buf = 0;
659
 
        int   offset = 0;
660
 
        int   needs_concat = 0;
661
 
 
662
 
        data_final = data;
663
 
        do {
664
 
            /* Fetch data for this field */
665
 
            memset(data, 0, bufsize_bytes);
666
 
            res = SQLGetData (db_handle->jobrep_hstmt,
667
 
                              colNum + 1,
668
 
                              colCType, data, bufsize_bytes,
669
 
                              &colIndicator);
670
 
            if (res == SQL_SUCCESS) {
671
 
                if (needs_concat) {
672
 
                    /* If there is more data available for a given field, continue here */
673
 
                    total_buf += bufsize_bytes;
674
 
 
675
 
                    /* Expand memory into a new buffer and copy the current buffer in it. */
676
 
                    if (data2 == NULL) {
677
 
                        data3 = malloc(sizeof(char) * total_buf);
678
 
                    } else {
679
 
                        data3 = realloc(data2, sizeof(char) * total_buf);
680
 
                    }
681
 
                    if (data3 == NULL) {
682
 
                        /* Allocation error */
683
 
                        free(data2);
684
 
                        goto done_with_filling_result_set;
685
 
                    }
686
 
                    data2 = data3;
687
 
                    memcpy((char*)data2+offset, data, bufsize_bytes);
688
 
 
689
 
                    /* Move the offset with the buffer size minus 1, because the last
690
 
                     * byte is a \0 */
691
 
                    offset += bufsize_bytes - 1;
692
 
 
693
 
                    data_final = data2;
694
 
                }
695
 
                break; /* Done */
696
 
            } else if (res != SQL_SUCCESS_WITH_INFO) {
697
 
                ODBC_Errors(db_handle, res, "SQLGetData");
698
 
                goto done_with_filling_result_set;
699
 
            }
700
 
 
701
 
            /* Signal that the last read buffer needs to be concattinated as a final step */
702
 
            needs_concat = 1;
703
 
 
704
 
            /* If there is more data available for a given field, continue here */
705
 
            total_buf += bufsize_bytes;
706
 
 
707
 
            /* Expand memory into a new buffer and copy the current buffer in it. */
708
 
            if (data2 == NULL) {
709
 
                data3 = malloc(sizeof(char) * total_buf);
710
 
            } else {
711
 
                data3 = realloc(data2, sizeof(char) * total_buf);
712
 
            }
713
 
            if (data3 == NULL) {
714
 
                /* Allocation error */
715
 
                free(data2);
716
 
                goto done_with_filling_result_set;
717
 
            }
718
 
            data2 = data3;
719
 
            memcpy((char*)data2+offset, data, bufsize_bytes);
720
 
            /* Move the offset with the buffer size minus 1, because the last
721
 
             * byte is a \0 */
722
 
            offset += bufsize_bytes - 1;
723
 
 
724
 
            data_final = data2;
725
 
        } while (res == SQL_SUCCESS_WITH_INFO);
726
 
 
727
 
        /* Hook up the fetched results into the TResultSet */
728
 
        db_handle->resultset->columns[colNum].columnname     = strdup(colName);
729
 
        db_handle->resultset->columns[colNum].type           = colType;
730
 
        db_handle->resultset->data[rowNum][colNum].fieldname = strdup(colName);
731
 
        db_handle->resultset->data[rowNum][colNum].type      = colCType;
732
 
        db_handle->resultset->data[rowNum][colNum].byte_size = total_buf;
733
 
        switch(colCType) {
734
 
            case SQL_C_CHAR :
735
 
                db_handle->resultset->data[rowNum][colNum].v_string = (char *)data_final;
736
 
                break;
737
 
            case SQL_C_LONG :
738
 
                db_handle->resultset->data[rowNum][colNum].v_long = *((long *)data_final);
739
 
                break;
740
 
            case SQL_C_SHORT:
741
 
                db_handle->resultset->data[rowNum][colNum].v_short = *((short *)data_final);
742
 
                break;
743
 
            case SQL_C_FLOAT:
744
 
                db_handle->resultset->data[rowNum][colNum].v_float = *((float *)data_final);
745
 
                break;
746
 
            case SQL_C_DOUBLE:
747
 
                db_handle->resultset->data[rowNum][colNum].v_double = *((double *)data_final);
748
 
                break;
749
 
        }
750
 
    }
751
 
 
752
 
    /* Next */
753
 
    rowNum++;
754
 
    goto loop_for_a_new_row;
755
 
 
756
 
done_with_filling_result_set:
757
 
    res = db_handle->resultset->rowCnt;
758
 
 
759
 
cleanup:
 
640
                case SQL_CHAR            :
 
641
                case SQL_VARCHAR         :
 
642
                    colCType = SQL_C_CHAR;
 
643
                    bufsize_bytes = sizeof(char) * 50;
 
644
                    break;
 
645
                default :
 
646
                    lcmaps_log(LOG_ERR, "%s: Unknown datatype of value %d\n", __func__, colType);
 
647
                    res = SQL_ERROR;
 
648
                    goto sql_query_cleanup;
 
649
            }
 
650
 
 
651
 
 
652
            /********************************
 
653
            Start of getting data with SQLGetData() The data will be read and made
 
654
            available in the 'data_final' field. This can be casted to what ever
 
655
            the colCType indicates.
 
656
            ********************************/
 
657
            data = malloc((size_t)bufsize_bytes);
 
658
 
 
659
            void *data_final = NULL;
 
660
 
 
661
            void *data2 = NULL;
 
662
            void *data3 = NULL;
 
663
            size_t total_buf = 0;
 
664
            SQLLEN offset = 0;
 
665
            int   needs_concat = 0;
 
666
 
 
667
            data_final = data;
 
668
            do {
 
669
                /* Fetch data for this field */
 
670
                memset(data, 0, (size_t)bufsize_bytes);
 
671
                res = SQLGetData (db_handle->jobrep_hstmt,
 
672
                                  (SQLUSMALLINT)(colNum + 1),
 
673
                                  colCType, data, bufsize_bytes,
 
674
                                  &colIndicator);
 
675
                if (res == SQL_SUCCESS) {
 
676
                    if (needs_concat) {
 
677
                        /* If there is more data available for a given field, continue here */
 
678
                        total_buf += (size_t)bufsize_bytes;
 
679
 
 
680
                        /* Expand memory into a new buffer and copy the current buffer in it. */
 
681
                        if (data2 == NULL) {
 
682
                            data3 = malloc(sizeof(char) * total_buf);
 
683
                        } else {
 
684
                            data3 = realloc(data2, sizeof(char) * total_buf);
 
685
                        }
 
686
                        if (data3 == NULL) {
 
687
                            /* Allocation error */
 
688
                            free(data2);
 
689
                            res = SQL_ERROR;
 
690
                            goto sql_query_cleanup;
 
691
                        }
 
692
                        data2 = data3;
 
693
                        memcpy((char*)data2+offset, data, (size_t)bufsize_bytes);
 
694
 
 
695
                        /* Move the offset with the buffer size minus 1, because the last
 
696
                         * byte is a \0 */
 
697
                        offset += bufsize_bytes - 1;
 
698
 
 
699
                        data_final = data2;
 
700
                    }
 
701
                    break; /* Done */
 
702
                } else if (res != SQL_SUCCESS_WITH_INFO) {
 
703
                    ODBC_Errors(db_handle, res, "SQLGetData");
 
704
                    goto sql_query_cleanup;
 
705
                }
 
706
 
 
707
                /* Signal that the last read buffer needs to be concattinated as a final step */
 
708
                needs_concat = 1;
 
709
 
 
710
                /* If there is more data available for a given field, continue here */
 
711
                total_buf += (size_t)bufsize_bytes;
 
712
 
 
713
                /* Expand memory into a new buffer and copy the current buffer in it. */
 
714
                if (data2 == NULL) {
 
715
                    data3 = malloc(sizeof(char) * total_buf);
 
716
                } else {
 
717
                    data3 = realloc(data2, sizeof(char) * total_buf);
 
718
                }
 
719
                if (data3 == NULL) {
 
720
                    /* Allocation error */
 
721
                    free(data2);
 
722
                    res = SQL_ERROR;
 
723
                    goto sql_query_cleanup;
 
724
                }
 
725
                data2 = data3;
 
726
                memcpy((char*)data2+offset, data, (size_t)bufsize_bytes);
 
727
                /* Move the offset with the buffer size minus 1, because the last
 
728
                 * byte is a \0 */
 
729
                offset += bufsize_bytes - 1;
 
730
 
 
731
                data_final = data2;
 
732
            } while (res == SQL_SUCCESS_WITH_INFO);
 
733
 
 
734
            /* Hook up the fetched results into the TResultSet */
 
735
            db_handle->resultset->columns[colNum].columnname     = strdup(colName);
 
736
            db_handle->resultset->columns[colNum].type           = colType;
 
737
            db_handle->resultset->data[rowNum][colNum].fieldname = strdup(colName);
 
738
            db_handle->resultset->data[rowNum][colNum].type      = colCType;
 
739
            db_handle->resultset->data[rowNum][colNum].byte_size = total_buf;
 
740
            switch(colCType) {
 
741
                case SQL_C_CHAR :
 
742
                    db_handle->resultset->data[rowNum][colNum].v_string = (char *)data_final;
 
743
                    break;
 
744
                case SQL_C_LONG :
 
745
                    db_handle->resultset->data[rowNum][colNum].v_long = *((long *)data_final);
 
746
                    break;
 
747
                case SQL_C_SHORT:
 
748
                    db_handle->resultset->data[rowNum][colNum].v_short = *((short *)data_final);
 
749
                    break;
 
750
                case SQL_C_FLOAT:
 
751
                    db_handle->resultset->data[rowNum][colNum].v_float = *((float *)data_final);
 
752
                    break;
 
753
                case SQL_C_DOUBLE:
 
754
                    db_handle->resultset->data[rowNum][colNum].v_double = *((double *)data_final);
 
755
                    break;
 
756
            }
 
757
        }
 
758
    } /* row loop */
 
759
 
 
760
sql_query_cleanup:
760
761
    SQL_QueryClose(db_handle);
761
762
 
762
763
    return res;
794
795
******************************************************************************/
795
796
int
796
797
SQL_QueryClose(struct jr_db_handle_s *db_handle) {
797
 
    int sts = 0;
 
798
    SQLRETURN sts = 0;
798
799
 
799
800
    if (db_handle == NULL) {
800
801
        return -1;