Skip to content

Commit 4e218d7

Browse files
committed
Removed sqlite mode, removed ACK on chunk rowset
1 parent 5407903 commit 4e218d7

3 files changed

Lines changed: 123 additions & 56 deletions

File tree

C/cli/main.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#endif
2727

2828
#define CLI_HISTORY_FILENAME ".sqlitecloud_history.txt"
29-
#define CLI_VERSION "1.0"
29+
#define CLI_VERSION "1.1"
3030
#define CLI_BUILD_DATE __DATE__
3131

3232
#ifndef MAXPATH
@@ -126,7 +126,6 @@ static void do_print_usage (void) {
126126
printf(" -i activate insecure mode (non TLS connection)\n");
127127
printf(" -j disable certificate verification\n");
128128
printf(" -q activate quite mode (disable output print)\n");
129-
printf(" -x activate special sqlite mode\n");
130129
printf(" -z request zero-terminated strings in all replies\n");
131130
printf(" -w in case of -f file to execute, skip the line by line processing and send the whole file\n");
132131
}
@@ -492,7 +491,6 @@ int main(int argc, char * argv[]) {
492491
bool compression = false;
493492
bool insecure = false;
494493
bool noverifycert = false;
495-
bool sqlite = false;
496494
bool zerotext = false;
497495
bool linebyline = true;
498496

@@ -507,7 +505,6 @@ int main(int argc, char * argv[]) {
507505
case 'i': insecure = true; break;
508506
case 'j': noverifycert = true; break;
509507
case 'q': quiet = true; break;
510-
case 'x': sqlite = true; break;
511508
case 'z': zerotext = true; break;
512509
case 'w': linebyline = false; break;
513510
case 'd': database = optarg; break;
@@ -552,7 +549,6 @@ int main(int argc, char * argv[]) {
552549
if (client_certificate_key_path) config.tls_certificate_key = client_certificate_key_path;
553550
#endif
554551

555-
if (sqlite) config.sqlite_mode = true;
556552
if (zerotext) config.zero_text = true;
557553
if (compression) config.compression = true;
558554
if (database) config.database = database;
@@ -566,7 +562,7 @@ int main(int argc, char * argv[]) {
566562
printf("ERROR connecting to %s: %s (%d)\n", hostname, SQCloudErrorMsg(conn), SQCloudErrorCode(conn));
567563
return -1;
568564
} else {
569-
printf("Connection to %s OK...\n\n", hostname);
565+
printf("Connection to %s:%d OK...\n\n", hostname, port);
570566
}
571567

572568
// load history file

C/sqcloud.c

Lines changed: 108 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,19 @@ struct SQCloudResult {
170170
uint32_t nheader; // number of character in the first part of the header (which is usually skipped)
171171

172172
// used in TYPE_ROWSET only
173-
uint32_t flags; // rowset flags
173+
uint32_t version; // rowset version
174174
uint32_t nrows; // number of rows
175175
uint32_t ncols; // number of columns
176176
uint32_t ndata; // number of items stores in data
177177
char **data; // data contained in the rowset
178178
char **name; // column names
179-
char **decltype; // column declared types (sqlite mode only)
180-
char **dbname; // column database names (sqlite mode only)
181-
char **tblname; // column table names (sqlite mode only)
182-
char **origname; // column origin names (sqlite mode only)
179+
char **decltype; // column declared types
180+
char **dbname; // column database names
181+
char **tblname; // column table names
182+
char **origname; // column origin names
183+
int *notnull; // column is not null
184+
int *prikey; // column is primary key
185+
int *autoinc; // column is auto increment
183186
uint32_t *clen; // max len for each column (used to display result)
184187
uint32_t maxlen; // max len for each row/column
185188

@@ -801,12 +804,20 @@ static char *internal_get_rowset_header (SQCloudResult *result, char **header, u
801804
return internal_parse_value(header[col], len, NULL);
802805
}
803806

804-
static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer, uint32_t *pblen, uint32_t ncols, uint32_t flags) {
805-
if (BITCHECK(flags, SQCLOUD_ROWSET_FLAG_DATAONLY)) return true;
807+
static int internal_get_rowset_header_int (SQCloudResult *result, int *header, uint32_t col) {
808+
if (!result || result->tag != RESULT_ROWSET) return -1;
809+
if (col >= result->ncols) return -1;
810+
if (header == NULL) return -1;
811+
return header[col];
812+
}
813+
814+
static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer, uint32_t *pblen, uint32_t ncols, uint32_t version) {
815+
if (version == ROWSET_TYPE_DATA_ONLY) return true;
806816

807817
char *buffer = *pbuffer;
808818
uint32_t blen = *pblen;
809819

820+
/*
810821
if (BITCHECK(flags, SQCLOUD_ROWSET_FLAG_METAVM)) {
811822
uint32_t cstart1 = 0, cstart2 = 0, cstart3 = 0, cstart4 = 0, cstart5 = 0;
812823
@@ -838,8 +849,9 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
838849
rowset->n4 = n4;
839850
rowset->n5 = n5;
840851
}
852+
*/
841853

842-
// header is guarantee to contains column names (1st)
854+
// header is guarantee to contain column names
843855
for (uint32_t i=0; i<ncols; ++i) {
844856
uint32_t cstart = 0;
845857
uint32_t len = internal_parse_number(&buffer[1], blen, &cstart);
@@ -850,7 +862,8 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
850862
if (rowset->maxlen < len) rowset->maxlen = len;
851863
}
852864

853-
if (BITCHECK(flags, SQCLOUD_ROWSET_FLAG_METACOLS)) {
865+
// check if additional metadata is contained
866+
if (version == ROWSET_TYPE_METADATA_v1) {
854867
rowset->decltype = (char **) mem_alloc(ncols * sizeof(char *));
855868
if (!rowset->decltype) return false;
856869
rowset->dbname = (char **) mem_alloc(ncols * sizeof(char *));
@@ -859,8 +872,14 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
859872
if (!rowset->tblname) return false;
860873
rowset->origname = (char **) mem_alloc(ncols * sizeof(char *));
861874
if (!rowset->origname) return false;
862-
863-
// in sqlite mode header contains column declared types (2nd)
875+
rowset->notnull = (int *) mem_alloc(ncols * sizeof(int));
876+
if (!rowset->notnull) return false;
877+
rowset->prikey = (int *) mem_alloc(ncols * sizeof(int));
878+
if (!rowset->prikey) return false;
879+
rowset->autoinc = (int *) mem_alloc(ncols * sizeof(int));
880+
if (!rowset->autoinc) return false;
881+
882+
// column declared types
864883
for (uint32_t i=0; i<ncols; ++i) {
865884
uint32_t cstart = 0;
866885
uint32_t len = internal_parse_number(&buffer[1], blen, &cstart);
@@ -869,7 +888,7 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
869888
blen -= cstart + len + 1;
870889
}
871890

872-
// in sqlite mode header contains column database names (3rd)
891+
// column database names
873892
for (uint32_t i=0; i<ncols; ++i) {
874893
uint32_t cstart = 0;
875894
uint32_t len = internal_parse_number(&buffer[1], blen, &cstart);
@@ -878,7 +897,7 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
878897
blen -= cstart + len + 1;
879898
}
880899

881-
// in sqlite mode header contains column table names (4th)
900+
// column table names
882901
for (uint32_t i=0; i<ncols; ++i) {
883902
uint32_t cstart = 0;
884903
uint32_t len = internal_parse_number(&buffer[1], blen, &cstart);
@@ -887,14 +906,44 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
887906
blen -= cstart + len + 1;
888907
}
889908

890-
// in sqlite mode header contains column origin names (5th)
909+
// column origin names
891910
for (uint32_t i=0; i<ncols; ++i) {
892911
uint32_t cstart = 0;
893912
uint32_t len = internal_parse_number(&buffer[1], blen, &cstart);
894913
rowset->origname[i] = buffer;
895914
buffer += cstart + len + 1;
896915
blen -= cstart + len + 1;
897916
}
917+
918+
// column not null flag
919+
for (uint32_t i=0; i<ncols; ++i) {
920+
uint32_t cstart = 0;
921+
uint32_t value = internal_parse_number(&buffer[1], blen, &cstart);
922+
rowset->notnull[i] = (int)value;
923+
uint32_t len = 0;
924+
buffer += cstart + len + 1;
925+
blen -= cstart + len + 1;
926+
}
927+
928+
// column primary key flag
929+
for (uint32_t i=0; i<ncols; ++i) {
930+
uint32_t cstart = 0;
931+
uint32_t value = internal_parse_number(&buffer[1], blen, &cstart);
932+
rowset->prikey[i] = (int)value;
933+
uint32_t len = 0;
934+
buffer += cstart + len + 1;
935+
blen -= cstart + len + 1;
936+
}
937+
938+
// column autoincrement key flag
939+
for (uint32_t i=0; i<ncols; ++i) {
940+
uint32_t cstart = 0;
941+
uint32_t value = internal_parse_number(&buffer[1], blen, &cstart);
942+
rowset->autoinc[i] = (int)value;
943+
uint32_t len = 0;
944+
buffer += cstart + len + 1;
945+
blen -= cstart + len + 1;
946+
}
898947
}
899948

900949
*pbuffer = buffer;
@@ -903,8 +952,8 @@ static bool internal_parse_rowset_header (SQCloudResult *rowset, char **pbuffer,
903952
return true;
904953
}
905954

906-
static bool internal_parse_rowset_values (SQCloudResult *rowset, char **pbuffer, uint32_t *pblen, uint32_t index, uint32_t bound, uint32_t ncols, uint32_t flags) {
907-
if (BITCHECK(flags, SQCLOUD_ROWSET_FLAG_HEADONLY)) return true;
955+
static bool internal_parse_rowset_values (SQCloudResult *rowset, char **pbuffer, uint32_t *pblen, uint32_t index, uint32_t bound, uint32_t ncols, uint32_t version) {
956+
if (version == ROWSET_TYPE_HEADER_ONLY) return true;
908957

909958
char *buffer = *pbuffer;
910959
uint32_t blen = *pblen;
@@ -924,7 +973,7 @@ static bool internal_parse_rowset_values (SQCloudResult *rowset, char **pbuffer,
924973
}
925974

926975
static SQCloudResult *internal_parse_rowset (SQCloudConnection *connection, char *buffer, uint32_t blen, uint32_t bstart,
927-
uint32_t nrows, uint32_t ncols, uint32_t flags) {
976+
uint32_t nrows, uint32_t ncols, uint32_t version) {
928977
SQCloudResult *rowset = (SQCloudResult *)mem_zeroalloc(sizeof(SQCloudResult));
929978
if (!rowset) {
930979
internal_set_error(connection, INTERNAL_ERRCODE_MEMORY, "Unable to allocate memory for SQCloudResult: %d.", sizeof(SQCloudResult));
@@ -937,7 +986,7 @@ static SQCloudResult *internal_parse_rowset (SQCloudConnection *connection, char
937986
rowset->blen = blen;
938987
rowset->balloc = blen;
939988
rowset->nheader = bstart;
940-
rowset->flags = flags;
989+
rowset->version = version;
941990

942991
rowset->nrows = nrows;
943992
rowset->ncols = ncols;
@@ -950,10 +999,10 @@ static SQCloudResult *internal_parse_rowset (SQCloudConnection *connection, char
950999
blen -= bstart;
9511000

9521001
// parse rowset header
953-
if (!internal_parse_rowset_header(rowset, &buffer, &blen, ncols, flags)) goto abort_rowset;
1002+
if (!internal_parse_rowset_header(rowset, &buffer, &blen, ncols, version)) goto abort_rowset;
9541003

9551004
// parse values (buffer and blen was updated in internal_parse_rowset_header)
956-
if (!internal_parse_rowset_values(rowset, &buffer, &blen, 0, nrows * ncols, ncols, flags)) goto abort_rowset;
1005+
if (!internal_parse_rowset_values(rowset, &buffer, &blen, 0, nrows * ncols, ncols, version)) goto abort_rowset;
9571006

9581007
return rowset;
9591008

@@ -968,7 +1017,7 @@ static SQCloudResult *internal_parse_rowset (SQCloudConnection *connection, char
9681017
}
9691018

9701019
static SQCloudResult *internal_parse_rowset_chunck (SQCloudConnection *connection, char *buffer, uint32_t blen, uint32_t bstart, uint32_t idx,
971-
uint32_t nrows, uint32_t ncols, uint32_t flags) {
1020+
uint32_t nrows, uint32_t ncols, uint32_t version) {
9721021
SQCloudResult *rowset = connection->_chunk;
9731022
bool first_chunk = false;
9741023

@@ -997,7 +1046,7 @@ static SQCloudResult *internal_parse_rowset_chunck (SQCloudConnection *connectio
9971046

9981047
if (first_chunk) {
9991048
rowset->tag = RESULT_ROWSET;
1000-
rowset->flags = flags;
1049+
rowset->version = version;
10011050
rowset->ischunk = true;
10021051

10031052
rowset->buffers = (char **)mem_zeroalloc((sizeof(char *) * DEFAULT_CHUCK_NBUFFERS));
@@ -1030,7 +1079,7 @@ static SQCloudResult *internal_parse_rowset_chunck (SQCloudConnection *connectio
10301079
buffer += bstart;
10311080

10321081
// parse rowset header
1033-
if (!internal_parse_rowset_header(rowset, &buffer, &blen, ncols, flags)) goto abort_rowset;
1082+
if (!internal_parse_rowset_header(rowset, &buffer, &blen, ncols, version)) goto abort_rowset;
10341083
}
10351084

10361085
// update total buffer size
@@ -1092,14 +1141,16 @@ static SQCloudResult *internal_parse_rowset_chunck (SQCloudConnection *connectio
10921141
uint32_t bound = rowset->ndata + (nrows * ncols);
10931142

10941143
// parse values
1095-
if (!internal_parse_rowset_values(rowset, &buffer, &blen, index, bound, ncols, flags)) goto abort_rowset;
1144+
if (!internal_parse_rowset_values(rowset, &buffer, &blen, index, bound, ncols, version)) goto abort_rowset;
10961145

10971146
// this check is for internal usage only
10981147
if (connection->fd == 0) return rowset;
10991148

1100-
// normal usage
1149+
#if 0
1150+
// January 24th, 2024 -> ACK disabled for Rowset in chunks
11011151
// send ACK
1102-
if (!internal_socket_write(connection, "OK", 2, true, true)) goto abort_rowset;
1152+
// if (!internal_socket_write(connection, "OK", 2, true, true)) goto abort_rowset;
1153+
#endif
11031154

11041155
// read next chunk
11051156
return internal_socket_read (connection, true);
@@ -1231,10 +1282,10 @@ static SQCloudResult *internal_parse_buffer (SQCloudConnection *connection, char
12311282
// CMD_ROWSET: *LEN 0:VERSION ROWS COLS DATA
12321283
// CMD_ROWSET_CHUNK: /LEN IDX:VERSION ROWS COLS DATA
12331284
uint32_t cstart1 = 0, cstart2 = 0, cstart3 = 0, cstart4 = 0;
1234-
uint32_t flags = 0;
1285+
uint32_t version = 0;
12351286

12361287
internal_parse_number(&buffer[1], blen-1, &cstart1); // parse len (already parsed in blen parameter)
1237-
uint32_t idx = internal_parse_number_extended(&buffer[cstart1 + 1], blen-(cstart1+1), &cstart2, &flags, NULL);
1288+
uint32_t idx = internal_parse_number_extended(&buffer[cstart1 + 1], blen-(cstart1+1), &cstart2, &version, NULL);
12381289
uint32_t nrows = internal_parse_number(&buffer[cstart1 + cstart2 + 1], blen-(cstart1 + cstart2 + 1), &cstart3);
12391290
uint32_t ncols = internal_parse_number(&buffer[cstart1 + cstart2 + + cstart3 + 1], blen-(cstart1 + cstart2 + + cstart3 + 1), &cstart4);
12401291

@@ -1244,8 +1295,8 @@ static SQCloudResult *internal_parse_buffer (SQCloudConnection *connection, char
12441295
SQCloudResult *res = NULL;
12451296
// the externalbuffer flag can change in case of compressed rowset when the end chunk is received
12461297
if (connection->_chunk) connection->_chunk->externalbuffer = externalbuffer;
1247-
if (buffer[0] == CMD_ROWSET) res = internal_parse_rowset(connection, buffer, blen, bstart, nrows, ncols, flags);
1248-
else res = internal_parse_rowset_chunck(connection, buffer, blen, bstart, idx, nrows, ncols, flags);
1298+
if (buffer[0] == CMD_ROWSET) res = internal_parse_rowset(connection, buffer, blen, bstart, nrows, ncols, version);
1299+
else res = internal_parse_rowset_chunck(connection, buffer, blen, bstart, idx, nrows, ncols, version);
12491300
if (res) {
12501301
res->externalbuffer = externalbuffer;
12511302
if (res->ischunk && res->bcount == 1) res->bext[0] = externalbuffer;
@@ -1589,10 +1640,6 @@ static bool internal_connect_apply_config (SQCloudConnection *connection, SQClou
15891640
len += snprintf(&buffer[len], sizeof(buffer) - len, "USE DATABASE %s;", config->database);
15901641
}
15911642

1592-
if (config->sqlite_mode) {
1593-
len += snprintf(&buffer[len], sizeof(buffer) - len, "SET CLIENT KEY SQLITE TO 1;");
1594-
}
1595-
15961643
if (config->compression) {
15971644
len += snprintf(&buffer[len], sizeof(buffer) - len, "SET CLIENT KEY COMPRESSION TO 1;");
15981645
}
@@ -2450,10 +2497,6 @@ SQCloudConnection *SQCloudConnectWithString (const char *s, SQCloudConfig *pconf
24502497
int compression = (int)strtol(value, NULL, 0);
24512498
config->compression = (compression > 0) ? true : false;
24522499
}
2453-
else if (strcasecmp(key, "sqlite") == 0) {
2454-
int sqlite_mode = (int)strtol(value, NULL, 0);
2455-
config->sqlite_mode = (sqlite_mode > 0) ? true : false;
2456-
}
24572500
else if (strcasecmp(key, "zerotext") == 0) {
24582501
int zero_text = (int)strtol(value, NULL, 0);
24592502
config->zero_text = (zero_text > 0) ? true : false;
@@ -2505,7 +2548,6 @@ SQCloudConnection *SQCloudConnectWithString (const char *s, SQCloudConfig *pconf
25052548
if (pconfig) {
25062549
if (pconfig->timeout) config->timeout = pconfig->timeout;
25072550
if (pconfig->compression) config->compression = pconfig->compression;
2508-
if (pconfig->sqlite_mode) config->sqlite_mode = pconfig->sqlite_mode;
25092551
if (pconfig->zero_text) config->zero_text = pconfig->zero_text;
25102552
if (pconfig->nonlinearizable) config->nonlinearizable = pconfig->nonlinearizable;
25112553
if (pconfig->no_blob) config->no_blob = pconfig->no_blob;
@@ -2915,6 +2957,33 @@ char *SQCloudRowsetColumnOrigName (SQCloudResult *result, uint32_t col, uint32_t
29152957
return internal_get_rowset_header(result, result->origname, col, len);
29162958
}
29172959

2960+
uint32_t SQCloudRowSetColumnNotNULL (SQCloudResult *result, uint32_t col) {
2961+
return internal_get_rowset_header_int(result, result->notnull, col);
2962+
}
2963+
2964+
uint32_t SQCloudRowSetColumnPrimaryKey (SQCloudResult *result, uint32_t col) {
2965+
return internal_get_rowset_header_int(result, result->prikey, col);
2966+
}
2967+
2968+
uint32_t SQCloudRowSetColumnAutoIncrement (SQCloudResult *result, uint32_t col) {
2969+
return internal_get_rowset_header_int(result, result->autoinc, col);
2970+
}
2971+
2972+
bool SQCloudRowsetCanWrite (SQCloudResult *result) {
2973+
// check if the rowset is not a JOIN (must have the same table)
2974+
char *keytable = result->tblname[0];
2975+
for (int i=1; i<result->ncols; ++i) {
2976+
if (strcmp(keytable, result->tblname[i]) != 0) return false;
2977+
}
2978+
2979+
// check if contains at least a primary key
2980+
for (int i=0; i<result->ncols; ++i) {
2981+
if (result->prikey[i] == 1) return true;
2982+
}
2983+
2984+
return false;
2985+
}
2986+
29182987
uint32_t SQCloudRowsetRows (SQCloudResult *result) {
29192988
if (!SQCloudRowsetSanityCheck(result, 0, 0)) return 0;
29202989
return result->nrows;

0 commit comments

Comments
 (0)