This file is indexed.

/usr/include/dballe/sql/sqlite.h is in libdballe-dev 7.21-1.

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
/** @file
 * SQLite DB connector
 */
#ifndef DBALLE_SQL_SQLITE_H
#define DBALLE_SQL_SQLITE_H

#include <dballe/core/error.h>
#include <dballe/sql/sql.h>
#include <sqlite3.h>
#include <vector>

namespace dballe {
namespace sql {
struct SQLiteStatement;

/**
 * Report an SQLite error
 */
struct error_sqlite : public dballe::error_db
{
    std::string msg;

    error_sqlite(sqlite3* db, const std::string& msg);
    error_sqlite(const std::string& dbmsg, const std::string& msg);
    ~error_sqlite() noexcept {}

    const char* what() const noexcept override { return msg.c_str(); }

    static void throwf(sqlite3* db, const char* fmt, ...) WREPORT_THROWF_ATTRS(2, 3);
};

/// Database connection
class SQLiteConnection : public Connection
{
protected:
    /// Database connection
    sqlite3* db = nullptr;

    void init_after_connect();
    static void on_sqlite3_profile(void* arg, const char* query, sqlite3_uint64 usecs);

public:
    SQLiteConnection();
    SQLiteConnection(const SQLiteConnection&) = delete;
    SQLiteConnection(const SQLiteConnection&&) = delete;
    ~SQLiteConnection();

    SQLiteConnection& operator=(const SQLiteConnection&) = delete;

    operator sqlite3*() { return db; }

    void open_file(const std::string& pathname, int flags=SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    void open_memory(int flags=SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
    void open_private_file(int flags=SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);

    std::unique_ptr<Transaction> transaction() override;
    std::unique_ptr<SQLiteStatement> sqlitestatement(const std::string& query);

    bool has_table(const std::string& name) override;
    std::string get_setting(const std::string& key) override;
    void set_setting(const std::string& key, const std::string& value) override;
    void drop_settings() override;
    void execute(const std::string& query) override;
    void explain(const std::string& query, FILE* out) override;

    /**
     * Delete a table in the database if it exists, otherwise do nothing.
     */
    void drop_table_if_exists(const char* name);

    /**
     * Return LAST_INSERT_ID or LAST_INSER_ROWID or whatever is appropriate for
     * the current database, if supported.
     *
     * If not supported, an exception is thrown.
     */
    int get_last_insert_id();

    /// Count the number of rows modified by the last query that was run
    int changes();

    /// Wrap sqlite3_exec, without a callback
    void exec(const std::string& query);
    void exec_nothrow(const std::string& query) noexcept;
};

/// SQLite statement
struct SQLiteStatement
{
    SQLiteConnection& conn;
    sqlite3_stmt *stm = nullptr;

    SQLiteStatement(SQLiteConnection& conn, const std::string& query);
    SQLiteStatement(const SQLiteStatement&) = delete;
    SQLiteStatement(const SQLiteStatement&&) = delete;
    ~SQLiteStatement();
    SQLiteStatement& operator=(const SQLiteStatement&) = delete;

    /**
     * Bind all the arguments in a single invocation.
     *
     * Note that the parameter positions are used as bind column numbers, so
     * calling this function twice will re-bind columns instead of adding new
     * ones.
     */
    template<typename... Args> void bind(const Args& ...args)
    {
        bindn<sizeof...(args)>(args...);
    }

    void bind_null_val(int idx);
    void bind_val(int idx, int val);
    void bind_val(int idx, unsigned val);
    void bind_val(int idx, unsigned short val);
    void bind_val(int idx, const Datetime& val);
    void bind_val(int idx, const char* val); // Warning: SQLITE_STATIC is used
    void bind_val(int idx, const std::string& val); // Warning: SQLITE_STATIC is used
    void bind_val(int idx, const std::vector<uint8_t>& val); // Warning: SQLITE_STATIC is used

    /// Run the query, ignoring all results
    void execute();

    /**
     * Run the query, calling on_row for every row in the result.
     *
     * At the end of the function, the statement is reset, even in case an
     * exception is thrown.
     */
    void execute(std::function<void()> on_row);

    /**
     * Run the query, raising an error if there is more than one row in the
     * result
     */
    void execute_one(std::function<void()> on_row);

    /// Read the int value of a column in the result set (0-based)
    int column_int(int col) { return sqlite3_column_int(stm, col); }

    /// Read the int value of a column in the result set (0-based)
    sqlite3_int64 column_int64(int col) { return sqlite3_column_int64(stm, col); }

    /// Read the double value of a column in the result set (0-based)
    double column_double(int col) { return sqlite3_column_double(stm, col); }

    /// Read the string value of a column in the result set (0-based)
    const char* column_string(int col) { return (const char*)sqlite3_column_text(stm, col); }

    /// Read the string value of a column in the result set (0-based)
    std::vector<uint8_t> column_blob(int col) {
        int size = sqlite3_column_bytes(stm, col);
        const uint8_t* val = (const uint8_t*)sqlite3_column_blob(stm, col);
        return std::vector<uint8_t>(val, val + size);
    }

    /// Read the string value of a column and parse it as a Datetime
    Datetime column_datetime(int col);

    /// Check if a column has a NULL value (0-based)
    bool column_isnull(int col) { return sqlite3_column_type(stm, col) == SQLITE_NULL; }

    void wrap_sqlite3_reset();
    void wrap_sqlite3_reset_nothrow() noexcept;
    /**
     * Get the current error message, reset the statement and throw
     * error_sqlite
     */
    [[noreturn]] void reset_and_throw(const std::string& errmsg);

    operator sqlite3_stmt*() { return stm; }
#if 0
    /// @return SQLExecute's result
    int execute();
    /// @return SQLExecute's result
    int exec_direct(const char* query);
    /// @return SQLExecute's result
    int exec_direct(const char* query, int qlen);

    /// @return SQLExecute's result
    int execute_and_close();
    /// @return SQLExecute's result
    int exec_direct_and_close(const char* query);
    /// @return SQLExecute's result
    int exec_direct_and_close(const char* query, int qlen);

    /**
     * @return the number of columns in the result set (or 0 if the statement
     * did not return columns)
     */
    int columns_count();
    bool fetch();
    bool fetch_expecting_one();
    void close_cursor();
    void close_cursor_if_needed();
    /// Row count for select operations
    size_t select_rowcount();
    /// Row count for insert, delete and other non-select operations
    size_t rowcount();
#endif

private:
    // Implementation of variadic bind: terminating condition
    template<size_t total> void bindn() {}
    // Implementation of variadic bind: recursive iteration over the parameter pack
    template<size_t total, typename ...Args, typename T> void bindn(const T& first, const Args& ...args)
    {
        bind_val(total - sizeof...(args), first);
        bindn<total>(args...);
    }
};

}
}
#endif