Skip to content

Commit

Permalink
Up to 1.4.0
Browse files Browse the repository at this point in the history
+ Executing queries in parallel on different tabs (multi-threading mode)
+ Edit data dialog: support exactly match "=" and regexp "/" column filters
+ ora-extension: base64_encode, base64_decode
* ora-extension: support negative index in strpart
* Recompile sqlite3.dll with -O3 and -DSQLITE_THREADSAFE=2
* Up SQLite to 3.34.1
* Fix minor bugs
  • Loading branch information
little-brother committed Jan 30, 2021
1 parent fc83ba3 commit d454a34
Show file tree
Hide file tree
Showing 16 changed files with 1,087 additions and 564 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Sqlite-gui is a lightweight Windows GUI for [SQLite](https://www.sqlite.org/index.html) powered by C++, WinAPI and [Code::Blocks 17](http://www.codeblocks.org/). <br>
sqlite-gui is a lightweight Windows GUI for [SQLite](https://www.sqlite.org/index.html) powered by C++, WinAPI and [Code::Blocks 17](http://www.codeblocks.org/). <br>

|[**Download the latest version**](https://github.com/little-brother/sqlite-gui/releases/latest)|
|-------------------------------------------------------------------------------------------|
Expand Down Expand Up @@ -29,5 +29,5 @@ Sqlite-gui is a lightweight Windows GUI for [SQLite](https://www.sqlite.org/inde
* NULL is displayed as an empty string and an empty string is set to NULL when data is edit
* The application is a single threaded. Therefore, the interface freeze on long operations

If you like the project, press the like-button [here](https://alternativeto.net/software/sqlite-gui/) or write something in a [Reddit](https://www.reddit.com/r/sqlite/comments/iaao8x/a_new_lightweight_sqlite_tool_for_windows/) topic to support it.<br>
If you like the project, press the like-button [here](https://alternativeto.net/software/sqlite-gui/about) or write something in a [Reddit](https://www.reddit.com/r/sqlite/comments/iaao8x/a_new_lightweight_sqlite_tool_for_windows/) topic to support it.<br>
If you have any problems, comments or suggestions, check [Wiki](https://github.com/little-brother/sqlite-gui/wiki) or just let me know <a href="mailto:[email protected]?subject=sqlite-gui">[email protected]</a>.
215 changes: 211 additions & 4 deletions extensions/ora.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@
md5(str)
Calculate md5 checksum
base64_encode (str)
Encodes the given string with base64.
select base64_encode('foobar') --> Zm9vYmFy
base64_decode (str)
Decodes a base64 encoded string.
select base64_encode('Zm9vYmFy') --> foobar
strpart(str, delimiter, partno)
Returns substring for a delimiter and a part number
select strpart('ab-cd-ef', '-', 2) --> 'cd'
Expand Down Expand Up @@ -270,16 +279,212 @@ static void md5 (sqlite3_context *ctx, int argc, sqlite3_value **argv) {
sqlite3_result_text(ctx, buf, -1, SQLITE_TRANSIENT);
}

// https://github.com/zhicheng/base64
#define BASE64_ENCODE_OUT_SIZE(s) ((unsigned int)((((s) + 2) / 3) * 4 + 1))
#define BASE64_DECODE_OUT_SIZE(s) ((unsigned int)(((s) / 4) * 3))

#define BASE64_PAD '='
#define BASE64DE_FIRST '+'
#define BASE64DE_LAST 'z'

/* BASE 64 encode table */
static const char base64en[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
};

/* ASCII order for BASE 64 decode, 255 in unused character */
static const unsigned char base64de[] = {
/* nul, soh, stx, etx, eot, enq, ack, bel, */
255, 255, 255, 255, 255, 255, 255, 255,

/* bs, ht, nl, vt, np, cr, so, si, */
255, 255, 255, 255, 255, 255, 255, 255,

/* dle, dc1, dc2, dc3, dc4, nak, syn, etb, */
255, 255, 255, 255, 255, 255, 255, 255,

/* can, em, sub, esc, fs, gs, rs, us, */
255, 255, 255, 255, 255, 255, 255, 255,

/* sp, '!', '"', '#', '$', '%', '&', ''', */
255, 255, 255, 255, 255, 255, 255, 255,

/* '(', ')', '*', '+', ',', '-', '.', '/', */
255, 255, 255, 62, 255, 255, 255, 63,

/* '0', '1', '2', '3', '4', '5', '6', '7', */
52, 53, 54, 55, 56, 57, 58, 59,

/* '8', '9', ':', ';', '<', '=', '>', '?', */
60, 61, 255, 255, 255, 255, 255, 255,

/* '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', */
255, 0, 1, 2, 3, 4, 5, 6,

/* 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', */
7, 8, 9, 10, 11, 12, 13, 14,

/* 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', */
15, 16, 17, 18, 19, 20, 21, 22,

/* 'X', 'Y', 'Z', '[', '\', ']', '^', '_', */
23, 24, 25, 255, 255, 255, 255, 255,

/* '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', */
255, 26, 27, 28, 29, 30, 31, 32,

/* 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', */
33, 34, 35, 36, 37, 38, 39, 40,

/* 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', */
41, 42, 43, 44, 45, 46, 47, 48,

/* 'x', 'y', 'z', '{', '|', '}', '~', del, */
49, 50, 51, 255, 255, 255, 255, 255
};

static unsigned int _base64_encode(const unsigned char *in, unsigned int inlen, char *out) {
int s;
unsigned int i;
unsigned int j;
unsigned char c;
unsigned char l;

s = 0;
l = 0;
for (i = j = 0; i < inlen; i++) {
c = in[i];

switch (s) {
case 0:
s = 1;
out[j++] = base64en[(c >> 2) & 0x3F];
break;
case 1:
s = 2;
out[j++] = base64en[((l & 0x3) << 4) | ((c >> 4) & 0xF)];
break;
case 2:
s = 0;
out[j++] = base64en[((l & 0xF) << 2) | ((c >> 6) & 0x3)];
out[j++] = base64en[c & 0x3F];
break;
}
l = c;
}

switch (s) {
case 1:
out[j++] = base64en[(l & 0x3) << 4];
out[j++] = BASE64_PAD;
out[j++] = BASE64_PAD;
break;
case 2:
out[j++] = base64en[(l & 0xF) << 2];
out[j++] = BASE64_PAD;
break;
}

out[j] = 0;

return j;
}

static unsigned int _base64_decode(const char *in, unsigned int inlen, unsigned char *out) {
unsigned int i;
unsigned int j;
unsigned char c;

if (inlen & 0x3) {
return 0;
}

for (i = j = 0; i < inlen; i++) {
if (in[i] == BASE64_PAD) {
break;
}
if (in[i] < BASE64DE_FIRST || in[i] > BASE64DE_LAST) {
return 0;
}

c = base64de[(unsigned char)in[i]];
if (c == 255) {
return 0;
}

switch (i & 0x3) {
case 0:
out[j] = (c << 2) & 0xFF;
break;
case 1:
out[j++] |= (c >> 4) & 0x3;
out[j] = (c & 0xF) << 4;
break;
case 2:
out[j++] |= (c >> 2) & 0xF;
out[j] = (c & 0x3) << 6;
break;
case 3:
out[j++] |= c;
break;
}
}

return j;
}

static void base64_encode (sqlite3_context *ctx, int argc, sqlite3_value **argv) {
const char* in = sqlite3_value_text(argv[0]);
int len = strlen(in);
unsigned char* out = malloc(BASE64_ENCODE_OUT_SIZE(len));

_base64_encode(in, len, out);

sqlite3_result_text(ctx, out, -1, SQLITE_TRANSIENT);
free(out);
}

static void base64_decode (sqlite3_context *ctx, int argc, sqlite3_value **argv) {
const char* in = sqlite3_value_text(argv[0]);
int len = strlen(in);
unsigned char* out = malloc(BASE64_DECODE_OUT_SIZE(len));

_base64_decode(in, len, out);

sqlite3_result_text(ctx, out, -1, SQLITE_TRANSIENT);
free(out);
}

static void strpart (sqlite3_context *ctx, int argc, sqlite3_value **argv) {
const char* instr = sqlite3_value_text(argv[0]);
const char* delim = sqlite3_value_text(argv[1]);
int no = sqlite3_value_int(argv[2]);

if (no < 0) {
char str[strlen(instr) + 1];
strcpy(str, instr);

char *ptr = strtok(str, delim);
int cnt = 0;
while (ptr != NULL) {
ptr = strtok(NULL, delim);
cnt++;
}
no = cnt + no + 1;
}

if (no < 1) {
if (no <= 0) {
sqlite3_result_null(ctx);
return;
}

}
char str[strlen(instr) + 1];
strcpy(str, instr);

Expand All @@ -304,6 +509,8 @@ __declspec(dllexport) int sqlite3_ora_init(sqlite3 *db, char **pzErrMsg, const s
SQLITE_OK == sqlite3_create_function(db, "decode", -1, SQLITE_UTF8, 0, decode, 0, 0) &&
SQLITE_OK == sqlite3_create_function(db, "crc32", 1, SQLITE_UTF8, 0, crc32, 0, 0) &&
SQLITE_OK == sqlite3_create_function(db, "md5", 1, SQLITE_UTF8, 0, md5, 0, 0) &&
SQLITE_OK == sqlite3_create_function(db, "strpart", 3, SQLITE_UTF8, 0, strpart, 0, 0) ?
SQLITE_OK == sqlite3_create_function(db, "base64_encode", 1, SQLITE_UTF8, 0, base64_encode, 0, 0) &&
SQLITE_OK == sqlite3_create_function(db, "base64_decode", 1, SQLITE_UTF8, 0, base64_decode, 0, 0) &&
SQLITE_OK == sqlite3_create_function(db, "strpart", 3, SQLITE_UTF8, 0, strpart, 0, 0) ?
SQLITE_OK : SQLITE_ERROR;
}
20 changes: 11 additions & 9 deletions include/sqlite3.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.34.0. By combining all the individual C code files into this
** version 3.34.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
Expand Down Expand Up @@ -1171,9 +1171,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3034000
#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b"
#define SQLITE_VERSION "3.34.1"
#define SQLITE_VERSION_NUMBER 3034001
#define SQLITE_SOURCE_ID "2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f"

/*
** CAPI3REF: Run-Time Library Version Numbers
Expand Down Expand Up @@ -4745,7 +4745,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
** If the Y parameter to sqlite3_free_filename(Y) is anything other
** than a NULL pointer or a pointer previously acquired from
** sqlite3_create_filename(), then bad things such as heap
** corruption or segfaults may occur. The value Y should be
** corruption or segfaults may occur. The value Y should not be
** used again after sqlite3_free_filename(Y) has been called. This means
** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
** then the corresponding [sqlite3_module.xClose() method should also be
Expand Down Expand Up @@ -135416,7 +135416,9 @@ static void explainSimpleCount(
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
if( pExpr->op!=TK_AND ){
Select *pS = pWalker->u.pSelect;
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy)
&& ExprAlwaysFalse(pExpr)==0
){
sqlite3 *db = pWalker->pParse->db;
Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1");
if( pNew ){
Expand Down Expand Up @@ -226819,7 +226821,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b", -1, SQLITE_TRANSIENT);
sqlite3_result_text(pCtx, "fts5: 2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f", -1, SQLITE_TRANSIENT);
}

/*
Expand Down Expand Up @@ -231745,9 +231747,9 @@ SQLITE_API int sqlite3_stmt_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */

/************** End of stmt.c ************************************************/
#if __LINE__!=231748
#if __LINE__!=231750
#undef SQLITE_SOURCE_ID
#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089falt2"
#define SQLITE_SOURCE_ID "2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ealt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
Expand Down
8 changes: 4 additions & 4 deletions include/sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.34.0"
#define SQLITE_VERSION_NUMBER 3034000
#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 a26b6597e3ae272231b96f9982c3bcc17ddec2f2b6eb4df06a224b91089fed5b"
#define SQLITE_VERSION "3.34.1"
#define SQLITE_VERSION_NUMBER 3034001
#define SQLITE_SOURCE_ID "2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f"

/*
** CAPI3REF: Run-Time Library Version Numbers
Expand Down Expand Up @@ -3697,7 +3697,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
** If the Y parameter to sqlite3_free_filename(Y) is anything other
** than a NULL pointer or a pointer previously acquired from
** sqlite3_create_filename(), then bad things such as heap
** corruption or segfaults may occur. The value Y should be
** corruption or segfaults may occur. The value Y should not be
** used again after sqlite3_free_filename(Y) has been called. This means
** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
** then the corresponding [sqlite3_module.xClose() method should also be
Expand Down
Binary file modified lib/libsqlite3.a
Binary file not shown.
3 changes: 2 additions & 1 deletion sqlite-gui.cbp
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@
<Add option="-std=c++11" />
</Compiler>
<Linker>
<Add option="-static-libstdc++" />
<Add option="-static-libgcc" />
<Add option="-static-libstdc++ -static-libgcc" />
<Add option="-static" />
<Add library="gdi32" />
<Add library="user32" />
<Add library="kernel32" />
Expand Down
Loading

0 comments on commit d454a34

Please sign in to comment.