Formatted
All checks were successful
SORM tests / Compile (push) Successful in 4s

This commit is contained in:
retoor 2024-11-22 15:51:47 +01:00
parent 6d5d810f0d
commit 681fbc3a96
5 changed files with 408 additions and 460 deletions

138
cli.h
View File

@ -1,19 +1,19 @@
#ifndef SORM_CLI_H #ifndef SORM_CLI_H
#define SORM_CLI_H #define SORM_CLI_H
#include <rlib.h> #include "sorm.h"
#include <fcntl.h>
#include <readline/history.h>
#include <readline/readline.h>
#include <rlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <readline/readline.h> #include <unistd.h>
#include <readline/history.h>
#include "sorm.h"
const char * history_filename = ".sorm_history"; const char *history_filename = ".sorm_history";
int _sorm_readline_accept_line(int count, int key) { int _sorm_readline_accept_line(int count, int key) {
if (strchr(rl_line_buffer, ';')) { if (strchr(rl_line_buffer, ';')) {
rl_done = 1; rl_done = 1;
@ -23,18 +23,9 @@ const char * history_filename = ".sorm_history";
return 0; return 0;
} }
char* _sorm_autocompletion_generator(const char* text, int state) { char *_sorm_autocompletion_generator(const char *text, int state) {
const char* completions[] = { const char *completions[] = {"exit", sorm_last_query, sorm_last_query_expanded, "python", "history", "memory", "truncate", NULL};
"exit", int list_index;
sorm_last_query,
sorm_last_query_expanded,
"python",
"history",
"memory",
"truncate",
NULL
};
int list_index;
if (!state) { if (!state) {
list_index = 0; list_index = 0;
@ -50,26 +41,22 @@ char* _sorm_autocompletion_generator(const char* text, int state) {
return NULL; return NULL;
} }
char** _sorm_autocomplete(const char* text, int start, int end) { char **_sorm_autocomplete(const char *text, int start, int end) {
rl_attempted_completion_over = 1; rl_attempted_completion_over = 1;
return rl_completion_matches(text, _sorm_autocompletion_generator); return rl_completion_matches(text, _sorm_autocompletion_generator);
} }
int _hs_read_file(const char *filename, char *buffer, size_t size) {
int
_hs_read_file (const char *filename, char *buffer, size_t size)
{
int fd; int fd;
ssize_t bytes_read; ssize_t bytes_read;
fd = open (filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;
bytes_read = read (fd, buffer, size); bytes_read = read(fd, buffer, size);
close (fd); close(fd);
if (bytes_read < 0 || (size_t)bytes_read != size) if (bytes_read < 0 || (size_t)bytes_read != size)
return -1; return -1;
@ -77,25 +64,22 @@ _hs_read_file (const char *filename, char *buffer, size_t size)
return 0; return 0;
} }
int sorm_cli_history_dump(const char *filename) {
int
sorm_cli_history_dump (const char *filename)
{
register int line_start, line_end; register int line_start, line_end;
char *input; char *input;
struct stat finfo; struct stat finfo;
size_t file_size; size_t file_size;
if (stat (filename, &finfo) < 0) if (stat(filename, &finfo) < 0)
return -1; return -1;
file_size = (size_t)finfo.st_size; file_size = (size_t)finfo.st_size;
input = (char *)malloc (file_size + 1); input = (char *)malloc(file_size + 1);
if (!input) if (!input)
return -1; return -1;
if (_hs_read_file (filename, input, file_size) < 0) { if (_hs_read_file(filename, input, file_size) < 0) {
free (input); free(input);
return -1; return -1;
} }
input[file_size] = '\0'; input[file_size] = '\0';
@ -104,25 +88,25 @@ sorm_cli_history_dump (const char *filename)
if (input[line_end] == '\n') { if (input[line_end] == '\n') {
input[line_end] = '\0'; input[line_end] = '\0';
printf ("%s\n",input + line_start); printf("%s\n", input + line_start);
line_start = line_end + 1; line_start = line_end + 1;
} }
} }
if (line_start < file_size) if (line_start < file_size)
printf ("%s\n",input + line_start); printf("%s\n", input + line_start);
free (input); free(input);
return where_history (); return where_history();
} }
char sorm_history_filename[4096]; char sorm_history_filename[4096];
void sorm_cli_init(const char * history_filename){ void sorm_cli_init(const char *history_filename) {
strcpy(sorm_history_filename, history_filename); strcpy(sorm_history_filename, history_filename);
rl_bind_key('\n',NULL); rl_bind_key('\n', NULL);
rl_bind_key('\r', NULL); rl_bind_key('\r', NULL);
rl_add_defun("custom-accept-line", _sorm_readline_accept_line, '\n'); rl_add_defun("custom-accept-line", _sorm_readline_accept_line, '\n');
rl_add_defun("custom-accept-line-cr", _sorm_readline_accept_line, '\r'); rl_add_defun("custom-accept-line-cr", _sorm_readline_accept_line, '\r');
@ -136,49 +120,49 @@ void sorm_cli_init(const char * history_filename){
} }
char sorm_cli_previous_command[sizeof(rl_line_buffer)]; char sorm_cli_previous_command[sizeof(rl_line_buffer)];
char * sorm_cli_readline(char * prompt){ char *sorm_cli_readline(char *prompt) {
char * result = readline(prompt); char *result = readline(prompt);
if(strcmp(rl_line_buffer,sorm_cli_previous_command)){ if (strcmp(rl_line_buffer, sorm_cli_previous_command)) {
add_history((const char *)result); add_history((const char *)result);
write_history(sorm_history_filename); write_history(sorm_history_filename);
} }
strcpy(sorm_cli_previous_command,rl_line_buffer); strcpy(sorm_cli_previous_command, rl_line_buffer);
return result; return result;
} }
bool sormrepl_handle_command(char *command) {
bool sormrepl_handle_command(char * command){ if (!strncmp(command, "history", 7)) {
if(!strncmp(command, "history",7)){ sorm_cli_history_dump(history_filename);
sorm_cli_history_dump(history_filename); return true;
return true; }
}
return false; return false;
} }
void sormrepl(int sorm){ void sormrepl(int sorm) {
sorm_t * db = sormg(sorm); sorm_t *db = sormg(sorm);
char sql[4097]; char sql[4097];
sorm_cli_init(history_filename); sorm_cli_init(history_filename);
char * query; char *query;
while((query = sorm_cli_readline("sql> "))){ while ((query = sorm_cli_readline("sql> "))) {
if(sormrepl_handle_command(query)) if (sormrepl_handle_command(query))
continue; continue;
sorm_ptr res = sormq(sorm,query); sorm_ptr res = sormq(sorm, query);
if(res){ if (res) {
if(sormqt(query) == SORM_SELECT){ if (sormqt(query) == SORM_SELECT) {
int length = sormlv(res); int length = sormlv(res);
sormfmtd(res); sormfmtd(res);
free(res); free(res);
}else if(sormqt(query) == SORM_DELETE){ } else if (sormqt(query) == SORM_DELETE) {
printf("%d records affected.\n",res); printf("%d records affected.\n", res);
}else if(sormqt(query) == SORM_INSERT){ } else if (sormqt(query) == SORM_INSERT) {
printf("Last insert id: %d.\n",res); printf("Last insert id: %d.\n", res);
}
} }
printf("Rows: %lld, Execute %s, Format: %s\n",sorm_row_count, format_time(_sorm_query_duration),format_time(_sorm_result_format_duration));
printf("%s\n",rmalloc_stats());
} }
printf("Rows: %lld, Execute %s, Format: %s\n", sorm_row_count, format_time(_sorm_query_duration),
format_time(_sorm_result_format_duration));
printf("%s\n", rmalloc_stats());
}
} }
#endif #endif

44
main.c
View File

@ -1,39 +1,27 @@
#include "sorm.h"
#include "cli.h" #include "cli.h"
#include "sorm.h"
int main() { int main() {
int db = sormc("db.sqlite3"); int db = sormc("db.sqlite3");
//sormq(db,"DROP TABLE IF EXISTS pony;"); // sormq(db,"DROP TABLE IF EXISTS pony;");
printf("%d\n",db); printf("%d\n", db);
sormq(db, "CREATE TABLE IF NOT EXISTS pony (id INTEGER PRIMARY KEY AUTOINCREMENT,name,age);",NULL); sormq(db, "CREATE TABLE IF NOT EXISTS pony (id INTEGER PRIMARY KEY AUTOINCREMENT,name,age);", NULL);
sorm_pk iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);", sorm_pk iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);", "Teenii", 19);
"Teenii", iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);", "Amber", 20);
19 iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);", "Feuerherz", 20);
);
iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);",
"Amber",
20
);
iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);",
"Feuerherz",
20
);
iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);", iid = sormq(db, "INSERT INTO pony (id,name,age) VALUES (NULL,%s,%d);", "Retoor", 34);
"Retoor", sorm_str csv = sormq(db, "SELECT * FROM pony WHERE id in (?i,?i,?i)", 1, 2, 3);
34 sorm_str csv2 = sormq(db, "SELECT * FROM pony WHERE id = %d and age = %d ", 1, 33);
);
sorm_str csv = sormq(db, "SELECT * FROM pony WHERE id in (?i,?i,?i)",1,2,3);
sorm_str csv2 = sormq(db, "SELECT * FROM pony WHERE id = %d and age = %d ", 1,33);
sorm_str csv3 = sormq(db, "SELECT * FROM pony LIMIT 2"); sorm_str csv3 = sormq(db, "SELECT * FROM pony LIMIT 2");
//free(csv3); // free(csv3);
//free(csv2); // free(csv2);
if(csv2) if (csv2)
printf("%s\n",csv2); printf("%s\n", csv2);
printf("%s\n",csv3); printf("%s\n", csv3);
free(csv3); free(csv3);
sormd(db); sormd(db);
printf("%s\n",rmalloc_stats()); printf("%s\n", rmalloc_stats());
db = sormc("db.sqlite3"); db = sormc("db.sqlite3");
sormrepl(db); sormrepl(db);
} }

479
sorm.h
View File

@ -1,21 +1,20 @@
#ifndef SORM_H #ifndef SORM_H
#define SORM_H #define SORM_H
#include "str.h"
#include <ctype.h>
#include <rlib.h> #include <rlib.h>
#include <sqlite3.h> #include <sqlite3.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <stdarg.h>
#include <ctype.h>
#include "str.h"
sqlite3 *db; sqlite3 *db;
sqlite3_stmt *stmt; sqlite3_stmt *stmt;
char *sorm_last_query = NULL;
char * sorm_last_query = NULL; char *sorm_last_query_expanded = NULL;
char * sorm_last_query_expanded = NULL;
nsecs_t _sorm_query_start = 0; nsecs_t _sorm_query_start = 0;
nsecs_t _sorm_query_end = 0; nsecs_t _sorm_query_end = 0;
@ -28,10 +27,10 @@ nsecs_t _sorm_result_format_duration = 0;
int64_t sorm_row_count = 0; int64_t sorm_row_count = 0;
typedef struct sorm_t { typedef struct sorm_t {
sqlite3 * conn; sqlite3 *conn;
int current_row; int current_row;
int current_column; int current_column;
char * csv; char *csv;
nsecs_t time_query_start; nsecs_t time_query_start;
nsecs_t time_query_end; nsecs_t time_query_end;
nsecs_t time_query_duration; nsecs_t time_query_duration;
@ -39,26 +38,24 @@ typedef struct sorm_t {
nsecs_t time_result_format_end; nsecs_t time_result_format_end;
nsecs_t time_result_format_duration; nsecs_t time_result_format_duration;
} sorm_t; } sorm_t;
typedef char * sorm_pk; typedef char *sorm_pk;
typedef char * sorm_int; typedef char *sorm_int;
typedef char * sorm_ptr; typedef char *sorm_ptr;
typedef unsigned char * sorm_str; typedef unsigned char *sorm_str;
typedef double sorm_double; typedef double sorm_double;
typedef double sorm_float; typedef double sorm_float;
typedef bool sorm_bool; typedef bool sorm_bool;
int sormc(char * path); int sormc(char *path);
void sormd(int db); void sormd(int db);
char * sormpt(char * sql, int number); char *sormpt(char *sql, int number);
unsigned int sormcq(char * sql, char * out); unsigned int sormcq(char *sql, char *out);
unsigned int sormpc(char * sql); unsigned int sormpc(char *sql);
sqlite3_stmt * sormb(sorm_t* db, char * sql, ...); sqlite3_stmt *sormb(sorm_t *db, char *sql, ...);
sorm_ptr sormq(int db, char * sql, ...); sorm_ptr sormq(int db, char *sql, ...);
char * sorm_csvc(int db, sqlite3_stmt * stmt); char *sorm_csvc(int db, sqlite3_stmt *stmt);
char * sorm_csvd(int db, sqlite3_stmt * stmt); char *sorm_csvd(int db, sqlite3_stmt *stmt);
char * sorm_csv(int db,sqlite3_stmt * stmt); char *sorm_csv(int db, sqlite3_stmt *stmt);
typedef enum sorm_query_t { typedef enum sorm_query_t {
SORM_UNKNOWN = 0, SORM_UNKNOWN = 0,
@ -71,21 +68,18 @@ typedef enum sorm_query_t {
const int sorm_null = -1337; const int sorm_null = -1337;
sorm_t **sorm_instances = NULL;
sorm_t ** sorm_instances = NULL;
int sorm_instance_count = 0; int sorm_instance_count = 0;
int sormc(char *path) {
int sormc(char * path){
// sorm connect // sorm connect
printf("HIERR\n"); printf("HIERR\n");
sorm_instance_count++; sorm_instance_count++;
sorm_instance_count++; sorm_instance_count++;
sorm_instances = realloc(sorm_instances,sorm_instance_count * sizeof(sorm_t *) + sorm_instance_count * sizeof(sorm_t)); sorm_instances = realloc(sorm_instances, sorm_instance_count * sizeof(sorm_t *) + sorm_instance_count * sizeof(sorm_t));
printf("HIERR\n"); printf("HIERR\n");
sorm_t * db = &sorm_instances[sorm_instance_count - 1]; sorm_t *db = &sorm_instances[sorm_instance_count - 1];
printf("HIERR\n"); printf("HIERR\n");
db->conn = NULL; db->conn = NULL;
@ -101,93 +95,86 @@ int sormc(char * path){
db->time_result_format_end = 0; db->time_result_format_end = 0;
db->time_result_format_start = 0; db->time_result_format_start = 0;
if(sqlite3_open(path,&db->conn)) if (sqlite3_open(path, &db->conn)) {
{ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db->conn));
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db->conn)); return 0;
return 0;
} }
printf("DONE!\n"); printf("DONE!\n");
return sorm_instance_count; return sorm_instance_count;
} }
sorm_t * sormg(int ptr){ sorm_t *sormg(int ptr) { return &sorm_instances[ptr - 1]; }
return &sorm_instances[ptr -1];
}
char * sormgcsv(int ptr){ char *sormgcsv(int ptr) {
/* sorm get csv*/ /* sorm get csv*/
sorm_t * db = sormg(ptr); sorm_t *db = sormg(ptr);
return db->csv; return db->csv;
} }
void sormd(int sorm){ void sormd(int sorm) {
sorm_t * db = sormg(sorm); sorm_t *db = sormg(sorm);
if(sqlite3_close(db->conn)) if (sqlite3_close(db->conn)) {
{
fprintf(stderr, "Error closing database: %s\n", sqlite3_errmsg(db->conn)); fprintf(stderr, "Error closing database: %s\n", sqlite3_errmsg(db->conn));
} }
if(sorm_last_query){ if (sorm_last_query) {
free(sorm_last_query); free(sorm_last_query);
sorm_last_query = NULL; sorm_last_query = NULL;
} }
if(sorm_last_query_expanded){ if (sorm_last_query_expanded) {
free(sorm_last_query_expanded); free(sorm_last_query_expanded);
sorm_last_query_expanded = NULL; sorm_last_query_expanded = NULL;
} }
} }
char * sormpt(char * sql, int number){ char *sormpt(char *sql, int number) {
// param type // param type
char * sqlp = sql; char *sqlp = sql;
char * result = NULL; char *result = NULL;
int index = 0; int index = 0;
while(*sqlp){ while (*sqlp) {
if(*sqlp == '%' || *sqlp == '?'){ if (*sqlp == '%' || *sqlp == '?') {
sqlp++; sqlp++;
switch(*sqlp){ switch (*sqlp) {
case 'f': case 'f':
result = "double"; result = "double";
break; break;
case 's': case 's':
result = "text"; result = "text";
break; break;
case 'd': case 'd':
result = "int"; result = "int";
break; break;
case 'b': case 'b':
result = "blob"; result = "blob";
break; break;
default: default:
result = "?"; result = "?";
break; break;
} }
sqlp++; sqlp++;
index++; index++;
} }
if(index == number){ if (index == number) {
return result; return result;
} }
if(*sqlp) if (*sqlp)
sqlp++; sqlp++;
} }
if(number > index){ if (number > index) {
printf("RETURNED\n"); printf("RETURNED\n");
return NULL; return NULL;
} }
return NULL; return NULL;
} }
unsigned int sormcq(char *sql, char *out) {
unsigned int sormcq(char * sql, char * out){
// clean query // clean query
// converts %s %i parameters to ? // converts %s %i parameters to ?
unsigned int count = 0; unsigned int count = 0;
while(*sql){ while (*sql) {
if(*sql != '%' && *sql != '?') if (*sql != '%' && *sql != '?')
*out = *sql; *out = *sql;
else{ else {
count++; count++;
sql++; sql++;
*out = '?'; *out = '?';
@ -199,25 +186,25 @@ unsigned int sormcq(char * sql, char * out){
return count; return count;
} }
unsigned int sormpc(char * sql){ unsigned int sormpc(char *sql) {
int number = 0; int number = 0;
while(sormpt(sql,number) != NULL) while (sormpt(sql, number) != NULL)
number++; number++;
printf("FOUND: %d\n",number); printf("FOUND: %d\n", number);
return number; return number;
} }
char * sormcts(int column_type){ char *sormcts(int column_type) {
if(column_type == SQLITE_INTEGER) if (column_type == SQLITE_INTEGER)
return "integer"; return "integer";
else if(column_type == SQLITE_TEXT) else if (column_type == SQLITE_TEXT)
return "text"; return "text";
else if(column_type == SQLITE_FLOAT) else if (column_type == SQLITE_FLOAT)
return "float"; return "float";
else if(column_type == SQLITE_NULL) else if (column_type == SQLITE_NULL)
return "null"; return "null";
else if(column_type == SQLITE_BLOB) else if (column_type == SQLITE_BLOB)
return "blob"; return "blob";
return "?"; return "?";
} }
@ -225,25 +212,25 @@ char * sormcts(int column_type){
Execute 3.35s, Format: 36.77s Execute 3.35s, Format: 36.77s
Memory usage: 537 GB, 96.026 allocated, 96.024 freed, 2 in use. Memory usage: 537 GB, 96.026 allocated, 96.024 freed, 2 in use.
*/ */
char * sorm_csvc(int db, sqlite3_stmt * stmt){ char *sorm_csvc(int db, sqlite3_stmt *stmt) {
sormstr_t * str = sormstrn(512); sormstr_t *str = sormstrn(512);
unsigned int column_count = sqlite3_column_count(stmt); unsigned int column_count = sqlite3_column_count(stmt);
for(int i = 0; i < column_count; i++){ for (int i = 0; i < column_count; i++) {
const char * column_name = sqlite3_column_name(stmt,i); const char *column_name = sqlite3_column_name(stmt, i);
sormstra(str,column_name); sormstra(str, column_name);
sormstra(str,"("); sormstra(str, "(");
char column_type[1000] = ""; char column_type[1000] = "";
sprintf(column_type,"%s",sormcts(sqlite3_column_type(stmt,i))); sprintf(column_type, "%s", sormcts(sqlite3_column_type(stmt, i)));
sormstra(str,column_type); sormstra(str, column_type);
sormstra(str,")"); sormstra(str, ")");
// if(i != column_count - 1) // if(i != column_count - 1)
sormstra(str,";"); sormstra(str, ";");
} }
return sormstrc(str); return sormstrc(str);
} }
char * sorm_csvd(int sorm, sqlite3_stmt * stmt) { char *sorm_csvd(int sorm, sqlite3_stmt *stmt) {
sorm_t * db = sormg(sorm); sorm_t *db = sormg(sorm);
int rc = SQLITE_ROW; int rc = SQLITE_ROW;
int column_count = sqlite3_column_count(stmt); int column_count = sqlite3_column_count(stmt);
/* /*
@ -257,108 +244,109 @@ char * sorm_csvd(int sorm, sqlite3_stmt * stmt) {
xecute 3.42s, Format: 37.33s xecute 3.42s, Format: 37.33s
Memory usage: 6 MB, 96.052 (re)allocated, 96.024 unqiue freed, 2 in use. Memory usage: 6 MB, 96.052 (re)allocated, 96.024 unqiue freed, 2 in use.
*/ */
sormstr_t * str = sormstrn(512); sormstr_t *str = sormstrn(512);
while(rc == SQLITE_ROW){ while (rc == SQLITE_ROW) {
sorm_row_count++; sorm_row_count++;
for(int field_index = 0; field_index < column_count; field_index++){ for (int field_index = 0; field_index < column_count; field_index++) {
if(sqlite3_column_type(stmt,field_index) == SQLITE_INTEGER){ if (sqlite3_column_type(stmt, field_index) == SQLITE_INTEGER) {
char temp[1000] = ""; char temp[1000] = "";
sprintf(temp, "%lld",sqlite3_column_int64(stmt,field_index)); sprintf(temp, "%lld", sqlite3_column_int64(stmt, field_index));
sormstra(str,temp); sormstra(str, temp);
}else if(sqlite3_column_type(stmt,field_index) == SQLITE_FLOAT){ } else if (sqlite3_column_type(stmt, field_index) == SQLITE_FLOAT) {
char temp[1000] = ""; char temp[1000] = "";
sprintf(temp, "%f",sqlite3_column_double(stmt,field_index)); sprintf(temp, "%f", sqlite3_column_double(stmt, field_index));
sormstra(str,temp); sormstra(str, temp);
} else if(sqlite3_column_type(stmt,field_index) == SQLITE3_TEXT){ } else if (sqlite3_column_type(stmt, field_index) == SQLITE3_TEXT) {
const char * temp = sqlite3_column_text(stmt,field_index); const char *temp = sqlite3_column_text(stmt, field_index);
sormstra(str,temp); sormstra(str, temp);
} else { } else {
// exit(1); // exit(1);
}
// if(field_index != column_count - 1)
sormstra(str,";");
} }
sormstra(str,"\n"); // if(field_index != column_count - 1)
rc = sqlite3_step(stmt); sormstra(str, ";");
} }
char * text = sormstrc(str); sormstra(str, "\n");
if(*text) rc = sqlite3_step(stmt);
if(text[strlen(text)-1] == '\n') }
text[strlen(text)-1] = 0; char *text = sormstrc(str);
return strdup(text); if (*text)
if (text[strlen(text) - 1] == '\n')
text[strlen(text) - 1] = 0;
return strdup(text);
} }
char * sorm_csv(int sorm,sqlite3_stmt * stmt){ char *sorm_csv(int sorm, sqlite3_stmt *stmt) {
sorm_t * db = sormg(sorm); sorm_t *db = sormg(sorm);
sorm_row_count = 0; sorm_row_count = 0;
char * column_names = sorm_csvc(sorm,stmt); char *column_names = sorm_csvc(sorm, stmt);
char * data = sorm_csvd(sorm,stmt); char *data = sorm_csvd(sorm, stmt);
char * result = (char *)malloc(strlen(column_names) + strlen(data) + 2); char *result = (char *)malloc(strlen(column_names) + strlen(data) + 2);
result[0] = 0; result[0] = 0;
strcat(result,column_names); strcat(result, column_names);
if(*column_names) if (*column_names)
strcat(result,"\n"); strcat(result, "\n");
free(column_names); free(column_names);
strcat(result,data); strcat(result, data);
free(data); free(data);
return result; return result;
} }
sqlite3_stmt * sormb(sorm_t* db, char * sql, ...){ sqlite3_stmt *sormb(sorm_t *db, char *sql, ...) {
// Bind parameters to statement and return amount of parameters // Bind parameters to statement and return amount of parameters
int rc = 0; int rc = 0;
sqlite3_stmt * stmt; sqlite3_stmt *stmt;
va_list args; va_list args;
va_start(args,sql); va_start(args, sql);
unsigned int number = 0; unsigned int number = 0;
char * clean_query = (char *)malloc(strlen(sql) + 1); char *clean_query = (char *)malloc(strlen(sql) + 1);
unsigned int parameter_count = sormcq(sql,clean_query); unsigned int parameter_count = sormcq(sql, clean_query);
free(clean_query); free(clean_query);
return stmt; return stmt;
} }
char * sormm(sorm_t * db){ char *sormm(sorm_t *db) {
/* sormmemory */ /* sormmemory */
return rmalloc_stats(); return rmalloc_stats();
} }
sorm_ptr sormq(int sorm, char * sql, ...){ sorm_ptr sormq(int sorm, char *sql, ...) {
sorm_t * db = sormg(sorm); sorm_t *db = sormg(sorm);
if(db->csv){ if (db->csv) {
//free(db->csv); // free(db->csv);
//db->csv = NULL; // db->csv = NULL;
} }
_sorm_query_start = nsecs(); _sorm_query_start = nsecs();
db->time_query_start = nsecs(); db->time_query_start = nsecs();
va_list args; va_list args;
va_start (args,sql); va_start(args, sql);
sqlite3_stmt * stmt; sqlite3_stmt *stmt;
sorm_ptr result = NULL; sorm_ptr result = NULL;
char * clean_query = malloc(strlen(sql) + 1); char *clean_query = malloc(strlen(sql) + 1);
unsigned int parameter_count = sormcq(sql,clean_query); unsigned int parameter_count = sormcq(sql, clean_query);
int rc = sqlite3_prepare_v2(db->conn, clean_query, -1, &stmt, 0); int rc = sqlite3_prepare_v2(db->conn, clean_query, -1, &stmt, 0);
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
fprintf(stderr, "%s\n", sqlite3_errmsg(db->conn)); fprintf(stderr, "%s\n", sqlite3_errmsg(db->conn));
} }
free(clean_query); free(clean_query);
int number = 0; int number = 0;
for(int i = 0; i < parameter_count; i++){ for (int i = 0; i < parameter_count; i++) {
number++; number++;
char * column_type = sormpt(sql,number); char *column_type = sormpt(sql, number);
int arg_index = number - 1; int arg_index = number - 1;
if(!strcmp(column_type, "int") || !strcmp(column_type, "integer") || !strcmp(column_type, "number")) { if (!strcmp(column_type, "int") || !strcmp(column_type, "integer") || !strcmp(column_type, "number")) {
rc = sqlite3_bind_int(stmt, number, va_arg(args,int)); rc = sqlite3_bind_int(stmt, number, va_arg(args, int));
}else if(!strcmp(column_type, "int64")){ } else if (!strcmp(column_type, "int64")) {
rc = sqlite3_bind_int64(stmt, number,va_arg(args,__uint64_t)); rc = sqlite3_bind_int64(stmt, number, va_arg(args, __uint64_t));
}else if(!strcmp(column_type, "double") || !strcmp(column_type, "dec") || !strcmp(column_type, "decimal") || !strcmp(column_type, "float")){ } else if (!strcmp(column_type, "double") || !strcmp(column_type, "dec") || !strcmp(column_type, "decimal") ||
rc = sqlite3_bind_double(stmt, number,va_arg(args,double)); !strcmp(column_type, "float")) {
}else if(!strcmp(column_type, "blob")){ rc = sqlite3_bind_double(stmt, number, va_arg(args, double));
size_t size = (size_t)va_arg(args,size_t); } else if (!strcmp(column_type, "blob")) {
unsigned char * data = va_arg(args,unsigned char *); size_t size = (size_t)va_arg(args, size_t);
unsigned char *data = va_arg(args, unsigned char *);
rc = sqlite3_bind_blob(stmt, number, data, size, SQLITE_STATIC); rc = sqlite3_bind_blob(stmt, number, data, size, SQLITE_STATIC);
}else if(!strcmp(column_type,"text") || !strcmp(column_type,"str") || !strcmp(column_type,"string")) { } else if (!strcmp(column_type, "text") || !strcmp(column_type, "str") || !strcmp(column_type, "string")) {
unsigned char * data = va_arg(args, unsigned char *); unsigned char *data = va_arg(args, unsigned char *);
rc = sqlite3_bind_text(stmt, number, data, -1, SQLITE_STATIC); rc = sqlite3_bind_text(stmt, number, data, -1, SQLITE_STATIC);
} }
if (rc != SQLITE_OK) { if (rc != SQLITE_OK) {
@ -366,27 +354,26 @@ sorm_ptr sormq(int sorm, char * sql, ...){
result = NULL; result = NULL;
} }
} }
rc = sqlite3_step(stmt); rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE && rc != SQLITE_ROW) { if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db->conn)); fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db->conn));
}else if(rc == SQLITE_DONE){ } else if (rc == SQLITE_DONE) {
if(!sqlite3_strnicmp(sql,"SELECT",6)){ if (!sqlite3_strnicmp(sql, "SELECT", 6)) {
result = 0; result = 0;
}else { } else {
result = (sorm_ptr)sqlite3_last_insert_rowid(db->conn); result = (sorm_ptr)sqlite3_last_insert_rowid(db->conn);
} }
} else if (rc == SQLITE_ROW) { } else if (rc == SQLITE_ROW) {
result = sorm_csv(sorm,stmt); result = sorm_csv(sorm, stmt);
} }
else{ else {
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db->conn)); fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db->conn));
} }
if(sorm_last_query){ if (sorm_last_query) {
free(sorm_last_query); free(sorm_last_query);
} }
if(sorm_last_query){ if (sorm_last_query) {
free(sorm_last_query_expanded); free(sorm_last_query_expanded);
} }
sorm_last_query = strdup(sqlite3_sql(stmt)); sorm_last_query = strdup(sqlite3_sql(stmt));
@ -400,103 +387,99 @@ sorm_ptr sormq(int sorm, char * sql, ...){
return result; return result;
} }
char sormlc(char *sql) {
char sormlc(char * sql){
// returns last char // returns last char
char last_char = 0; char last_char = 0;
while(*sql){ while (*sql) {
if(*sql == ' ' || *sql == '\t' || *sql == '\n') if (*sql == ' ' || *sql == '\t' || *sql == '\n')
continue ; continue;
//printf("%c\n",*sql); // printf("%c\n",*sql);
last_char = *sql; last_char = *sql;
sql++; sql++;
} }
return last_char; return last_char;
} }
int sormlv(char * csv){ int sormlv(char *csv) {
size_t longest = 0; size_t longest = 0;
while(*csv){ while (*csv) {
char * found = strstr(csv,";"); char *found = strstr(csv, ";");
if(found){ if (found) {
if(found - csv > longest) if (found - csv > longest)
longest = found-csv; longest = found - csv;
csv = csv + (found - csv) + 1; csv = csv + (found - csv) + 1;
}else{ } else {
break; break;
} }
} }
return longest; return longest;
} }
sorm_query_t sormqt(char * sql){ sorm_query_t sormqt(char *sql) {
while(*sql && isspace(*sql)) while (*sql && isspace(*sql))
sql++; sql++;
if(!sqlite3_strnicmp(sql,"select",6)) if (!sqlite3_strnicmp(sql, "select", 6))
return SORM_SELECT; return SORM_SELECT;
else if(!sqlite3_strnicmp(sql, "update",6)) else if (!sqlite3_strnicmp(sql, "update", 6))
return SORM_UPDATE; return SORM_UPDATE;
else if(!sqlite3_strnicmp(sql, "delete",6)) else if (!sqlite3_strnicmp(sql, "delete", 6))
return SORM_DELETE; return SORM_DELETE;
else if(!sqlite3_strnicmp(sql, "create",6)){ else if (!sqlite3_strnicmp(sql, "create", 6)) {
return SORM_CREATE; return SORM_CREATE;
}else { } else {
return SORM_UNKNOWN; return SORM_UNKNOWN;
} }
} }
char * sormrq(FILE * f){ char *sormrq(FILE *f) {
static char buffer[4097]; static char buffer[4097];
buffer[0] = 0; buffer[0] = 0;
char * bufferp = buffer; char *bufferp = buffer;
char c; char c;
bool in_string = false; bool in_string = false;
while((c = fgetc(f)) != EOF && strlen(buffer) != sizeof(buffer) -2){ while ((c = fgetc(f)) != EOF && strlen(buffer) != sizeof(buffer) - 2) {
*bufferp = c; *bufferp = c;
if(c == '"') if (c == '"') {
{
in_string = !in_string; in_string = !in_string;
} }
if(!in_string && c == ';'){ if (!in_string && c == ';') {
break; break;
} }
bufferp++; bufferp++;
*bufferp = 0; *bufferp = 0;
} }
return strdup(buffer); return strdup(buffer);
} }
char * sormcsvn(char * csv){ char *sormcsvn(char *csv) {
if(!csv || !*csv) if (!csv || !*csv)
return NULL; return NULL;
char * pos = strstr(csv,";"); char *pos = strstr(csv, ";");
char * pos2 = strstr(csv,"\n"); char *pos2 = strstr(csv, "\n");
if(pos2){ if (pos2) {
if(pos > pos2){ if (pos > pos2) {
pos = pos2; pos = pos2;
} }
//pos = pos > pos2 ? pos2 : pos; // pos = pos > pos2 ? pos2 : pos;
} }
if(!pos || !*pos) if (!pos || !*pos)
return strdup(csv); return strdup(csv);
int length = pos - csv; int length = pos - csv;
char * result = malloc(length + 2); char *result = malloc(length + 2);
strncpy(result,csv,length); strncpy(result, csv, length);
result[length] = 0; result[length] = 0;
//csv += strlen(result); // csv += strlen(result);
return result; return result;
} }
char * sormfmt(char * csv){ char *sormfmt(char *csv) {
_sorm_result_format_start = nsecs(); _sorm_result_format_start = nsecs();
size_t longest = sormlv(csv); size_t longest = sormlv(csv);
char * field; char *field;
/* /*
sormstrn(1) sormstrn(1)
Execute 3.77s, Format: 36.40s Execute 3.77s, Format: 36.40s
@ -511,15 +494,15 @@ char * sormfmt(char * csv){
Execute 3.11s, Format: 36.45s Execute 3.11s, Format: 36.45s
Memory usage: 6 MB, 96.048 (re)allocated, 96.024 unqiue freed, 2 in use. Memory usage: 6 MB, 96.048 (re)allocated, 96.024 unqiue freed, 2 in use.
*/ */
sormstr_t * str = sormstrn(longest + 2); sormstr_t *str = sormstrn(longest + 2);
while(*csv && (field = sormcsvn(csv))){ while (*csv && (field = sormcsvn(csv))) {
sormstra(str,field); sormstra(str, field);
for(int i = 0; i < longest - strlen(field); i++) for (int i = 0; i < longest - strlen(field); i++)
sormstra(str," "); sormstra(str, " ");
csv += strlen(field); csv += strlen(field);
while( *csv == ';' || *csv == '\n'){ while (*csv == ';' || *csv == '\n') {
if(*csv == '\n') if (*csv == '\n')
sormstra(str, "\n"); sormstra(str, "\n");
csv++; csv++;
} }
@ -530,47 +513,41 @@ char * sormfmt(char * csv){
return sormstrc(str); return sormstrc(str);
} }
void apply_colors(char * csv){ void apply_colors(char *csv) {
char * end; char *end;
bool even = false; bool even = false;
while(*csv){ while (*csv) {
printf("%s\n",csv); printf("%s\n", csv);
end = strstr(csv,"\n"); end = strstr(csv, "\n");
char * line; char *line;
if(end) if (end) {
{ line = (char *)malloc(end - csv + 1024);
line = (char *)malloc(end -csv + 1024); strncpy(line, csv, end - csv);
strncpy(line,csv,end-csv); } else {
}else{
line = (char *)malloc(strlen(csv) + 1024); line = (char *)malloc(strlen(csv) + 1024);
strcpy(line, csv); strcpy(line, csv);
} }
if(even){ if (even) {
printf("%s","\033[37m"); printf("%s", "\033[37m");
} }
printf("%s\n",line); printf("%s\n", line);
free(line); free(line);
if(even){ if (even) {
printf("%s","\033[0m"); printf("%s", "\033[0m");
} }
even = !even; even = !even;
csv += end-csv; csv += end - csv;
if(*csv && *(csv + 1)) if (*csv && *(csv + 1))
csv++; csv++;
} }
} }
void sormfmtd(char * csv){ void sormfmtd(char *csv) {
char * formatted = sormfmt(csv); char *formatted = sormfmt(csv);
printf("%s\n",formatted); printf("%s\n", formatted);
free(formatted); free(formatted);
} }
#endif #endif

95
sorm.py
View File

@ -5,19 +5,20 @@ import io
import tempfile import tempfile
import time import time
class DictReader: class DictReader:
def get_column_types(self): def get_column_types(self):
types = [] types = []
for column in self.columns: for column in self.columns:
name = column.split("(")[0] name = column.split("(")[0]
type = column.split("(")[1] type = column.split("(")[1]
type = type.split(")")[0] type = type.split(")")[0]
if type == "integer": if type == "integer":
types.append(int) types.append(int)
if type == "text": if type == "text":
types.append(str) types.append(str)
return types return types
def get_column_names(self): def get_column_names(self):
names = [] names = []
@ -25,12 +26,13 @@ class DictReader:
name = column.split("(")[0] name = column.split("(")[0]
names.append(name) names.append(name)
return names return names
def __init__(self, data): def __init__(self, data):
self.result = 0 self.result = 0
if type(data) == int: if type(data) == int:
self.data = '' self.data = ""
else: else:
self.data = data.decode(); self.data = data.decode()
self.rows = [row.split(";")[:-1] for row in self.data.split("\n")] self.rows = [row.split(";")[:-1] for row in self.data.split("\n")]
self.columns = self.rows[0] self.columns = self.rows[0]
@ -41,47 +43,42 @@ class DictReader:
self.result = data self.result = data
self.column_types = self.get_column_types() self.column_types = self.get_column_types()
for row in self.rows: for row in self.rows:
for index,field in enumerate(row): for index, field in enumerate(row):
row[index] = self.column_types[index](field) row[index] = self.column_types[index](field)
self.column_names = self.get_column_names() self.column_names = self.get_column_names()
def __iter__(self): def __iter__(self):
return self.rows.__iter__() return self.rows.__iter__()
libc = ctypes.CDLL("libc.so.6")
libc = ctypes.CDLL('libc.so.6');
class Sorm: class Sorm:
def __init__(self): def __init__(self):
self.lib = ctypes.CDLL('./sorm.so') self.lib = ctypes.CDLL("./sorm.so")
self.sormq = self.lib.sormq self.sormq = self.lib.sormq
self.sormq.argtypes = [ctypes.c_int, ctypes.c_char_p]; self.sormq.argtypes = [ctypes.c_int, ctypes.c_char_p]
self.sormq.restype = ctypes.c_char_p self.sormq.restype = ctypes.c_char_p
self.sormc = self.lib.sormc self.sormc = self.lib.sormc
self.sormc.argtypes = [ctypes.c_char_p]; self.sormc.argtypes = [ctypes.c_char_p]
self.sormc.restype = ctypes.c_int; self.sormc.restype = ctypes.c_int
self.sormd = self.lib.sormd self.sormd = self.lib.sormd
self.sormd.argtypes = [ctypes.c_int]; self.sormd.argtypes = [ctypes.c_int]
self.sormd.restype = None self.sormd.restype = None
self.sormm = self.lib.sormm self.sormm = self.lib.sormm
self.sormm.argtypes = [ctypes.c_int]; self.sormm.argtypes = [ctypes.c_int]
self.sormm.restype = ctypes.c_char_p self.sormm.restype = ctypes.c_char_p
class SormDb(Sorm): class SormDb(Sorm):
def __init__(self,path): def __init__(self, path):
super().__init__( super().__init__()
)
self.path = path self.path = path
self.conn = None self.conn = None
@ -94,10 +91,10 @@ class SormDb(Sorm):
self.c() self.c()
return self return self
def __exit__(self,*args, **kwargs): def __exit__(self, *args, **kwargs):
self.d() self.d()
def q(self, sql,*args) -> DictReader: def q(self, sql, *args) -> DictReader:
ctypes_list = [] ctypes_list = []
for arg in args: for arg in args:
if type(arg) == int: if type(arg) == int:
@ -109,7 +106,10 @@ class SormDb(Sorm):
self.sormq.restype = ctypes.c_int self.sormq.restype = ctypes.c_int
else: else:
self.sormq.restype = ctypes.c_char_p self.sormq.restype = ctypes.c_char_p
params = tuple([self.conn, sql.encode()] + list(arg.encode() if type(arg) == str else arg for arg in args)) params = tuple(
[self.conn, sql.encode()]
+ list(arg.encode() if type(arg) == str else arg for arg in args)
)
result = DictReader(self.sormq(*params)) result = DictReader(self.sormq(*params))
self.m = self.sormm(self.conn).decode() self.m = self.sormm(self.conn).decode()
return result return result
@ -120,43 +120,42 @@ class SormDb(Sorm):
self.sormd(self.conn) self.sormd(self.conn)
self.conn = None self.conn = None
# Load the shared library # Load the shared library
lib = ctypes.CDLL('./sorm.so') lib = ctypes.CDLL("./sorm.so")
free = libc.free free = libc.free
free.argtypes = [ctypes.c_void_p] free.argtypes = [ctypes.c_void_p]
free.restype = None free.restype = None
rsomm = lib.sormm rsomm = lib.sormm
rsomm.argtypes = [ctypes.c_int]; rsomm.argtypes = [ctypes.c_int]
rsomm.restype = ctypes.c_char_p; rsomm.restype = ctypes.c_char_p
disconnect = lib.sormd disconnect = lib.sormd
disconnect.argtypes = [ctypes.c_int]; disconnect.argtypes = [ctypes.c_int]
start = time.time() start = time.time()
for x in range(1): for x in range(1):
with SormDb("db.sqlite3") as db: with SormDb("db.sqlite3") as db:
for x in range(1): for x in range(1):
#db.q("BEGIN TRANSACTION") # db.q("BEGIN TRANSACTION")
#for x in range(100000): # for x in range(100000):
# db.q("INSERT INTO pony (name,age) VALUES (?s,?d);","Python Pony",1337) # db.q("INSERT INTO pony (name,age) VALUES (?s,?d);","Python Pony",1337)
#db.q("COMMIT") # db.q("COMMIT")
result = db.q("SELECT * FROM pony WHERE id > ?d AND name like ?s ORDER BY id",1337, "%hon Pon%"); result = db.q(
#for row in result: "SELECT * FROM pony WHERE id > ?d AND name like ?s ORDER BY id",
1337,
"%hon Pon%",
)
# for row in result:
# print(row) # print(row)
print(result.column_names) print(result.column_names)
print(len(result.rows),"records") print(len(result.rows), "records")
print(db.m); print(db.m)
end = time.time() end = time.time()
duration = end - start duration = end - start
print("Duration: {}s".format(duration)) print("Duration: {}s".format(duration))

28
str.h
View File

@ -1,19 +1,19 @@
#ifndef SORM_STR_H #ifndef SORM_STR_H
#define SORM_STR_H #define SORM_STR_H
#include <rlib.h> #include <rlib.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
typedef struct sormstr_t { typedef struct sormstr_t {
char * content; char *content;
size_t length; size_t length;
size_t buffer_size; size_t buffer_size;
size_t size; size_t size;
} sormstr_t; } sormstr_t;
sormstr_t * sormstrn(size_t buffer_size){ sormstr_t *sormstrn(size_t buffer_size) {
sormstr_t * result = (sormstr_t *)malloc(sizeof(sormstr_t)); sormstr_t *result = (sormstr_t *)malloc(sizeof(sormstr_t));
result->length = 0; result->length = 0;
result->size = buffer_size; result->size = buffer_size;
result->buffer_size = buffer_size; result->buffer_size = buffer_size;
@ -21,27 +21,27 @@ sormstr_t * sormstrn(size_t buffer_size){
result->content[0] = 0; result->content[0] = 0;
return result; return result;
} }
void sormstra(sormstr_t * str, const char * to_append){ void sormstra(sormstr_t *str, const char *to_append) {
size_t required_new_length = str->length + strlen(to_append); size_t required_new_length = str->length + strlen(to_append);
str->length += strlen(to_append); str->length += strlen(to_append);
if(required_new_length > str->size){ if (required_new_length > str->size) {
str->size += required_new_length + str->buffer_size; str->size += required_new_length + str->buffer_size;
str->content = realloc(str->content,str->size + 1); str->content = realloc(str->content, str->size + 1);
}else{ } else {
// printf("NO NDEED\n"); // printf("NO NDEED\n");
} }
strcat(str->content,to_append); strcat(str->content, to_append);
str->content[str->length] = 0; str->content[str->length] = 0;
} }
void sormstrd(sormstr_t * str){ void sormstrd(sormstr_t *str) {
if(str->content){ if (str->content) {
free(str->content); free(str->content);
} }
free(str); free(str);
} }
char * sormstrc(sormstr_t * str){ char *sormstrc(sormstr_t *str) {
// sorm str convert // sorm str convert
char * content = str->content; char *content = str->content;
str->content = NULL; str->content = NULL;
sormstrd(str); sormstrd(str);
return content; return content;