|
|
|
|
@ -4,15 +4,117 @@
|
|
|
|
|
|
|
|
|
|
#define USLEEP_SQLITE_LOCKED 100
|
|
|
|
|
|
|
|
|
|
SQLite3_column::SQLite3_column(int a, const char *b) {
|
|
|
|
|
datatype=a;
|
|
|
|
|
if (b) {
|
|
|
|
|
name=strdup(b);
|
|
|
|
|
} else {
|
|
|
|
|
name=strdup((char *)"");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_column::~SQLite3_column() {
|
|
|
|
|
free(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLite3_row::SQLite3_row(int c) {
|
|
|
|
|
sizes=(int *)malloc(sizeof(int)*c);
|
|
|
|
|
fields=(char **)malloc(sizeof(char *)*c);
|
|
|
|
|
memset(fields,0,sizeof(char *)*c);
|
|
|
|
|
cnt=c;
|
|
|
|
|
data=NULL;
|
|
|
|
|
ds=0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned long long SQLite3_row::get_size() {
|
|
|
|
|
unsigned long long s = sizeof(SQLite3_row);
|
|
|
|
|
s += cnt * sizeof(int);
|
|
|
|
|
s += cnt * sizeof(char *);
|
|
|
|
|
s += ds;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_row::~SQLite3_row() {
|
|
|
|
|
free(fields);
|
|
|
|
|
free(sizes);
|
|
|
|
|
if (data) {
|
|
|
|
|
free(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3_row::add_fields(sqlite3_stmt *stmt) {
|
|
|
|
|
int i;
|
|
|
|
|
int t;
|
|
|
|
|
int data_size=0;
|
|
|
|
|
int data_ptr=0;
|
|
|
|
|
// compute the length
|
|
|
|
|
for (i=0;i<cnt;i++) {
|
|
|
|
|
t=sqlite3_column_type(stmt,i);
|
|
|
|
|
if (t==SQLITE_NULL) {
|
|
|
|
|
sizes[i]=0;
|
|
|
|
|
} else {
|
|
|
|
|
sizes[i]=sqlite3_column_bytes(stmt,i);
|
|
|
|
|
data_size+=sizes[i];
|
|
|
|
|
data_size++; // leading 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (data_size) {
|
|
|
|
|
data=(char *)malloc(data_size);
|
|
|
|
|
}
|
|
|
|
|
for (i=0;i<cnt;i++) {
|
|
|
|
|
t=sqlite3_column_type(stmt,i);
|
|
|
|
|
const char *c=(char *)sqlite3_column_text(stmt,i);
|
|
|
|
|
if (t==SQLITE_NULL) {
|
|
|
|
|
//sizes[i]=0;
|
|
|
|
|
fields[i]=NULL;
|
|
|
|
|
} else {
|
|
|
|
|
memcpy(data+data_ptr,c,sizes[i]);
|
|
|
|
|
fields[i]=data+data_ptr;
|
|
|
|
|
data_ptr+=sizes[i];
|
|
|
|
|
data[data_ptr]='\0';
|
|
|
|
|
data_ptr++; // leading 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ds=data_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3_row::add_fields(char **_fields) {
|
|
|
|
|
int i;
|
|
|
|
|
int data_size=0;
|
|
|
|
|
int data_ptr=0;
|
|
|
|
|
for (i=0;i<cnt;i++) {
|
|
|
|
|
if (_fields[i]) {
|
|
|
|
|
sizes[i]=strlen(_fields[i]);
|
|
|
|
|
data_size+=sizes[i];
|
|
|
|
|
data_size++; // leading 0
|
|
|
|
|
} else {
|
|
|
|
|
sizes[i]=0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (data_size) {
|
|
|
|
|
data=(char *)malloc(data_size);
|
|
|
|
|
}
|
|
|
|
|
for (i=0;i<cnt;i++) {
|
|
|
|
|
if (_fields[i]) {
|
|
|
|
|
memcpy(data+data_ptr,_fields[i],sizes[i]);
|
|
|
|
|
fields[i]=data+data_ptr;
|
|
|
|
|
data_ptr+=sizes[i];
|
|
|
|
|
data[data_ptr]='\0';
|
|
|
|
|
data_ptr++; // leading 0
|
|
|
|
|
} else {
|
|
|
|
|
fields[i]=NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ds=data_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SQLite3DB::SQLite3DB() {
|
|
|
|
|
db=NULL;
|
|
|
|
|
url=NULL;
|
|
|
|
|
assert_on_error=0;
|
|
|
|
|
#ifdef PROXYSQL_SQLITE3DB_PTHREAD_MUTEX
|
|
|
|
|
pthread_rwlock_init(&rwlock, NULL);
|
|
|
|
|
#else
|
|
|
|
|
spinlock_rwlock_init(&rwlock);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3DB::~SQLite3DB() {
|
|
|
|
|
@ -239,35 +341,19 @@ bool SQLite3DB::check_and_build_table(char *table_name, char *table_def) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3DB::rdlock() {
|
|
|
|
|
#ifdef PROXYSQL_SQLITE3DB_PTHREAD_MUTEX
|
|
|
|
|
pthread_rwlock_rdlock(&rwlock);
|
|
|
|
|
#else
|
|
|
|
|
spin_wrlock(&rwlock);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3DB::rdunlock() {
|
|
|
|
|
#ifdef PROXYSQL_SQLITE3DB_PTHREAD_MUTEX
|
|
|
|
|
pthread_rwlock_unlock(&rwlock);
|
|
|
|
|
#else
|
|
|
|
|
spin_wrunlock(&rwlock);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3DB::wrlock() {
|
|
|
|
|
#ifdef PROXYSQL_SQLITE3DB_PTHREAD_MUTEX
|
|
|
|
|
pthread_rwlock_wrlock(&rwlock);
|
|
|
|
|
#else
|
|
|
|
|
spin_wrlock(&rwlock);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3DB::wrunlock() {
|
|
|
|
|
#ifdef PROXYSQL_SQLITE3DB_PTHREAD_MUTEX
|
|
|
|
|
pthread_rwlock_unlock(&rwlock);
|
|
|
|
|
#else
|
|
|
|
|
spin_wrunlock(&rwlock);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t SQLite3_result::raw_checksum() {
|
|
|
|
|
@ -401,3 +487,109 @@ void SQLite3_result::dump_to_stderr() {
|
|
|
|
|
fprintf(stderr,"%s\n",s.c_str());
|
|
|
|
|
free(columns_lengths);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_result::SQLite3_result(SQLite3_result *src) {
|
|
|
|
|
rows_count=0;
|
|
|
|
|
columns=src->columns;
|
|
|
|
|
if (src->enabled_mutex) {
|
|
|
|
|
pthread_mutex_init(&m,NULL);
|
|
|
|
|
enabled_mutex = true;
|
|
|
|
|
} else {
|
|
|
|
|
enabled_mutex = false;
|
|
|
|
|
}
|
|
|
|
|
for (std::vector<SQLite3_column *>::iterator it = src->column_definition.begin() ; it != src->column_definition.end(); ++it) {
|
|
|
|
|
SQLite3_column *r=*it;
|
|
|
|
|
add_column_definition(SQLITE_TEXT,r->name);
|
|
|
|
|
}
|
|
|
|
|
for (std::vector<SQLite3_row *>::iterator it = src->rows.begin() ; it != src->rows.end(); ++it) {
|
|
|
|
|
SQLite3_row *r=*it;
|
|
|
|
|
add_row(r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned long long SQLite3_result::get_size() {
|
|
|
|
|
unsigned long long s = sizeof(SQLite3_result);
|
|
|
|
|
s += column_definition.size() * sizeof(SQLite3_column *);
|
|
|
|
|
s += rows.size() * sizeof(SQLite3_row *);
|
|
|
|
|
for (std::vector<SQLite3_column *>::iterator it = column_definition.begin() ; it != column_definition.end(); ++it) {
|
|
|
|
|
SQLite3_column *r=*it;
|
|
|
|
|
s+= sizeof(SQLite3_column) + strlen(r->name);
|
|
|
|
|
}
|
|
|
|
|
for (std::vector<SQLite3_row *>::iterator it = rows.begin() ; it != rows.end(); ++it) {
|
|
|
|
|
SQLite3_row *r=*it;
|
|
|
|
|
s += r->get_size();
|
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SQLite3_result::add_column_definition(int a, const char *b) {
|
|
|
|
|
SQLite3_column *cf=new SQLite3_column(a,b);
|
|
|
|
|
column_definition.push_back(cf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SQLite3_result::add_row(sqlite3_stmt *stmt) {
|
|
|
|
|
int rc=sqlite3_step(stmt);
|
|
|
|
|
if (rc!=SQLITE_ROW) return rc;
|
|
|
|
|
SQLite3_row *row=new SQLite3_row(columns);
|
|
|
|
|
row->add_fields(stmt);
|
|
|
|
|
rows.push_back(row);
|
|
|
|
|
rows_count++;
|
|
|
|
|
return SQLITE_ROW;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SQLite3_result::add_row(char **_fields) {
|
|
|
|
|
SQLite3_row *row=new SQLite3_row(columns);
|
|
|
|
|
row->add_fields(_fields);
|
|
|
|
|
if (enabled_mutex) {
|
|
|
|
|
pthread_mutex_lock(&m);
|
|
|
|
|
}
|
|
|
|
|
rows.push_back(row);
|
|
|
|
|
rows_count++;
|
|
|
|
|
if (enabled_mutex) {
|
|
|
|
|
pthread_mutex_unlock(&m);
|
|
|
|
|
}
|
|
|
|
|
return SQLITE_ROW;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SQLite3_result::add_row(SQLite3_row *old_row) {
|
|
|
|
|
SQLite3_row *row=new SQLite3_row(columns);
|
|
|
|
|
row->add_fields(old_row->fields);
|
|
|
|
|
rows.push_back(row);
|
|
|
|
|
rows_count++;
|
|
|
|
|
return SQLITE_ROW;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_result::SQLite3_result(sqlite3_stmt *stmt) {
|
|
|
|
|
rows_count=0;
|
|
|
|
|
columns=sqlite3_column_count(stmt);
|
|
|
|
|
for (int i=0; i<columns; i++) {
|
|
|
|
|
add_column_definition(sqlite3_column_type(stmt,i), sqlite3_column_name(stmt,i));
|
|
|
|
|
}
|
|
|
|
|
while (add_row(stmt)==SQLITE_ROW) {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_result::SQLite3_result(int num_columns, bool en_mutex) {
|
|
|
|
|
rows_count=0;
|
|
|
|
|
columns=num_columns;
|
|
|
|
|
if (en_mutex) {
|
|
|
|
|
pthread_mutex_init(&m,NULL);
|
|
|
|
|
enabled_mutex = true;
|
|
|
|
|
} else {
|
|
|
|
|
enabled_mutex = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_result::~SQLite3_result() {
|
|
|
|
|
for (std::vector<SQLite3_column *>::iterator it = column_definition.begin() ; it != column_definition.end(); ++it) {
|
|
|
|
|
SQLite3_column *c=*it;
|
|
|
|
|
delete c;
|
|
|
|
|
}
|
|
|
|
|
for (std::vector<SQLite3_row *>::iterator it = rows.begin() ; it != rows.end(); ++it) {
|
|
|
|
|
SQLite3_row *r=*it;
|
|
|
|
|
delete r;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLite3_result::SQLite3_result() {
|
|
|
|
|
columns=0;
|
|
|
|
|
}
|
|
|
|
|
|