This file is indexed.

/usr/include/soci/odbc/soci-odbc.h is in libsoci-dev 3.2.3-2ubuntu2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
//
// Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, David Courtney
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef SOCI_ODBC_H_INCLUDED
#define SOCI_ODBC_H_INCLUDED

#ifdef _WIN32
# ifdef SOCI_DLL
#  ifdef SOCI_ODBC_SOURCE
#   define SOCI_ODBC_DECL __declspec(dllexport)
#  else
#   define SOCI_ODBC_DECL __declspec(dllimport)
#  endif // SOCI_ODBC_SOURCE
# endif // SOCI_DLL
#endif // _WIN32
//
// If SOCI_ODBC_DECL isn't defined yet define it now
#ifndef SOCI_ODBC_DECL
# define SOCI_ODBC_DECL
#endif

#include <vector>
#include <sstream>
#include <soci-backend.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <soci-platform.h>
#include <windows.h>
#endif
#include <sqlext.h> // ODBC
#include <string.h> // strcpy()

namespace soci
{

    // TODO: Do we want to make it a part of public interface? --mloskot
namespace details
{
    std::size_t const odbc_max_buffer_length = 100 * 1024 * 1024;
}

// Option allowing to specify the "driver completion" parameter of
// SQLDriverConnect(). Its possible values are the same as the allowed values
// for this parameter in the official ODBC, i.e. one of SQL_DRIVER_XXX (in
// string form as all options are strings currently).
extern SOCI_ODBC_DECL char const * odbc_option_driver_complete;

struct odbc_statement_backend;

// Helper of into and use backends.
class odbc_standard_type_backend_base
{
protected:
    odbc_standard_type_backend_base(odbc_statement_backend &st)
        : statement_(st) {}

    // Check if we need to pass 64 bit integers as strings to the database as
    // some drivers don't support them directly.
    inline bool use_string_for_bigint() const;

    // If we do need to use strings for 64 bit integers, this constant defines
    // the maximal string length needed.
    enum
    {
        // This is the length of decimal representation of UINT64_MAX + 1.
        max_bigint_length = 21
    };

    odbc_statement_backend &statement_;
};

struct odbc_standard_into_type_backend : details::standard_into_type_backend,
                                         private odbc_standard_type_backend_base
{
    odbc_standard_into_type_backend(odbc_statement_backend &st)
        : odbc_standard_type_backend_base(st), buf_(0)
    {}

    virtual void define_by_pos(int &position,
        void *data, details::exchange_type type);

    virtual void pre_fetch();
    virtual void post_fetch(bool gotData, bool calledFromFetch,
        indicator *ind);

    virtual void clean_up();

    char *buf_;        // generic buffer
    void *data_;
    details::exchange_type type_;
    int position_;
    SQLSMALLINT odbcType_;
    SQLLEN valueLen_;
};

struct odbc_vector_into_type_backend : details::vector_into_type_backend,
                                       private odbc_standard_type_backend_base
{
    odbc_vector_into_type_backend(odbc_statement_backend &st)
        : odbc_standard_type_backend_base(st), indHolders_(NULL),
          data_(NULL), buf_(NULL) {}

    virtual void define_by_pos(int &position,
        void *data, details::exchange_type type);

    virtual void pre_fetch();
    virtual void post_fetch(bool gotData, indicator *ind);

    virtual void resize(std::size_t sz);
    virtual std::size_t size();

    virtual void clean_up();

    // helper function for preparing indicators
    // (as part of the define_by_pos)
    void prepare_indicators(std::size_t size);


    SQLLEN *indHolders_;
    std::vector<SQLLEN> indHolderVec_;
    void *data_;
    char *buf_;              // generic buffer
    details::exchange_type type_;
    std::size_t colSize_;    // size of the string column (used for strings)
    SQLSMALLINT odbcType_;
};

struct odbc_standard_use_type_backend : details::standard_use_type_backend,
                                        private odbc_standard_type_backend_base
{
    odbc_standard_use_type_backend(odbc_statement_backend &st)
        : odbc_standard_type_backend_base(st),
          position_(-1), data_(0), buf_(0), indHolder_(0) {}

    virtual void bind_by_pos(int &position,
        void *data, details::exchange_type type, bool readOnly);
    virtual void bind_by_name(std::string const &name,
        void *data, details::exchange_type type, bool readOnly);

    virtual void pre_use(indicator const *ind);
    virtual void post_use(bool gotData, indicator *ind);

    virtual void clean_up();

    // Return the pointer to the buffer containing data to be used by ODBC.
    // This can be either data_ itself or buf_, that is allocated by this
    // function if necessary.
    //
    // Also fill in the size of the data and SQL and C types of it.
    void* prepare_for_bind(SQLLEN &size,
       SQLSMALLINT &sqlType, SQLSMALLINT &cType);

    int position_;
    void *data_;
    details::exchange_type type_;
    char *buf_;
    SQLLEN indHolder_;
};

struct odbc_vector_use_type_backend : details::vector_use_type_backend,
                                      private odbc_standard_type_backend_base
{
    odbc_vector_use_type_backend(odbc_statement_backend &st)
        : odbc_standard_type_backend_base(st), indHolders_(NULL),
          data_(NULL), buf_(NULL) {}

    // helper function for preparing indicators
    // (as part of the define_by_pos)
    void prepare_indicators(std::size_t size);

    // common part for bind_by_pos and bind_by_name
    void prepare_for_bind(void *&data, SQLUINTEGER &size, SQLSMALLINT &sqlType, SQLSMALLINT &cType);
    void bind_helper(int &position,
        void *data, details::exchange_type type);

    virtual void bind_by_pos(int &position,
        void *data, details::exchange_type type);
    virtual void bind_by_name(std::string const &name,
        void *data, details::exchange_type type);

    virtual void pre_use(indicator const *ind);

    virtual std::size_t size();

    virtual void clean_up();


    SQLLEN *indHolders_;
    std::vector<SQLLEN> indHolderVec_;
    void *data_;
    details::exchange_type type_;
    char *buf_;              // generic buffer
    std::size_t colSize_;    // size of the string column (used for strings)
    // used for strings only
    std::size_t maxSize_;
};

struct odbc_session_backend;
struct odbc_statement_backend : details::statement_backend
{
    odbc_statement_backend(odbc_session_backend &session);

    virtual void alloc();
    virtual void clean_up();
    virtual void prepare(std::string const &query,
        details::statement_type eType);

    virtual exec_fetch_result execute(int number);
    virtual exec_fetch_result fetch(int number);

    virtual long long get_affected_rows();
    virtual int get_number_of_rows();

    virtual std::string rewrite_for_procedure_call(std::string const &query);

    virtual int prepare_for_describe();
    virtual void describe_column(int colNum, data_type &dtype,
        std::string &columnName);

    // helper for defining into vector<string>
    std::size_t column_size(int position);

    virtual odbc_standard_into_type_backend * make_into_type_backend();
    virtual odbc_standard_use_type_backend * make_use_type_backend();
    virtual odbc_vector_into_type_backend * make_vector_into_type_backend();
    virtual odbc_vector_use_type_backend * make_vector_use_type_backend();

    odbc_session_backend &session_;
    SQLHSTMT hstmt_;
    SQLULEN numRowsFetched_;
    bool hasVectorUseElements_;
    bool boundByName_;
    bool boundByPos_;

    long long rowsAffected_; // number of rows affected by the last operation

    std::string query_;
    std::vector<std::string> names_; // list of names for named binds

};

struct odbc_rowid_backend : details::rowid_backend
{
    odbc_rowid_backend(odbc_session_backend &session);

    ~odbc_rowid_backend();
};

struct odbc_blob_backend : details::blob_backend
{
    odbc_blob_backend(odbc_session_backend &session);

    ~odbc_blob_backend();

    virtual std::size_t get_len();
    virtual std::size_t read(std::size_t offset, char *buf,
        std::size_t toRead);
    virtual std::size_t write(std::size_t offset, char const *buf,
        std::size_t toWrite);
    virtual std::size_t append(char const *buf, std::size_t toWrite);
    virtual void trim(std::size_t newLen);

    odbc_session_backend &session_;
};

struct odbc_session_backend : details::session_backend
{
    odbc_session_backend(connection_parameters const & parameters);

    ~odbc_session_backend();

    virtual void begin();
    virtual void commit();
    virtual void rollback();

    virtual bool get_next_sequence_value(session & s,
        std::string const & sequence, long & value);
    virtual bool get_last_insert_id(session & s,
        std::string const & table, long & value);

    virtual std::string get_backend_name() const { return "odbc"; }

    void reset_transaction();

    void clean_up();

    virtual odbc_statement_backend * make_statement_backend();
    virtual odbc_rowid_backend * make_rowid_backend();
    virtual odbc_blob_backend * make_blob_backend();

    enum database_product
    {
      prod_uninitialized, // Never returned by get_database_product().
      prod_firebird,
      prod_mssql,
      prod_mysql,
      prod_oracle,
      prod_postgresql,
      prod_sqlite,
      prod_unknown = -1
    };

    // Determine the type of the database we're connected to.
    database_product get_database_product();

    // Return full ODBC connection string.
    std::string get_connection_string() const { return connection_string_; }

    SQLHENV henv_;
    SQLHDBC hdbc_;

    std::string connection_string_;
    database_product product_;
};

class SOCI_ODBC_DECL odbc_soci_error : public soci_error
{
    SQLCHAR message_[SQL_MAX_MESSAGE_LENGTH + 1];
    SQLCHAR sqlstate_[SQL_SQLSTATE_SIZE + 1];
    SQLINTEGER sqlcode_;

public:
    odbc_soci_error(SQLSMALLINT htype,
                  SQLHANDLE hndl,
                  std::string const & msg)
        : soci_error(interpret_odbc_error(htype, hndl, msg))
    {
    }

    SQLCHAR const * odbc_error_code() const
    {
        return sqlstate_;
    }
    SQLINTEGER native_error_code() const
    {
        return sqlcode_;
    }
    SQLCHAR const * odbc_error_message() const
    {
        return message_;
    }
private:
    std::string interpret_odbc_error(SQLSMALLINT htype, SQLHANDLE hndl, std::string const& msg)
    {
        std::ostringstream ss(msg, std::ostringstream::app);

        const char* socierror = NULL;

        SQLSMALLINT length, i = 1;
        switch ( SQLGetDiagRecA(htype, hndl, i, sqlstate_, &sqlcode_,
                               message_, SQL_MAX_MESSAGE_LENGTH + 1,
                               &length) )
        {
          case SQL_SUCCESS:
            // The error message was successfully retrieved.
            break;

          case SQL_INVALID_HANDLE:
            socierror = "[SOCI]: Invalid handle.";
            break;

          case SQL_ERROR:
            socierror = "[SOCI]: SQLGetDiagRec() error.";
            break;

          case SQL_SUCCESS_WITH_INFO:
            socierror = "[SOCI]: Error message too long.";
            break;

          case SQL_NO_DATA:
            socierror = "[SOCI]: No error.";
            break;

          default:
            socierror = "[SOCI]: Unexpected SQLGetDiagRec() return value.";
            break;
        }

        if (socierror)
        {
            // Use our own error message if we failed to retrieve the ODBC one.
            strcpy(reinterpret_cast<char*>(message_), socierror);

            // Use "General warning" SQLSTATE code.
            strcpy(reinterpret_cast<char*>(sqlstate_), "01000");

            sqlcode_ = 0;
        }

        ss << ": " << message_ << " (" << sqlstate_ << ")";

        return ss.str();
    }
};

inline bool is_odbc_error(SQLRETURN rc)
{
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA)
    {
        return true;
    }
    else
    {
        return false;
    }
}

inline bool odbc_standard_type_backend_base::use_string_for_bigint() const
{
    // Oracle ODBC driver doesn't support SQL_C_[SU]BIGINT data types
    // (see appendix G.1 of Oracle Database Administrator's reference at
    // http://docs.oracle.com/cd/B19306_01/server.102/b15658/app_odbc.htm),
    // so we need a special workaround for this case and we represent 64
    // bit integers as strings and rely on ODBC driver for transforming
    // them to SQL_NUMERIC.
    return statement_.session_.get_database_product()
            == odbc_session_backend::prod_oracle;
}

struct odbc_backend_factory : backend_factory
{
    odbc_backend_factory() {}
    virtual odbc_session_backend * make_session(
        connection_parameters const & parameters) const;
};

extern SOCI_ODBC_DECL odbc_backend_factory const odbc;

extern "C"
{

// for dynamic backend loading
SOCI_ODBC_DECL backend_factory const * factory_odbc();
SOCI_ODBC_DECL void register_factory_odbc();

} // extern "C"

} // namespace soci

#endif // SOCI_EMPTY_H_INCLUDED