mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
8.1 KiB
225 lines
8.1 KiB
#ifndef __CLASS_SQLITE3DB_H
|
|
#define __CLASS_SQLITE3DB_H
|
|
#include <pthread.h>
|
|
#include "sqlite3.h"
|
|
#undef swap
|
|
#undef min
|
|
#undef max
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <vector>
|
|
#include <utility>
|
|
#define PROXYSQL_SQLITE3DB_PTHREAD_MUTEX
|
|
|
|
#ifndef SAFE_SQLITE3_STEP2
|
|
#define SAFE_SQLITE3_STEP2(_stmt) do {\
|
|
do {\
|
|
rc=(*proxy_sqlite3_step)(_stmt);\
|
|
if (rc==SQLITE_LOCKED || rc==SQLITE_BUSY) {\
|
|
usleep(100);\
|
|
}\
|
|
} while (rc==SQLITE_LOCKED || rc==SQLITE_BUSY);\
|
|
} while (0)
|
|
#endif // SAFE_SQLITE3_STEP2
|
|
|
|
#ifndef MAIN_PROXY_SQLITE3
|
|
extern int (*proxy_sqlite3_bind_double)(sqlite3_stmt*, int, double);
|
|
extern int (*proxy_sqlite3_bind_int)(sqlite3_stmt*, int, int);
|
|
extern int (*proxy_sqlite3_bind_int64)(sqlite3_stmt*, int, sqlite3_int64);
|
|
extern int (*proxy_sqlite3_bind_null)(sqlite3_stmt*, int);
|
|
extern int (*proxy_sqlite3_bind_text)(sqlite3_stmt*,int,const char*,int,void(*)(void*));
|
|
extern const char *(*proxy_sqlite3_column_name)(sqlite3_stmt*, int N);
|
|
extern const unsigned char *(*proxy_sqlite3_column_text)(sqlite3_stmt*, int iCol);
|
|
extern int (*proxy_sqlite3_column_bytes)(sqlite3_stmt*, int iCol);
|
|
extern int (*proxy_sqlite3_column_type)(sqlite3_stmt*, int iCol);
|
|
extern int (*proxy_sqlite3_column_count)(sqlite3_stmt *pStmt);
|
|
extern int (*proxy_sqlite3_column_int)(sqlite3_stmt*, int iCol);
|
|
extern const char *(*proxy_sqlite3_errmsg)(sqlite3*);
|
|
extern int (*proxy_sqlite3_finalize)(sqlite3_stmt *pStmt);
|
|
extern int (*proxy_sqlite3_reset)(sqlite3_stmt *pStmt);
|
|
extern int (*proxy_sqlite3_clear_bindings)(sqlite3_stmt*);
|
|
extern int (*proxy_sqlite3_close_v2)(sqlite3*);
|
|
extern int (*proxy_sqlite3_get_autocommit)(sqlite3*);
|
|
extern void (*proxy_sqlite3_free)(void*);
|
|
extern int (*proxy_sqlite3_status)(int op, int *pCurrent, int *pHighwater, int resetFlag);
|
|
extern int (*proxy_sqlite3_status64)(int op, long long *pCurrent, long long *pHighwater, int resetFlag);
|
|
extern int (*proxy_sqlite3_changes)(sqlite3*);
|
|
extern long long (*proxy_sqlite3_total_changes64)(sqlite3*);
|
|
extern int (*proxy_sqlite3_step)(sqlite3_stmt*);
|
|
extern int (*proxy_sqlite3_config)(int, ...);
|
|
extern int (*proxy_sqlite3_shutdown)(void);
|
|
|
|
extern int (*proxy_sqlite3_prepare_v2)(
|
|
sqlite3 *db, /* Database handle */
|
|
const char *zSql, /* SQL statement, UTF-8 encoded */
|
|
int nByte, /* Maximum length of zSql in bytes. */
|
|
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
|
|
const char **pzTail /* OUT: Pointer to unused portion of zSql */
|
|
);
|
|
|
|
extern int (*proxy_sqlite3_open_v2)(
|
|
const char *filename, /* Database filename (UTF-8) */
|
|
sqlite3 **ppDb, /* OUT: SQLite db handle */
|
|
int flags, /* Flags */
|
|
const char *zVfs /* Name of VFS module to use */
|
|
);
|
|
|
|
extern int (*proxy_sqlite3_exec)(
|
|
sqlite3*, /* An open database */
|
|
const char *sql, /* SQL to be evaluated */
|
|
int (*callback)(void*,int,char**,char**), /* Callback function */
|
|
void *, /* 1st argument to callback */
|
|
char **errmsg /* Error msg written here */
|
|
);
|
|
#else
|
|
int (*proxy_sqlite3_bind_double)(sqlite3_stmt*, int, double);
|
|
int (*proxy_sqlite3_bind_int)(sqlite3_stmt*, int, int);
|
|
int (*proxy_sqlite3_bind_int64)(sqlite3_stmt*, int, sqlite3_int64);
|
|
int (*proxy_sqlite3_bind_null)(sqlite3_stmt*, int);
|
|
int (*proxy_sqlite3_bind_text)(sqlite3_stmt*,int,const char*,int,void(*)(void*));
|
|
const char *(*proxy_sqlite3_column_name)(sqlite3_stmt*, int N);
|
|
const unsigned char *(*proxy_sqlite3_column_text)(sqlite3_stmt*, int iCol);
|
|
int (*proxy_sqlite3_column_bytes)(sqlite3_stmt*, int iCol);
|
|
int (*proxy_sqlite3_column_type)(sqlite3_stmt*, int iCol);
|
|
int (*proxy_sqlite3_column_count)(sqlite3_stmt *pStmt);
|
|
int (*proxy_sqlite3_column_int)(sqlite3_stmt*, int iCol);
|
|
const char *(*proxy_sqlite3_errmsg)(sqlite3*);
|
|
int (*proxy_sqlite3_finalize)(sqlite3_stmt *pStmt);
|
|
int (*proxy_sqlite3_reset)(sqlite3_stmt *pStmt);
|
|
int (*proxy_sqlite3_clear_bindings)(sqlite3_stmt*);
|
|
int (*proxy_sqlite3_close_v2)(sqlite3*);
|
|
int (*proxy_sqlite3_get_autocommit)(sqlite3*);
|
|
void (*proxy_sqlite3_free)(void*);
|
|
int (*proxy_sqlite3_status)(int op, int *pCurrent, int *pHighwater, int resetFlag);
|
|
int (*proxy_sqlite3_status64)(int op, long long *pCurrent, long long *pHighwater, int resetFlag);
|
|
|
|
int (*proxy_sqlite3_changes)(sqlite3*);
|
|
long long (*proxy_sqlite3_total_changes64)(sqlite3*);
|
|
int (*proxy_sqlite3_step)(sqlite3_stmt*);
|
|
int (*proxy_sqlite3_config)(int, ...);
|
|
int (*proxy_sqlite3_shutdown)(void);
|
|
|
|
int (*proxy_sqlite3_prepare_v2)(
|
|
sqlite3 *db, /* Database handle */
|
|
const char *zSql, /* SQL statement, UTF-8 encoded */
|
|
int nByte, /* Maximum length of zSql in bytes. */
|
|
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
|
|
const char **pzTail /* OUT: Pointer to unused portion of zSql */
|
|
);
|
|
|
|
int (*proxy_sqlite3_open_v2)(
|
|
const char *filename, /* Database filename (UTF-8) */
|
|
sqlite3 **ppDb, /* OUT: SQLite db handle */
|
|
int flags, /* Flags */
|
|
const char *zVfs /* Name of VFS module to use */
|
|
);
|
|
|
|
int (*proxy_sqlite3_exec)(
|
|
sqlite3*, /* An open database */
|
|
const char *sql, /* SQL to be evaluated */
|
|
int (*callback)(void*,int,char**,char**), /* Callback function */
|
|
void *, /* 1st argument to callback */
|
|
char **errmsg /* Error msg written here */
|
|
);
|
|
#endif //MAIN_PROXY_SQLITE3
|
|
|
|
class SQLite3_row {
|
|
public:
|
|
int cnt;
|
|
int ds;
|
|
int *sizes;
|
|
char **fields;
|
|
char *data;
|
|
SQLite3_row(int c);
|
|
unsigned long long get_size();
|
|
~SQLite3_row();
|
|
void add_fields(sqlite3_stmt *stmt);
|
|
void add_fields(char **_fields);
|
|
};
|
|
|
|
class SQLite3_column {
|
|
public:
|
|
int datatype;
|
|
char *name;
|
|
SQLite3_column(int a, const char *b);
|
|
~SQLite3_column();
|
|
};
|
|
|
|
class SQLite3_result {
|
|
public:
|
|
pthread_mutex_t m;
|
|
bool enabled_mutex;
|
|
int columns;
|
|
int rows_count;
|
|
char *checksum();
|
|
uint64_t raw_checksum();
|
|
|
|
std::vector<SQLite3_column *> column_definition;
|
|
std::vector<SQLite3_row *> rows;
|
|
SQLite3_result();
|
|
SQLite3_result(SQLite3_result *);
|
|
unsigned long long get_size();
|
|
void add_column_definition(int a, const char *b);
|
|
int add_row(sqlite3_stmt *stmt, bool skip=false);
|
|
int add_row(char **_fields);
|
|
int add_row(const char **_fields) { return add_row((char **)_fields); }
|
|
int add_row(SQLite3_row *old_row);
|
|
int add_row(const char* _field, ...);
|
|
SQLite3_result(sqlite3_stmt *stmt);
|
|
SQLite3_result(sqlite3_stmt *stmt, int *found_rows, unsigned int offset, unsigned int limit);
|
|
SQLite3_result(int num_columns, bool en_mutex=false);
|
|
~SQLite3_result();
|
|
void dump_to_stderr();
|
|
};
|
|
|
|
/**
|
|
* @brief Helper type for finalizing 'sqlite3_stmt' managed by smart pointers.
|
|
*/
|
|
struct stmt_deleter_t {
|
|
void operator()(sqlite3_stmt* x) const;
|
|
};
|
|
|
|
/**
|
|
* @brief Safe type for automatically deallocation of 'sqlite3_stmt'.
|
|
*/
|
|
using stmt_unique_ptr = std::unique_ptr<sqlite3_stmt, stmt_deleter_t>;
|
|
|
|
class SQLite3DB {
|
|
private:
|
|
char *url;
|
|
sqlite3 *db;
|
|
pthread_rwlock_t rwlock;
|
|
public:
|
|
char *get_url() const { return url; }
|
|
sqlite3 *get_db() const { return db; }
|
|
int assert_on_error;
|
|
SQLite3DB();
|
|
~SQLite3DB();
|
|
int open(char *, int);
|
|
|
|
void rdlock();
|
|
void rdunlock();
|
|
void wrlock();
|
|
void wrunlock();
|
|
|
|
bool execute(const char *);
|
|
bool execute_statement(const char *, char **, int *, int *, SQLite3_result **);
|
|
SQLite3_result* execute_statement(const char *, char **_error=NULL, int *_cols=NULL, int *_affected_rows=NULL);
|
|
bool execute_statement_raw(const char *, char **, int *, int *, sqlite3_stmt **);
|
|
int return_one_int(const char *);
|
|
int check_table_structure(char *table_name, char *table_def);
|
|
bool build_table(char *table_name, char *table_def, bool dropit);
|
|
bool check_and_build_table(char *table_name, char *table_def);
|
|
[[deprecated("Use safer alternative 'prepare_v2(const char *)'")]]
|
|
int prepare_v2(const char *, sqlite3_stmt **);
|
|
/**
|
|
* @brief Prepares a query as a statement in the SQLite3DB.
|
|
* @param query The query to be prepared as an 'sqlite3_stmt'.
|
|
* @return A pair of with shape { err_code, stmt_unique_ptr }.
|
|
*/
|
|
std::pair<int,stmt_unique_ptr> prepare_v2(const char* query);
|
|
static void LoadPlugin(const char *);
|
|
};
|
|
|
|
#endif /* __CLASS_SQLITE3DB_H */
|