Commit b6135bb5 authored by Olivier Bertrand's avatar Olivier Bertrand

Continue working on MONGO tables

  modified:   storage/connect/tabmgo.cpp
  modified:   storage/connect/tabmgo.h

Add Trc to STRING allowing to test for truncation (ex oom)
  modified:   storage/connect/ha_connect.cc
  modified:   storage/connect/tabext.cpp
  modified:   storage/connect/tabjdbc.cpp
  modified:   storage/connect/tabmysql.cpp
  modified:   storage/connect/tabmysql.h
  modified:   storage/connect/tabodbc.cpp
  modified:   storage/connect/xobject.cpp
  modified:   storage/connect/xobject.h
parent 36206acc
This diff is collapsed.
......@@ -2283,7 +2283,7 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
const uchar *ptr;
//uint i, rem, len, klen, stlen;
uint i, rem, len, stlen;
bool nq, both, oom= false;
bool nq, both, oom;
OPVAL op;
Field *fp;
const key_range *ranges[2];
......@@ -2311,9 +2311,9 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
continue;
if (both && i > 0)
oom|= qry->Append(") AND (");
qry->Append(") AND (");
else
oom|= qry->Append(" WHERE (");
qry->Append(" WHERE (");
// klen= len= ranges[i]->length;
len= ranges[i]->length;
......@@ -2326,14 +2326,14 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
nq= fp->str_needs_quotes();
if (kpart != kfp->key_part)
oom|= qry->Append(" AND ");
qry->Append(" AND ");
if (q) {
oom|= qry->Append(q);
oom|= qry->Append((PSZ)fp->field_name);
oom|= qry->Append(q);
qry->Append(q);
qry->Append((PSZ)fp->field_name);
qry->Append(q);
} else
oom|= qry->Append((PSZ)fp->field_name);
qry->Append((PSZ)fp->field_name);
switch (ranges[i]->flag) {
case HA_READ_KEY_EXACT:
......@@ -2358,10 +2358,10 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
goto err;
} // endswitch flag
oom|= qry->Append((PSZ)GetValStr(op, false));
qry->Append((PSZ)GetValStr(op, false));
if (nq)
oom|= qry->Append('\'');
qry->Append('\'');
if (kpart->key_part_flag & HA_VAR_LENGTH_PART) {
String varchar;
......@@ -2369,17 +2369,17 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
varchar.set_quick((char*)ptr + HA_KEY_BLOB_LENGTH,
var_length, &my_charset_bin);
oom|= qry->Append(varchar.ptr(), varchar.length(), nq);
qry->Append(varchar.ptr(), varchar.length(), nq);
} else {
char strbuff[MAX_FIELD_WIDTH];
String str(strbuff, sizeof(strbuff), kpart->field->charset()), *res;
res= fp->val_str(&str, ptr);
oom|= qry->Append(res->ptr(), res->length(), nq);
qry->Append(res->ptr(), res->length(), nq);
} // endif flag
if (nq)
oom |= qry->Append('\'');
qry->Append('\'');
if (stlen >= len)
break;
......@@ -2394,7 +2394,9 @@ bool ha_connect::MakeKeyWhere(PGLOBAL g, PSTRG qry, OPVAL vop, char q,
} // endfor i
if ((oom|= qry->Append(")")))
qry->Append(')');
if ((oom= qry->IsTruncated()))
strcpy(g->Message, "Out of memory");
dbug_tmp_restore_column_map(table->write_set, old_map);
......
......@@ -287,7 +287,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
{
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len;
bool oom = false, first = true;
bool first = true;
PTABLE tablep = To_Table;
PCOL colp;
......@@ -341,7 +341,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (!first)
oom |= Query->Append(", ");
Query->Append(", ");
else
first = false;
......@@ -350,11 +350,11 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
} else
oom |= Query->Append(buf);
Query->Append(buf);
((PEXTCOL)colp)->SetRank(++Ncol);
} // endif colp
......@@ -362,13 +362,13 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
} else
// !Columns can occur for queries such that sql count(*) from...
// for which we will count the rows from sql * from...
oom |= Query->Append('*');
Query->Append('*');
} else
// SQL statement used to retrieve the size of the result
oom |= Query->Append("count(*)");
Query->Append("count(*)");
oom |= Query->Append(" FROM ");
Query->Append(" FROM ");
if (Catalog && *Catalog)
catp = Catalog;
......@@ -380,17 +380,17 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
schmp = Schema;
if (catp) {
oom |= Query->Append(catp);
Query->Append(catp);
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
Query->Append('.');
Query->Append(schmp);
} // endif schmp
oom |= Query->Append('.');
Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
Query->Append(schmp);
Query->Append('.');
} // endif schmp
// Table name can be encoded in UTF-8
......@@ -398,18 +398,18 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
} else
oom |= Query->Append(buf);
Query->Append(buf);
len = Query->GetLength();
if (To_CondFil) {
if (Mode == MODE_READ) {
oom |= Query->Append(" WHERE ");
oom |= Query->Append(To_CondFil->Body);
Query->Append(" WHERE ");
Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
......@@ -417,10 +417,11 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
} else
len += ((Mode == MODE_READX) ? 256 : 1);
if (oom || Query->Resize(len)) {
if (Query->IsTruncated()) {
strcpy(g->Message, "MakeSQL: Out of memory");
return true;
} // endif oom
} else
Query->Resize(len);
if (trace)
htrc("Query=%s\n", Query->GetStr());
......
......@@ -368,7 +368,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
uint pos;
bool b = false, oom = false;
bool b = false;
PTABLE tablep = To_Table;
PCOL colp;
......@@ -405,32 +405,32 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
Query = new(g)STRING(g, len, "INSERT INTO ");
if (catp) {
oom |= Query->Append(catp);
Query->Append(catp);
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
Query->Append('.');
Query->Append(schmp);
} // endif schmp
oom |= Query->Append('.');
Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
Query->Append(schmp);
Query->Append('.');
} // endif schmp
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
} else
oom |= Query->Append(buf);
Query->Append(buf);
oom |= Query->Append('(');
Query->Append('(');
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
oom |= Query->Append(", ");
Query->Append(", ");
else
b = true;
......@@ -439,15 +439,15 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
} else
oom |= Query->Append(buf);
Query->Append(buf);
} // endfor colp
if ((oom |= Query->Append(") VALUES ("))) {
if ((Query->Append(") VALUES ("))) {
strcpy(g->Message, "MakeInsert: Out of memory");
return true;
} else // in case prepared statement fails
......@@ -455,9 +455,9 @@ bool TDBJDBC::MakeInsert(PGLOBAL g)
// Make prepared statement
for (int i = 0; i < Nparm; i++)
oom |= Query->Append("?,");
Query->Append("?,");
if (oom) {
if (Query->IsTruncated()) {
strcpy(g->Message, "MakeInsert: Out of memory");
return true;
} else
......@@ -864,7 +864,6 @@ int TDBJDBC::WriteDB(PGLOBAL g)
// an insert query for each line to insert
uint len = Query->GetLength();
char buf[64];
bool oom = false;
// Make the Insert command value list
for (PCOL colp = Columns; colp; colp = colp->GetNext()) {
......@@ -872,28 +871,28 @@ int TDBJDBC::WriteDB(PGLOBAL g)
char *s = colp->GetValue()->GetCharString(buf);
if (colp->GetResultType() == TYPE_STRING)
oom |= Query->Append_quoted(s);
Query->Append_quoted(s);
else if (colp->GetResultType() == TYPE_DATE) {
DTVAL *dtv = (DTVAL*)colp->GetValue();
if (dtv->IsFormatted())
oom |= Query->Append_quoted(s);
Query->Append_quoted(s);
else
oom |= Query->Append(s);
Query->Append(s);
} else
oom |= Query->Append(s);
Query->Append(s);
} else
oom |= Query->Append("NULL");
Query->Append("NULL");
oom |= Query->Append(',');
Query->Append(',');
} // endfor colp
if (unlikely(oom)) {
if (unlikely(Query->IsTruncated())) {
strcpy(g->Message, "WriteDB: Out of memory");
return RC_FX;
} // endif oom
} // endif Query
Query->RepLast(')');
......
......@@ -586,15 +586,45 @@ PCOL TDBMGO::InsertSpecialColumn(PCOL colp)
int TDBMGO::Cardinality(PGLOBAL g)
{
if (!g)
return 0;
return 1;
else if (Cardinal < 0)
Cardinal = 10;
if (!Init(g)) {
bson_t *query;
const char *jf = NULL;
if (Pipe)
return 10;
else if (Filter)
jf = Filter;
if (jf) {
query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
if (!query) {
htrc("Wrong filter: %s", Error.message);
return 10;
} // endif Query
} else
query = bson_new();
Cardinal = (int)mongoc_collection_count(Collection,
MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
if (Cardinal < 0) {
htrc("Collection count: %s", Error.message);
Cardinal = 10;
} // endif Cardinal
bson_destroy(query);
} else
return 10;
return Cardinal;
} // end of Cardinality
/***********************************************************************/
/* MONGO GetMaxSize: returns file size estimate in number of lines. */
/* MONGO GetMaxSize: returns collection size estimate. */
/***********************************************************************/
int TDBMGO::GetMaxSize(PGLOBAL g)
{
......@@ -623,54 +653,101 @@ bool TDBMGO::Init(PGLOBAL g)
} // endif p
if (*Options) {
if (trace)
htrc("options=%s\n", Options);
} // endif Options
Opts = bson_new_from_json((const uint8_t *)Options, -1, &Error);
Uri = mongoc_uri_new(Uristr);
if (!Opts) {
sprintf(g->Message, "Wrong options: %s", Error.message);
return true;
} // endif Opts
if (!Uri) {
sprintf(g->Message, "Failed to parse URI: \"%s\"", Uristr);
return true;
} // endif Uri
} // endif *Options
// Create a new client pool instance
Pool = mongoc_client_pool_new(Uri);
mongoc_client_pool_set_error_api(Pool, 2);
} // endif Options
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
mongoc_client_pool_set_appname(Pool, "Connect");
if (Pipe) {
const char *p;
// Create a new client instance
Client = mongoc_client_pool_pop(Pool);
//Client = mongoc_client_new(uristr);
if (!Client) {
sprintf(g->Message, "Failed to get Client");
return true;
} // endif Client
//mongoc_client_set_error_api(Client, 2);
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
//mongoc_client_set_appname(Client, "Connect");
// Get a handle on the database Db_name and collection Coll_name
// Database = mongoc_client_get_database(Client, Db_name);
// Collection = mongoc_database_get_collection(Database, Coll_name);
Collection = mongoc_client_get_collection(Client, Db_name, Coll_name);
if (!Collection) {
sprintf(g->Message, "Failed to get Collection %s.%s", Db_name, Coll_name);
return true;
} // endif Collection
Done = true;
return false;
} // end of Init
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
bool TDBMGO::MakeCursor(PGLOBAL g)
{
const char *p;
PSTRG s;
if (Pipe) {
if (trace)
htrc("Pipeline: %s\n", Options);
if (To_Filter) {
p = strrchr(Options, ']');
p = strrchr(Options, ']');
if (!p) {
strcpy(g->Message, "Missing ] in pipeline");
return true;
} else
*(char*)p = 0;
if (!p) {
strcpy(g->Message, "Missing ] in pipeline");
return true;
} else
*(char*)p = 0;
s = new(g) STRING(g, 1023, (PSZ)Options);
PSTRG s = new(g) STRING(g, 1023, (PSZ)Options);
if (To_Filter) {
s->Append(",{\"$match\":");
if (To_Filter->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return true;
} // endif Selector
} else
s->Append('}');
s->Append("}]}");
s->Resize(s->GetLength() + 1);
p = s->GetStr();
To_Filter = NULL; // Not needed anymore
} // endif To_Filter
if (trace)
htrc("New Pipeline: %s\n", p);
// Project list
s->Append(",{\"$project\":{\"_id\":0");
To_Filter = NULL; // Not needed anymore
} else
p = Options;
for (PCOL cp = Columns; cp; cp = cp->GetNext()) {
s->Append(",\"");
s->Append(((PMGOCOL)cp)->Jpath);
s->Append("\":1");
} // endfor cp
s->Append("}}]}");
s->Resize(s->GetLength() + 1);
p = s->GetStr();
if (trace)
htrc("New Pipeline: %s\n", p);
Query = bson_new_from_json((const uint8_t *)p, -1, &Error);
......@@ -679,91 +756,90 @@ bool TDBMGO::Init(PGLOBAL g)
return true;
} // endif Query
} else if (Filter || To_Filter) {
if (trace) {
if (Filter)
htrc("Filter: %s\n", Filter);
if (To_Filter) {
char buf[512];
Cursor = mongoc_collection_aggregate(Collection, MONGOC_QUERY_NONE,
Query, NULL, NULL);
To_Filter->Print(g, buf, 511);
htrc("To_Filter: %s\n", buf);
} // endif To_Filter
if (mongoc_cursor_error(Cursor, &Error)) {
sprintf(g->Message, "Mongo aggregate Failure: %s", Error.message);
return true;
} // endif cursor
} // endif trace
} else {
if (Filter || To_Filter) {
if (trace) {
if (Filter)
htrc("Filter: %s\n", Filter);
PSTRG s = new(g) STRING(g, 1023, (PSZ)Filter);
if (To_Filter) {
char buf[512];
if (To_Filter) {
if (Filter)
s->Append(',');
To_Filter->Print(g, buf, 511);
htrc("To_Filter: %s\n", buf);
} // endif To_Filter
if (To_Filter->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return true;
} // endif Selector
} // endif trace
s->Resize(s->GetLength() + 1);
To_Filter = NULL; // Not needed anymore
} // endif To_Filter
s = new(g) STRING(g, 1023, (PSZ)Filter);
if (trace)
htrc("selector: %s\n", s->GetStr());
Query = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
if (To_Filter) {
if (Filter)
s->Append(',');
if (!Query) {
sprintf(g->Message, "Wrong filter: %s", Error.message);
return true;
} // endif Query
if (To_Filter->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return true;
} // endif Selector
} else
Query = bson_new();
To_Filter = NULL; // Not needed anymore
} // endif To_Filter
Uri = mongoc_uri_new(Uristr);
if (trace)
htrc("selector: %s\n", s->GetStr());
if (!Uri) {
sprintf(g->Message, "Failed to parse URI: \"%s\"", Uristr);
return true;
} // endif Uri
s->Resize(s->GetLength() + 1);
Query = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
// Create a new client pool instance
Pool = mongoc_client_pool_new(Uri);
mongoc_client_pool_set_error_api(Pool, 2);
if (!Query) {
sprintf(g->Message, "Wrong filter: %s", Error.message);
return true;
} // endif Query
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
mongoc_client_pool_set_appname(Pool, "Connect");
} else
Query = bson_new();
// Create a new client instance
Client = mongoc_client_pool_pop(Pool);
//Client = mongoc_client_new(uristr);
if (Options && *Options) {
if (trace)
htrc("options=%s\n", Options);
if (!Client) {
sprintf(g->Message, "Failed to get Client");
return true;
} // endif Client
Opts = bson_new_from_json((const uint8_t *)Options, -1, &Error);
} else {
// Projection list
if (s)
s->Set("{\"projection\":{\"_id\":0");
else
s = new(g) STRING(g, 511, "{\"projection\":{\"_id\":0");
//mongoc_client_set_error_api(Client, 2);
for (PCOL cp = Columns; cp; cp = cp->GetNext()) {
s->Append(",\"");
s->Append(((PMGOCOL)cp)->Jpath);
s->Append("\":1");
} // endfor cp
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
//mongoc_client_set_appname(Client, "Connect");
s->Append("}}");
s->Resize(s->GetLength() + 1);
Opts = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
} // endif Options
// Get a handle on the database Db_name and collection Coll_name
// Database = mongoc_client_get_database(Client, Db_name);
// Collection = mongoc_database_get_collection(Database, Coll_name);
Collection = mongoc_client_get_collection(Client, Db_name, Coll_name);
if (!Opts) {
sprintf(g->Message, "Wrong options: %s", Error.message);
return true;
} // endif Opts
if (!Collection) {
sprintf(g->Message, "Failed to get Collection %s.%s", Db_name, Coll_name);
return true;
} // endif Collection
Cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL);
} // endif Pipe
Done = true;
return false;
} // end of Init
} // end of MakeCursor
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
......@@ -797,17 +873,8 @@ bool TDBMGO::OpenDB(PGLOBAL g)
} else if (Mode == MODE_INSERT)
MakeColumnGroups(g);
else if (Pipe) {
Cursor = mongoc_collection_aggregate(Collection, MONGOC_QUERY_NONE,
Query, NULL, NULL);
if (mongoc_cursor_error(Cursor, &Error)) {
sprintf(g->Message, "Mongo aggregate Failure: %s", Error.message);
return true;
} // endif cursor
} else
Cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL);
else if (MakeCursor(g))
return true;
} // endif Use
......
......@@ -124,30 +124,31 @@ class DllExport TDBMGO : public TDBEXT {
TDBMGO(TDBMGO *tdbp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
virtual PTDB Duplicate(PGLOBAL g) { return (PTDB)new(g) TDBMGO(this); }
virtual AMT GetAmType(void) {return TYPE_AM_MGO;}
virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMGO(this);}
// Methods
virtual PTDB Clone(PTABS t);
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual int RowNumber(PGLOBAL g, bool b = FALSE) {return N;}
virtual PTDB Clone(PTABS t);
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual PCOL InsertSpecialColumn(PCOL colp);
virtual int RowNumber(PGLOBAL g, bool b = FALSE) {return N;}
// Database routines
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
virtual int Cardinality(PGLOBAL g);
virtual int GetMaxSize(PGLOBAL g);
virtual bool OpenDB(PGLOBAL g);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr);
protected:
bool Init(PGLOBAL g);
void ShowDocument(bson_iter_t *i, const bson_t *b, const char *k);
void MakeColumnGroups(PGLOBAL g);
bool DocWrite(PGLOBAL g, PINCOL icp);
bool Init(PGLOBAL g);
bool MakeCursor(PGLOBAL g);
void ShowDocument(bson_iter_t *i, const bson_t *b, const char *k);
void MakeColumnGroups(PGLOBAL g);
bool DocWrite(PGLOBAL g, PINCOL icp);
// Members
mongoc_uri_t *Uri;
......
......@@ -495,11 +495,11 @@ PCOL TDBMYSQL::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* filter should be removed from column list. */
/***********************************************************************/
bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
{
{
//char *tk = "`";
char tk = '`';
int len = 0, rank = 0;
bool b = false, oom = false;
bool b = false;
PCOL colp;
//PDBUSER dup = PlgGetUser(g);
......@@ -526,13 +526,13 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
for (colp = Columns; colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
if (b)
oom |= Query->Append(", ");
Query->Append(", ");
else
b = true;
oom |= Query->Append(tk);
oom |= Query->Append(colp->GetName());
oom |= Query->Append(tk);
Query->Append(tk);
Query->Append(colp->GetName());
Query->Append(tk);
((PMYCOL)colp)->Rank = rank++;
} // endif colp
......@@ -542,22 +542,22 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
// Query '*' from...
// (the use of a char constant minimize the result storage)
if (Isview)
oom |= Query->Append('*');
Query->Append('*');
else
oom |= Query->Append("'*'");
Query->Append("'*'");
} // endif ncol
oom |= Query->Append(" FROM ");
oom |= Query->Append(tk);
oom |= Query->Append(TableName);
oom |= Query->Append(tk);
Query->Append(" FROM ");
Query->Append(tk);
Query->Append(TableName);
Query->Append(tk);
len = Query->GetLength();
if (To_CondFil) {
if (!mx) {
oom |= Query->Append(" WHERE ");
oom |= Query->Append(To_CondFil->Body);
Query->Append(" WHERE ");
Query->Append(To_CondFil->Body);
len = Query->GetLength() + 1;
} else
len += (strlen(To_CondFil->Body) + 256);
......@@ -565,16 +565,16 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx)
} else
len += (mx ? 256 : 1);
if (oom || Query->Resize(len)) {
if (Query->IsTruncated() || Query->Resize(len)) {
strcpy(g->Message, "MakeSelect: Out of memory");
return true;
} // endif oom
} // endif Query
if (trace)
htrc("Query=%s\n", Query->GetStr());
return false;
} // end of MakeSelect
} // end of MakeSelect
/***********************************************************************/
/* MakeInsert: make the Insert statement used with MySQL connection. */
......@@ -583,7 +583,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
{
char *tk = "`";
uint len = 0;
bool b = false, oom;
bool oom, b = false;
PCOL colp;
if (Query)
......@@ -622,38 +622,38 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g)
Query = new(g) STRING(g, len);
if (Delayed)
oom = Query->Set("INSERT DELAYED INTO ");
Query->Set("INSERT DELAYED INTO ");
else
oom = Query->Set("INSERT INTO ");
Query->Set("INSERT INTO ");
oom |= Query->Append(tk);
oom |= Query->Append(TableName);
oom |= Query->Append("` (");
Query->Append(tk);
Query->Append(TableName);
Query->Append("` (");
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
oom |= Query->Append(", ");
Query->Append(", ");
else
b = true;
oom |= Query->Append(tk);
oom |= Query->Append(colp->GetName());
oom |= Query->Append(tk);
Query->Append(tk);
Query->Append(colp->GetName());
Query->Append(tk);
} // endfor colp
oom |= Query->Append(") VALUES (");
Query->Append(") VALUES (");
#if defined(MYSQL_PREPARED_STATEMENTS)
if (Prep) {
for (int i = 0; i < Nparm; i++)
oom |= Query->Append("?,");
Query->Append("?,");
Query->RepLast(')');
Query->Trim();
} // endif Prep
#endif // MYSQL_PREPARED_STATEMENTS
if (oom)
if ((oom = Query->IsTruncated()))
strcpy(g->Message, "MakeInsert: Out of memory");
return oom;
......@@ -684,18 +684,18 @@ bool TDBMYSQL::MakeCommand(PGLOBAL g)
strlwr(strcpy(name, Name)); // Not a keyword
if ((p = strstr(qrystr, name))) {
bool oom = Query->Set(Qrystr, p - qrystr);
Query->Set(Qrystr, p - qrystr);
if (qtd && *(p-1) == ' ') {
oom |= Query->Append('`');
oom |= Query->Append(TableName);
oom |= Query->Append('`');
Query->Append('`');
Query->Append(TableName);
Query->Append('`');
} else
oom |= Query->Append(TableName);
Query->Append(TableName);
oom |= Query->Append(Qrystr + (p - qrystr) + strlen(name));
Query->Append(Qrystr + (p - qrystr) + strlen(name));
if (oom) {
if (Query->IsTruncated()) {
strcpy(g->Message, "MakeCommand: Out of memory");
return true;
} else
......@@ -1161,24 +1161,23 @@ int TDBMYSQL::WriteDB(PGLOBAL g)
int rc;
uint len = Query->GetLength();
char buf[64];
bool oom = false;
// Make the Insert command value list
for (PCOL colp = Columns; colp; colp = colp->GetNext()) {
if (!colp->GetValue()->IsNull()) {
if (colp->GetResultType() == TYPE_STRING ||
colp->GetResultType() == TYPE_DATE)
oom |= Query->Append_quoted(colp->GetValue()->GetCharString(buf));
Query->Append_quoted(colp->GetValue()->GetCharString(buf));
else
oom |= Query->Append(colp->GetValue()->GetCharString(buf));
Query->Append(colp->GetValue()->GetCharString(buf));
} else
oom |= Query->Append("NULL");
Query->Append("NULL");
oom |= Query->Append(',');
Query->Append(',');
} // endfor colp
if (unlikely(oom)) {
if (unlikely(Query->IsTruncated())) {
strcpy(g->Message, "WriteDB: Out of memory");
rc = RC_FX;
} else {
......@@ -1186,7 +1185,7 @@ int TDBMYSQL::WriteDB(PGLOBAL g)
Myc.m_Rows = -1; // To execute the query
rc = Myc.ExecSQL(g, Query->GetStr());
Query->Truncate(len); // Restore query
} // endif oom
} // endif Query
return (rc == RC_NF) ? RC_OK : rc; // RC_NF is Ok
} // end of WriteDB
......
......@@ -109,7 +109,7 @@ class TDBMYSQL : public TDBEXT {
// Internal functions
bool MakeSelect(PGLOBAL g, bool mx);
bool MakeInsert(PGLOBAL g);
int BindColumns(PGLOBAL g);
int BindColumns(PGLOBAL g __attribute__((unused)));
virtual bool MakeCommand(PGLOBAL g);
//int MakeUpdate(PGLOBAL g);
//int MakeDelete(PGLOBAL g);
......
......@@ -299,7 +299,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
{
char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
bool b = false, oom = false;
bool oom, b = false;
PTABLE tablep = To_Table;
PCOL colp;
......@@ -336,32 +336,32 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
Query = new(g) STRING(g, len, "INSERT INTO ");
if (catp) {
oom |= Query->Append(catp);
Query->Append(catp);
if (schmp) {
oom |= Query->Append('.');
oom |= Query->Append(schmp);
Query->Append('.');
Query->Append(schmp);
} // endif schmp
oom |= Query->Append('.');
Query->Append('.');
} else if (schmp) {
oom |= Query->Append(schmp);
oom |= Query->Append('.');
Query->Append(schmp);
Query->Append('.');
} // endif schmp
if (Quote) {
// Put table name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
} else
oom |= Query->Append(buf);
Query->Append(buf);
oom |= Query->Append('(');
Query->Append('(');
for (colp = Columns; colp; colp = colp->GetNext()) {
if (b)
oom |= Query->Append(", ");
Query->Append(", ");
else
b = true;
......@@ -370,20 +370,20 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
if (Quote) {
// Put column name between identifier quotes in case in contains blanks
oom |= Query->Append(Quote);
oom |= Query->Append(buf);
oom |= Query->Append(Quote);
Query->Append(Quote);
Query->Append(buf);
Query->Append(Quote);
} else
oom |= Query->Append(buf);
Query->Append(buf);
} // endfor colp
oom |= Query->Append(") VALUES (");
Query->Append(") VALUES (");
for (int i = 0; i < Nparm; i++)
oom |= Query->Append("?,");
Query->Append("?,");
if (oom)
if ((oom = Query->IsTruncated()))
strcpy(g->Message, "MakeInsert: Out of memory");
else
Query->RepLast(')');
......
......@@ -192,7 +192,7 @@ void CONSTANT::Print(PGLOBAL g, char *ps, uint z)
/* STRING public constructor for new char values. Alloc Size must be */
/* calculated because PlugSubAlloc rounds up size to multiple of 8. */
/***********************************************************************/
STRING::STRING(PGLOBAL g, uint n, char *str)
STRING::STRING(PGLOBAL g, uint n, PSZ str)
{
G = g;
Length = (str) ? strlen(str) : 0;
......@@ -205,10 +205,12 @@ STRING::STRING(PGLOBAL g, uint n, char *str)
Next = GetNext();
Size = Next - Strp;
Trc = false;
} else {
// This should normally never happen
Next = NULL;
Size = 0;
Trc = true;
} // endif Strp
} // end of STRING constructor
......@@ -229,6 +231,7 @@ char *STRING::Realloc(uint len)
if (!p) {
// No more room in Sarea; this is very unlikely
strcpy(G->Message, "No more room in work area");
Trc = true;
return NULL;
} // endif p
......
......@@ -130,6 +130,7 @@ class DllExport STRING : public BLOCK {
inline void SetLength(uint n) {Length = n;}
inline PSZ GetStr(void) {return Strp;}
inline uint32 GetSize(void) {return Size;}
inline bool IsTruncated(void) {return Trc;}
// Methods
inline void Reset(void) {*Strp = 0;}
......@@ -156,6 +157,7 @@ class DllExport STRING : public BLOCK {
PSZ Strp; // The char string
uint Length; // String length
uint Size; // Allocated size
bool Trc; // When truncated
char *Next; // Next alloc position
}; // end of class STRING
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment