diff options
Diffstat (limited to 'storage/connect')
86 files changed, 3994 insertions, 1702 deletions
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index ce6de424421..a602084b5bd 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -22,16 +22,16 @@ fmdlex.c osutil.c plugutil.c rcmsg.c rcmsg.h array.cpp blkfil.cpp colblk.cpp csort.cpp filamap.cpp filamdbf.cpp filamfix.cpp filamgz.cpp filamtxt.cpp filter.cpp json.cpp jsonudf.cpp maputil.cpp myconn.cpp myutil.cpp plgdbutl.cpp -reldef.cpp tabcol.cpp tabdos.cpp tabfix.cpp tabfmt.cpp tabjson.cpp table.cpp -tabmul.cpp tabmysql.cpp taboccur.cpp tabpivot.cpp tabsys.cpp tabtbl.cpp tabutil.cpp -tabvir.cpp tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp +reldef.cpp tabcol.cpp tabdos.cpp tabext.cpp tabfix.cpp tabfmt.cpp tabjson.cpp +table.cpp tabmul.cpp tabmysql.cpp taboccur.cpp tabpivot.cpp tabsys.cpp tabtbl.cpp +tabutil.cpp tabvir.cpp tabxcl.cpp valblk.cpp value.cpp xindex.cpp xobject.cpp array.h blkfil.h block.h catalog.h checklvl.h colblk.h connect.h csort.h engmsg.h filamap.h filamdbf.h filamfix.h filamgz.h filamtxt.h filter.h global.h ha_connect.h inihandl.h json.h jsonudf.h maputil.h msgid.h mycat.h myconn.h myutil.h os.h osutil.h plgcnx.h plgdbsem.h preparse.h reldef.h -resource.h tabcol.h tabdos.h tabfix.h tabfmt.h tabjson.h tabmul.h tabmysql.h -taboccur.h tabpivot.h tabsys.h tabtbl.h tabutil.h tabvir.h tabxcl.h +resource.h tabcol.h tabdos.h tabext.h tabfix.h tabfmt.h tabjson.h tabmul.h +tabmysql.h taboccur.h tabpivot.h tabsys.h tabtbl.h tabutil.h tabvir.h tabxcl.h user_connect.h valblk.h value.h xindex.h xobject.h xtable.h) # diff --git a/storage/connect/array.cpp b/storage/connect/array.cpp index 193514eeb99..1998ab890e9 100644 --- a/storage/connect/array.cpp +++ b/storage/connect/array.cpp @@ -1,7 +1,7 @@ /************* Array C++ Functions Source Code File (.CPP) *************/ /* Name: ARRAY.CPP Version 2.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */ /* */ /* This file contains the XOBJECT derived class ARRAY functions. */ /* ARRAY is used for elaborate type of processing, such as sorting */ @@ -141,7 +141,7 @@ PARRAY MakeValueArray(PGLOBAL g, PPARM pp) /* ARRAY public constructor. */ /***********************************************************************/ ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec) - : CSORT(FALSE) + : CSORT(false) { Nval = 0; Ndif = 0; @@ -188,14 +188,14 @@ ARRAY::ARRAY(PGLOBAL g, int type, int size, int length, int prec) else if (type != TYPE_PCHAR) Value = AllocateValue(g, type, Len, prec); - Constant = TRUE; + Constant = true; } // end of ARRAY constructor #if 0 /***********************************************************************/ /* ARRAY public constructor from a QUERY. */ /***********************************************************************/ -ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(FALSE) +ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(false) { Type = qryp->GetColType(0); Nval = qryp->GetNblin(); @@ -206,7 +206,7 @@ ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(FALSE) Xsize = -1; Len = qryp->GetColLength(0); X = Inf = Sup = 0; - Correlated = FALSE; + Correlated = false; switch (Type) { case TYPE_STRING: @@ -229,13 +229,13 @@ ARRAY::ARRAY(PGLOBAL g, PQUERY qryp) : CSORT(FALSE) // The error message was built by ??? Type = TYPE_ERROR; - Constant = TRUE; + Constant = true; } // end of ARRAY constructor /***********************************************************************/ /* ARRAY constructor from a TYPE_LIST subarray. */ /***********************************************************************/ -ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(FALSE) +ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(false) { int prec; LSTBLK *lp; @@ -260,7 +260,7 @@ ARRAY::ARRAY(PGLOBAL g, PARRAY par, int k) : CSORT(FALSE) Len = (Type == TYPE_STRING) ? Vblp->GetVlen() : 0; prec = (Type == TYPE_FLOAT) ? 2 : 0; Value = AllocateValue(g, Type, Len, prec, NULL); - Constant = TRUE; + Constant = true; } // end of ARRAY constructor /***********************************************************************/ @@ -283,7 +283,7 @@ bool ARRAY::AddValue(PGLOBAL g, PSZ strp) { if (Type != TYPE_STRING) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "CHAR"); - return TRUE; + return true; } // endif Type if (trace) @@ -292,7 +292,7 @@ bool ARRAY::AddValue(PGLOBAL g, PSZ strp) //Value->SetValue_psz(strp); //Vblp->SetValue(valp, Nval++); Vblp->SetValue(strp, Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -302,14 +302,14 @@ bool ARRAY::AddValue(PGLOBAL g, void *p) { if (Type != TYPE_PCHAR) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "PCHAR"); - return TRUE; + return true; } // endif Type if (trace) htrc(" adding pointer(%d): %p\n", Nval, p); Vblp->SetValue((PSZ)p, Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -319,7 +319,7 @@ bool ARRAY::AddValue(PGLOBAL g, short n) { if (Type != TYPE_SHORT) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "SHORT"); - return TRUE; + return true; } // endif Type if (trace) @@ -328,7 +328,7 @@ bool ARRAY::AddValue(PGLOBAL g, short n) //Value->SetValue(n); //Vblp->SetValue(valp, Nval++); Vblp->SetValue(n, Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -338,7 +338,7 @@ bool ARRAY::AddValue(PGLOBAL g, int n) { if (Type != TYPE_INT) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "INTEGER"); - return TRUE; + return true; } // endif Type if (trace) @@ -347,7 +347,7 @@ bool ARRAY::AddValue(PGLOBAL g, int n) //Value->SetValue(n); //Vblp->SetValue(valp, Nval++); Vblp->SetValue(n, Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -357,7 +357,7 @@ bool ARRAY::AddValue(PGLOBAL g, double d) { if (Type != TYPE_DOUBLE) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(Type), "DOUBLE"); - return TRUE; + return true; } // endif Type if (trace) @@ -365,7 +365,7 @@ bool ARRAY::AddValue(PGLOBAL g, double d) Value->SetValue(d); Vblp->SetValue(Value, Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -376,7 +376,7 @@ bool ARRAY::AddValue(PGLOBAL g, PXOB xp) if (Type != xp->GetResultType()) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(xp->GetResultType()), GetTypeName(Type)); - return TRUE; + return true; } // endif Type if (trace) @@ -384,7 +384,7 @@ bool ARRAY::AddValue(PGLOBAL g, PXOB xp) //AddValue(xp->GetValue()); Vblp->SetValue(xp->GetValue(), Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -395,14 +395,14 @@ bool ARRAY::AddValue(PGLOBAL g, PVAL vp) if (Type != vp->GetType()) { sprintf(g->Message, MSG(ADD_BAD_TYPE), GetTypeName(vp->GetType()), GetTypeName(Type)); - return TRUE; + return true; } // endif Type if (trace) htrc(" adding (%d) from vp=%p\n", Nval, vp); Vblp->SetValue(vp, Nval++); - return FALSE; + return false; } // end of AddValue /***********************************************************************/ @@ -423,12 +423,12 @@ bool ARRAY::GetSubValue(PGLOBAL g, PVAL valp, int *kp) if (Type != TYPE_LIST) { sprintf(g->Message, MSG(NO_SUB_VAL), Type); - return TRUE; + return true; } // endif Type vblp = ((LSTBLK*)Vblp)->Mbvk[kp[0]]->Vblk; valp->SetValue_pvblk(vblp, kp[1]); - return FALSE; + return false; } // end of GetSubValue #endif // 0 @@ -476,11 +476,11 @@ bool ARRAY::Find(PVAL valp) else if (n > 0) Inf = X; else - return TRUE; + return true; } // endwhile - return FALSE; + return false; } // end of Find /***********************************************************************/ @@ -504,9 +504,9 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm) int top = Nval - 1; if (top < 0) // Array is empty - // Return TRUE for ALL because it means that there are no item that + // Return true for ALL because it means that there are no item that // does not verify the condition, which is true indeed. - // Return FALSE for ANY because TRUE means that there is at least + // Return false for ANY because true means that there is at least // one item that verifies the condition, which is false. return opm == 2; @@ -528,9 +528,9 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm) else if (opc == OP_NE && opm == 2) return !Find(vp); else if (opc == OP_EQ && opm == 2) - return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : FALSE; + return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : false; else if (opc == OP_NE && opm == 1) - return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : TRUE; + return (Ndif == 1) ? !(Vcompare(vp, 0) & bt) : true; if (Type != TYPE_LIST) { if (opc == OP_GT || opc == OP_GE) @@ -544,15 +544,15 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm) if (opm == 2) { for (i = 0; i < Nval; i++) if (Vcompare(vp, i) & bt) - return FALSE; + return false; - return TRUE; + return true; } else { // opm == 1 for (i = 0; i < Nval; i++) if (!(Vcompare(vp, i) & bt)) - return TRUE; + return true; - return FALSE; + return false; } // endif opm } // end of FilTest @@ -566,7 +566,7 @@ bool ARRAY::CanBeShort(void) int* To_Val = (int*)Valblk->GetMemp(); if (Type != TYPE_INT || !Ndif) - return FALSE; + return false; // Because the array is sorted, this is true if all the array // int values are in the range of SHORT values @@ -582,7 +582,7 @@ bool ARRAY::CanBeShort(void) int ARRAY::Convert(PGLOBAL g, int k, PVAL vp) { int i, prec = 0; - bool b = FALSE; + bool b = false; PMBV ovblk = Valblk; PVBLK ovblp = Vblp; @@ -619,7 +619,7 @@ int ARRAY::Convert(PGLOBAL g, int k, PVAL vp) if (((DTVAL*)Value)->SetFormat(g, vp)) return TYPE_ERROR; else - b = TRUE; // Sort the new array on date internal values + b = true; // Sort the new array on date internal values /*********************************************************************/ /* Do the actual conversion. */ @@ -706,7 +706,7 @@ void ARRAY::SetPrecision(PGLOBAL g, int p) /***********************************************************************/ /* Sort and eliminate distinct values from an array. */ /* Note: this is done by making a sorted index on distinct values. */ -/* Returns FALSE if Ok or TRUE in case of error. */ +/* Returns false if Ok or true in case of error. */ /***********************************************************************/ bool ARRAY::Sort(PGLOBAL g) { @@ -789,14 +789,14 @@ bool ARRAY::Sort(PGLOBAL g) Bot = -1; // For non optimized search Top = Ndif; // Find searches the whole array. - return FALSE; + return false; error: Nval = Ndif = 0; Valblk->Free(); PlgDBfree(Index); PlgDBfree(Offset); - return TRUE; + return true; } // end of Sort /***********************************************************************/ @@ -839,9 +839,9 @@ void *ARRAY::GetSortIndex(PGLOBAL g) /***********************************************************************/ /* Block filter testing for IN operator on Column/Array operands. */ -/* Here we call Find that returns TRUE if the value is in the array */ +/* Here we call Find that returns true if the value is in the array */ /* with X equal to the index of the found value in the array, or */ -/* FALSE if the value is not in the array with Inf and Sup being the */ +/* false if the value is not in the array with Inf and Sup being the */ /* indexes of the array values that are immediately below and over */ /* the not found value. This enables to restrict the array to the */ /* values that are between the min and max block values and to return */ @@ -854,9 +854,9 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm, bool bin, bax, pin, pax, veq, all = (opm == 2); if (Ndif == 0) // Array is empty - // Return TRUE for ALL because it means that there are no item that + // Return true for ALL because it means that there are no item that // does not verify the condition, which is true indeed. - // Return FALSE for ANY because TRUE means that there is at least + // Return false for ANY because true means that there is at least // one item that verifies the condition, which is false. return (all) ? 2 : -2; else if (opc == OP_EQ && all && Ndif > 1) @@ -864,7 +864,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm, else if (opc == OP_NE && !all && Ndif > 1) return 2; // else if (Ndif == 1) -// all = FALSE; +// all = false; // veq is true when all values in the block are equal switch (Type) { @@ -874,7 +874,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm, case TYPE_SHORT: veq = *(short*)minp == *(short*)maxp; break; case TYPE_INT: veq = *(int*)minp == *(int*)maxp; break; case TYPE_DOUBLE: veq = *(double*)minp == *(double*)maxp; break; - default: veq = FALSE; // Error ? + default: veq = false; // Error ? } // endswitch type if (!s) @@ -898,7 +898,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm, case OP_GT: return -1; break; } // endswitch opc - pax = (opc == OP_GE) ? (X < Ndif - 1) : TRUE; + pax = (opc == OP_GE) ? (X < Ndif - 1) : true; } else if (Inf == Bot) { // Max value is smaller than min list value return (opc == OP_LT || opc == OP_LE || opc == OP_NE) ? 1 : -1; @@ -924,7 +924,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm, case OP_LT: return (s) ? -2 : -1; break; } // endswitch opc - pin = (opc == OP_LE) ? (X > 0) : TRUE; + pin = (opc == OP_LE) ? (X > 0) : true; } else if (Sup == Ndif) { // Min value is greater than max list value if (opc == OP_GT || opc == OP_GE || opc == OP_NE) @@ -956,7 +956,7 @@ int ARRAY::BlockTest(PGLOBAL, int opc, int opm, // the only possible overlaps between the array and the block are: // Array: +-------+ +-------+ +-------+ +-----+ // Block: +-----+ +---+ +------+ +--------+ - // TRUE: pax pin pax pin + // true: pax pin pax pin if (all) switch (opc) { case OP_GT: case OP_GE: return (pax) ? -1 : 0; break; @@ -1052,7 +1052,7 @@ void ARRAY::Print(PGLOBAL, char *ps, uint z) /***********************************************************************/ /* MULAR public constructor. */ /***********************************************************************/ -MULAR::MULAR(PGLOBAL g, int n) : CSORT(FALSE) +MULAR::MULAR(PGLOBAL g, int n) : CSORT(false) { Narray = n; Pars = (PARRAY*)PlugSubAlloc(g, NULL, n * sizeof(PARRAY)); @@ -1075,7 +1075,7 @@ int MULAR::Qcompare(int *i1, int *i2) /***********************************************************************/ /* Sort and eliminate distinct values from multiple arrays. */ /* Note: this is done by making a sorted index on distinct values. */ -/* Returns FALSE if Ok or TRUE in case of error. */ +/* Returns false if Ok or true in case of error. */ /***********************************************************************/ bool MULAR::Sort(PGLOBAL g) { @@ -1087,7 +1087,7 @@ bool MULAR::Sort(PGLOBAL g) for (n = 1; n < Narray; n++) if (Pars[n]->Nval != nval) { strcpy(g->Message, MSG(BAD_ARRAY_VAL)); - return TRUE; + return true; } // endif nval // Prepare non conservative sort with offet values @@ -1161,10 +1161,10 @@ bool MULAR::Sort(PGLOBAL g) Pars[n]->Top = ndif; // Find searches the whole array. } // endfor n - return FALSE; + return false; error: PlgDBfree(Index); PlgDBfree(Offset); - return TRUE; + return true; } // end of Sort diff --git a/storage/connect/array.h b/storage/connect/array.h index 6fb38ae6b47..dfc3638de8a 100644 --- a/storage/connect/array.h +++ b/storage/connect/array.h @@ -1,7 +1,7 @@ /**************** Array H Declares Source Code File (.H) ***************/ /* Name: ARRAY.H Version 3.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2014 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */ /* */ /* This file contains the ARRAY and VALBASE derived classes declares. */ /***********************************************************************/ @@ -53,8 +53,8 @@ class DllExport ARRAY : public XOBJECT, public CSORT { // Array descblock using XOBJECT::GetIntValue; virtual void Reset(void) {Bot = -1;} virtual int Qcompare(int *, int *); - virtual bool Compare(PXOB) {assert(FALSE); return FALSE;} - virtual bool SetFormat(PGLOBAL, FORMAT&) {assert(FALSE); return FALSE;} + virtual bool Compare(PXOB) {assert(false); return false;} + virtual bool SetFormat(PGLOBAL, FORMAT&) {assert(false); return false;} //virtual int CheckSpcCol(PTDB, int) {return 0;} virtual void Print(PGLOBAL g, FILE *f, uint n); virtual void Print(PGLOBAL g, char *ps, uint z); diff --git a/storage/connect/colblk.cpp b/storage/connect/colblk.cpp index 80b405be041..58841387249 100644 --- a/storage/connect/colblk.cpp +++ b/storage/connect/colblk.cpp @@ -1,7 +1,7 @@ /************* Colblk C++ Functions Source Code File (.CPP) ************/ -/* Name: COLBLK.CPP Version 2.1 */ +/* Name: COLBLK.CPP Version 2.2 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */ /* */ /* This file contains the COLBLK class functions. */ /***********************************************************************/ @@ -300,7 +300,7 @@ FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op) #if defined(__WIN__) Format.Prec = 1; // Case insensitive #endif // __WIN__ - Constant = (!((PTDBASE)To_Tdb)->GetDef()->GetMultiple() && + Constant = (!To_Tdb->GetDef()->GetMultiple() && To_Tdb->GetAmType() != TYPE_AM_PLG && To_Tdb->GetAmType() != TYPE_AM_PLM); Fn = NULL; @@ -312,11 +312,11 @@ FIDBLK::FIDBLK(PCOLUMN cp, OPVAL op) : SPCBLK(cp), Op(op) /***********************************************************************/ void FIDBLK::ReadColumn(PGLOBAL g) { - if (Fn != ((PTDBASE)To_Tdb)->GetFile(g)) { + if (Fn != To_Tdb->GetFile(g)) { char filename[_MAX_PATH]; - Fn = ((PTDBASE)To_Tdb)->GetFile(g); - PlugSetPath(filename, Fn, ((PTDBASE)To_Tdb)->GetPath()); + Fn = To_Tdb->GetFile(g); + PlugSetPath(filename, Fn, To_Tdb->GetPath()); if (Op != OP_XX) { char buff[_MAX_PATH]; @@ -378,10 +378,8 @@ void PRTBLK::ReadColumn(PGLOBAL g) { if (Pname == NULL) { char *p; - PTDBASE tdbp = (PTDBASE)To_Tdb; - - Pname = tdbp->GetDef()->GetStringCatInfo(g, "partname", "?"); + Pname = To_Tdb->GetDef()->GetStringCatInfo(g, "partname", "?"); p = strrchr(Pname, '#'); Value->SetValue_psz((p) ? p + 1 : Pname); } // endif Pname diff --git a/storage/connect/connect.cc b/storage/connect/connect.cc index 460d47bcf62..098119e7be1 100644 --- a/storage/connect/connect.cc +++ b/storage/connect/connect.cc @@ -12,7 +12,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /***********************************************************************/ /* Author Olivier BERTRAND bertrandop@gmail.com 2004-2015 */ @@ -157,23 +157,22 @@ bool CntCheckDB(PGLOBAL g, PHC handler, const char *pathname) /* Returns valid: true if this is a table info. */ /***********************************************************************/ bool CntInfo(PGLOBAL g, PTDB tp, PXF info) - { - bool b; - PTDBDOS tdbp= (PTDBDOS)tp; +{ + if (tp) { + bool b = (tp->GetFtype() == RECFM_NAF); + PTDBDOS tdbp = b ? NULL : (PTDBDOS)tp; - if (tdbp) { - b= tdbp->GetFtype() != RECFM_NAF; - info->data_file_length= (b) ? (ulonglong)tdbp->GetFileLength(g) : 0; + info->data_file_length = (b) ? 0 : (ulonglong)tdbp->GetFileLength(g); - if (!b || info->data_file_length) - info->records= (unsigned)tdbp->Cardinality(g); -// info->records= (unsigned)tdbp->GetMaxSize(g); + if (b || info->data_file_length) + info->records= (unsigned)tp->Cardinality(g); +// info->records= (unsigned)tp->GetMaxSize(g); else info->records= 0; // info->mean_rec_length= tdbp->GetLrecl(); info->mean_rec_length= 0; - info->data_file_name= (b) ? tdbp->GetFile(g) : NULL; + info->data_file_name= (b) ? NULL : tdbp->GetFile(g); return true; } else { info->data_file_length= 0; @@ -183,7 +182,7 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info) return false; } // endif tdbp - } // end of CntInfo +} // end of CntInfo /***********************************************************************/ /* GetTDB: Get the table description block of a CONNECT table. */ @@ -332,9 +331,9 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2, } // endfor colp // Attach the updated columns list to the main table - ((PTDBASE)tdbp)->SetSetCols(utp->GetColumns()); + tdbp->SetSetCols(utp->GetColumns()); } else if (tdbp && mode == MODE_INSERT) - ((PTDBASE)tdbp)->SetSetCols(tdbp->GetColumns()); + tdbp->SetSetCols(tdbp->GetColumns()); // Now do open the physical table if (trace) @@ -343,7 +342,7 @@ bool CntOpenTable(PGLOBAL g, PTDB tdbp, MODE mode, char *c1, char *c2, //tdbp->SetMode(mode); - if (del/* && ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF*/) { + if (del/* && (tdbp->GetFtype() != RECFM_NAF*/) { // To avoid erasing the table when doing a partial delete // make a fake Next // PDOSDEF ddp= new(g) DOSDEF; @@ -436,7 +435,7 @@ RCODE CntReadNext(PGLOBAL g, PTDB tdbp) if (!tdbp) return RC_FX; - else if (((PTDBASE)tdbp)->GetKindex()) { + else if (tdbp->GetKindex()) { // Reading sequencially an indexed table. This happens after the // handler function records_in_range was called and MySQL decides // to quit using the index (!!!) Drop the index. @@ -483,7 +482,7 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) { RCODE rc; PCOL colp; - PTDBASE tp= (PTDBASE)tdbp; +//PTDBASE tp= (PTDBASE)tdbp; if (!tdbp) return RC_FX; @@ -501,13 +500,13 @@ RCODE CntWriteRow(PGLOBAL g, PTDB tdbp) } // endif rc // Store column values in table write buffer(s) - for (colp= tp->GetSetCols(); colp; colp= colp->GetNext()) + for (colp= tdbp->GetSetCols(); colp; colp= colp->GetNext()) if (!colp->GetColUse(U_VIRTUAL)) colp->WriteColumn(g); - if (tp->IsIndexed()) + if (tdbp->IsIndexed()) // Index values must be sorted before updating - rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, true); + rc= (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, true); else // Return result code from write operation rc= (RCODE)tdbp->WriteDB(g); @@ -535,7 +534,7 @@ RCODE CntUpdateRow(PGLOBAL g, PTDB tdbp) RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) { RCODE rc; - PTDBASE tp= (PTDBASE)tdbp; +//PTDBASE tp= (PTDBASE)tdbp; if (!tdbp || tdbp->GetMode() != MODE_DELETE) return RC_FX; @@ -543,16 +542,16 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) return RC_NF; if (all) { - if (((PTDBASE)tdbp)->GetDef()->Indexable()) + if (tdbp->GetDef()->Indexable()) ((PTDBDOS)tdbp)->Cardinal= 0; // Note: if all, this call will be done when closing the table rc= (RCODE)tdbp->DeleteDB(g, RC_FX); -//} else if (tp->GetKindex() && !tp->GetKindex()->IsSorted() && -// tp->Txfp->GetAmType() != TYPE_AM_DBF) { - } else if(tp->IsIndexed()) { +//} else if (tdbp->GetKindex() && !((PTDBASE)tdbp)->GetKindex()->IsSorted() && +// ((PTDBASE)tdbp)->Txfp->GetAmType() != TYPE_AM_DBF) { + } else if(tdbp->IsIndexed()) { // Index values must be sorted before updating - rc= (RCODE)((PTDBDOS)tp)->GetTxfp()->StoreValues(g, false); + rc= (RCODE)((PTDBDOS)tdbp)->GetTxfp()->StoreValues(g, false); } else // Return result code from delete operation rc= (RCODE)tdbp->DeleteDB(g, RC_OK); @@ -565,7 +564,7 @@ RCODE CntDeleteRow(PGLOBAL g, PTDB tdbp, bool all) int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) { int rc= RC_OK; - TDBASE *tbxp= (PTDBASE)tdbp; +//TDBASE *tbxp= (PTDBASE)tdbp; if (!tdbp) return rc; // Nothing to do @@ -581,13 +580,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) tdbp, tdbp->GetMode(), nox, abort); if (tdbp->GetMode() == MODE_DELETE && tdbp->GetUse() == USE_OPEN) { - if (tbxp->IsIndexed()) + if (tdbp->IsIndexed()) rc= ((PTDBDOS)tdbp)->GetTxfp()->DeleteSortedRows(g); if (!rc) rc= tdbp->DeleteDB(g, RC_EF); // Specific A.M. delete routine - } else if (tbxp->GetMode() == MODE_UPDATE && tbxp->IsIndexed()) + } else if (tdbp->GetMode() == MODE_UPDATE && tdbp->IsIndexed()) rc= ((PTDBDOX)tdbp)->Txfp->UpdateSortedRows(g); switch(rc) { @@ -595,7 +594,7 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) abort= true; break; case RC_INFO: - PushWarning(g, tbxp); + PushWarning(g, tdbp); break; } // endswitch rc @@ -631,11 +630,13 @@ int CntCloseTable(PGLOBAL g, PTDB tdbp, bool nox, bool abort) if (trace > 1) printf("About to reset opt\n"); - // Make all the eventual indexes - tbxp= (TDBDOX*)tdbp; - tbxp->ResetKindex(g, NULL); - tbxp->SetKey_Col(NULL); - rc= tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1); + if (!tdbp->IsRemote()) { + // Make all the eventual indexes + PTDBDOX tbxp = (PTDBDOX)tdbp; + tbxp->ResetKindex(g, NULL); + tbxp->SetKey_Col(NULL); + rc = tbxp->ResetTableOpt(g, true, tbxp->GetDef()->Indexable() == 1); + } // endif remote err: if (trace > 1) @@ -657,10 +658,10 @@ int CntIndexInit(PGLOBAL g, PTDB ptdb, int id, bool sorted) if (!ptdb) return -1; - else if (!((PTDBASE)ptdb)->GetDef()->Indexable()) { + else if (!ptdb->GetDef()->Indexable()) { sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName()); return 0; - } else if (((PTDBASE)ptdb)->GetDef()->Indexable() == 3) { + } else if (ptdb->GetDef()->Indexable() == 3) { return 1; } else tdbp= (PTDBDOX)ptdb; @@ -745,7 +746,7 @@ RCODE CntIndexRead(PGLOBAL g, PTDB ptdb, OPVAL op, if (!ptdb) return RC_FX; else - x= ((PTDBASE)ptdb)->GetDef()->Indexable(); + x= ptdb->GetDef()->Indexable(); if (!x) { sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName()); @@ -875,7 +876,7 @@ int CntIndexRange(PGLOBAL g, PTDB ptdb, const uchar* *key, uint *len, if (!ptdb) return -1; - x= ((PTDBASE)ptdb)->GetDef()->Indexable(); + x= ptdb->GetDef()->Indexable(); if (!x) { sprintf(g->Message, MSG(TABLE_NO_INDEX), ptdb->GetName()); diff --git a/storage/connect/connect.h b/storage/connect/connect.h index ce4cf9bf8b9..128561b80f3 100644 --- a/storage/connect/connect.h +++ b/storage/connect/connect.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /**************** Cnt H Declares Source Code File (.H) *****************/ /* Name: CONNECT.H Version 2.4 */ diff --git a/storage/connect/domdoc.cpp b/storage/connect/domdoc.cpp index eb9660b439d..1622ec16c68 100644 --- a/storage/connect/domdoc.cpp +++ b/storage/connect/domdoc.cpp @@ -116,7 +116,9 @@ bool DOMDOC::ParseFile(PGLOBAL g, char *fn) // Parse an in memory document char *xdoc = GetMemDoc(g, fn); - b = (xdoc) ? (bool)Docp->loadXML((_bstr_t)xdoc) : false; + // This is not equivalent to load for UTF8 characters + // It is why get node content is not the same + b = (xdoc) ? (bool)Docp->loadXML((_bstr_t)xdoc) : false; } else // Load the document b = (bool)Docp->load((_bstr_t)fn); @@ -266,6 +268,7 @@ DOMNODE::DOMNODE(PXDOC dp, MSXML2::IXMLDOMNodePtr np) : XMLNODE(dp) Nodep = np; Ws = NULL; Len = 0; + Zip = (bool)dp->zip; } // end of DOMNODE constructor /******************************************************************/ @@ -316,8 +319,10 @@ RCODE DOMNODE::GetContent(PGLOBAL g, char *buf, int len) RCODE rc = RC_OK; // Nodep can be null for a missing HTML table column - if (Nodep) { - if (!WideCharToMultiByte(CP_UTF8, 0, Nodep->text, -1, + if (Nodep) { + if (Zip) { + strcpy(buf, Nodep->text); + } else if (!WideCharToMultiByte(CP_UTF8, 0, Nodep->text, -1, buf, len, NULL, NULL)) { DWORD lsr = GetLastError(); diff --git a/storage/connect/domdoc.h b/storage/connect/domdoc.h index cfec98a9422..7f269002d59 100644 --- a/storage/connect/domdoc.h +++ b/storage/connect/domdoc.h @@ -93,6 +93,7 @@ class DOMNODE : public XMLNODE { char Name[64]; WCHAR *Ws; int Len; + bool Zip; }; // end of class DOMNODE /******************************************************************/ diff --git a/storage/connect/filamap.cpp b/storage/connect/filamap.cpp index 94c562a9981..8fffaca3d06 100644 --- a/storage/connect/filamap.cpp +++ b/storage/connect/filamap.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -45,6 +45,7 @@ #include "maputil.h" #include "filamap.h" #include "tabdos.h" +#include "tabfmt.h" /* --------------------------- Class MAPFAM -------------------------- */ @@ -322,17 +323,20 @@ int MAPFAM::ReadBuffer(PGLOBAL g) int rc, len; // Are we at the end of the memory - if (Mempos >= Top) + if (Mempos >= Top) { if ((rc = GetNext(g)) != RC_OK) return rc; + else if (Tdbp->GetAmType() == TYPE_AM_CSV && ((PTDBCSV)Tdbp)->Header) + if ((rc = SkipRecord(g, true)) != RC_OK) + return rc; + + } // endif Mempos if (!Placed) { /*******************************************************************/ /* Record file position in case of UPDATE or DELETE. */ /*******************************************************************/ - int rc; - next: Fpos = Mempos; CurBlk = (int)Rows++; diff --git a/storage/connect/filamdbf.cpp b/storage/connect/filamdbf.cpp index 5e3dfd8fe60..55feaa02bc4 100644 --- a/storage/connect/filamdbf.cpp +++ b/storage/connect/filamdbf.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -281,15 +281,25 @@ PQRYRES DBFColumns(PGLOBAL g, char *dp, const char *fn, bool info) /************************************************************************/ switch (thisfield.Type) { case 'C': // Characters - case 'L': // Logical 'T' or 'F' - type = TYPE_STRING; + case 'L': // Logical 'T' or 'F' or space + type = TYPE_STRING; + break; + case 'M': // Memo a .DBT block number + case 'B': // Binary a .DBT block number + case 'G': // Ole a .DBT block number + type = TYPE_STRING; break; + //case 'I': // Long + //case '+': // Autoincrement + // type = TYPE_INT; + // break; case 'N': type = (thisfield.Decimals) ? TYPE_DOUBLE : (len > 10) ? TYPE_BIGINT : TYPE_INT; break; - case 'F': - type = TYPE_DOUBLE; + case 'F': // Float + //case 'O': // Double + type = TYPE_DOUBLE; break; case 'D': type = TYPE_DATE; // Is this correct ??? @@ -441,6 +451,7 @@ int DBFFAM::Cardinality(PGLOBAL g) if (Accept) { Lrecl = rln; + Blksize = Nrec * rln; PushWarning(g, Tdbp); } else return -1; @@ -582,6 +593,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) if (Accept) { Lrecl = reclen; + Blksize = Nrec * Lrecl; PushWarning(g, Tdbp); } else return true; @@ -598,7 +610,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) header->Filedate[1] = datm->tm_mon + 1; header->Filedate[2] = datm->tm_mday; header->SetHeadlen((ushort)hlen); - header->SetReclen((ushort)reclen); + header->SetReclen(reclen); descp = (DESCRIPTOR*)header; // Currently only standard Xbase types are supported @@ -664,6 +676,7 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g) if (Accept) { Lrecl = header.Reclen(); + Blksize = Nrec * Lrecl; PushWarning(g, Tdbp); } else return true; @@ -956,6 +969,7 @@ int DBMFAM::Cardinality(PGLOBAL g) if (Accept) { Lrecl = rln; + Blksize = Nrec * Lrecl; PushWarning(g, Tdbp); } else return -1; @@ -1008,6 +1022,7 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g) if (Accept) { Lrecl = hp->Reclen(); + Blksize = Nrec * Lrecl; PushWarning(g, Tdbp); } else return true; diff --git a/storage/connect/filamgz.cpp b/storage/connect/filamgz.cpp index 07242ea633c..dc6f277ee27 100644 --- a/storage/connect/filamgz.cpp +++ b/storage/connect/filamgz.cpp @@ -724,20 +724,20 @@ void ZBKFAM::Rewind(void) /***********************************************************************/ /* Constructors. */ /***********************************************************************/ -ZIXFAM::ZIXFAM(PDOSDEF tdp) : ZBKFAM(tdp) +GZXFAM::GZXFAM(PDOSDEF tdp) : ZBKFAM(tdp) { //Block = tdp->GetBlock(); //Last = tdp->GetLast(); Nrec = (tdp->GetElemt()) ? tdp->GetElemt() : DOS_BUFF_LEN; Blksize = Nrec * Lrecl; - } // end of ZIXFAM standard constructor + } // end of GZXFAM standard constructor /***********************************************************************/ /* ZIX Cardinality: returns table cardinality in number of rows. */ /* This function can be called with a null argument to test the */ /* availability of Cardinality implementation (1 yes, 0 no). */ /***********************************************************************/ -int ZIXFAM::Cardinality(PGLOBAL g) +int GZXFAM::Cardinality(PGLOBAL g) { if (Last) return (g) ? (int)((Block - 1) * Nrec + Last) : 1; @@ -750,7 +750,7 @@ int ZIXFAM::Cardinality(PGLOBAL g) /* Allocate the line buffer. For mode Delete a bigger buffer has to */ /* be allocated because is it also used to move lines into the file. */ /***********************************************************************/ -bool ZIXFAM::AllocateBuffer(PGLOBAL g) +bool GZXFAM::AllocateBuffer(PGLOBAL g) { Buflen = Blksize; To_Buf = (char*)PlugSubAlloc(g, NULL, Buflen); @@ -788,7 +788,7 @@ bool ZIXFAM::AllocateBuffer(PGLOBAL g) /***********************************************************************/ /* ReadBuffer: Read one line from a compressed text file. */ /***********************************************************************/ -int ZIXFAM::ReadBuffer(PGLOBAL g) +int GZXFAM::ReadBuffer(PGLOBAL g) { int n, rc = RC_OK; @@ -850,7 +850,7 @@ int ZIXFAM::ReadBuffer(PGLOBAL g) /* WriteDB: Data Base write routine for ZDOS access method. */ /* Update is not possible without using a temporary file (NIY). */ /***********************************************************************/ -int ZIXFAM::WriteBuffer(PGLOBAL g) +int GZXFAM::WriteBuffer(PGLOBAL g) { /*********************************************************************/ /* In Insert mode, blocs are added sequentialy to the file end. */ diff --git a/storage/connect/filamgz.h b/storage/connect/filamgz.h index d667fdddcc2..7a00c0d4bc7 100644 --- a/storage/connect/filamgz.h +++ b/storage/connect/filamgz.h @@ -12,7 +12,7 @@ typedef class GZFAM *PGZFAM; typedef class ZBKFAM *PZBKFAM; -typedef class ZIXFAM *PZIXFAM; +typedef class GZXFAM *PZIXFAM; typedef class ZLBFAM *PZLBFAM; /***********************************************************************/ @@ -101,16 +101,16 @@ class DllExport ZBKFAM : public GZFAM { /* length files compressed using the gzip library functions. */ /* The file is always accessed by block. */ /***********************************************************************/ -class DllExport ZIXFAM : public ZBKFAM { +class DllExport GZXFAM : public ZBKFAM { public: // Constructor - ZIXFAM(PDOSDEF tdp); - ZIXFAM(PZIXFAM txfp) : ZBKFAM(txfp) {} + GZXFAM(PDOSDEF tdp); + GZXFAM(PZIXFAM txfp) : ZBKFAM(txfp) {} // Implementation virtual int GetNextPos(void) {return 0;} virtual PTXF Duplicate(PGLOBAL g) - {return (PTXF)new(g) ZIXFAM(this);} + {return (PTXF)new(g) GZXFAM(this);} // Methods virtual int Cardinality(PGLOBAL g); @@ -120,7 +120,7 @@ class DllExport ZIXFAM : public ZBKFAM { protected: // No additional Members - }; // end of class ZIXFAM + }; // end of class GZXFAM /***********************************************************************/ /* This is the DOS/UNIX Access Method class declaration for PlugDB */ diff --git a/storage/connect/filamzip.cpp b/storage/connect/filamzip.cpp index 6aca4631f32..3d157da5e87 100644 --- a/storage/connect/filamzip.cpp +++ b/storage/connect/filamzip.cpp @@ -1,11 +1,11 @@ /*********** File AM Zip C++ Program Source Code File (.CPP) ***********/ /* PROGRAM NAME: FILAMZIP */ /* ------------- */ -/* Version 1.0 */ +/* Version 1.1 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -19,13 +19,16 @@ #include "my_global.h" #if !defined(__WIN__) #if defined(UNIX) +#include <fnmatch.h> #include <errno.h> +#include <dirent.h> #include <unistd.h> #else // !UNIX #include <io.h> #endif // !UNIX #include <fcntl.h> #endif // !__WIN__ +#include <time.h> /***********************************************************************/ /* Include application header files: */ @@ -40,12 +43,346 @@ //#include "tabzip.h" #include "filamzip.h" +#define WRITEBUFFERSIZE (16384) + +bool ZipLoadFile(PGLOBAL g, char *zfn, char *fn, char *entry, bool append, bool mul); + +/***********************************************************************/ +/* Compress a file in zip when creating a table. */ +/***********************************************************************/ +static bool ZipFile(PGLOBAL g, ZIPUTIL *zutp, char *fn, char *entry, char *buf) +{ + int rc = RC_OK, size_read, size_buf = WRITEBUFFERSIZE; + FILE *fin; + + if (zutp->addEntry(g, entry)) + return true; + else if (!(fin = fopen(fn, "rb"))) { + sprintf(g->Message, "error in opening %s for reading", fn); + return true; + } // endif fin + + do { + size_read = (int)fread(buf, 1, size_buf, fin); + + if (size_read < size_buf && feof(fin) == 0) { + sprintf(g->Message, "error in reading %s", fn); + rc = RC_FX; + } // endif size_read + + if (size_read > 0) { + rc = zutp->writeEntry(g, buf, size_read); + + if (rc == RC_FX) + sprintf(g->Message, "error in writing %s in the zipfile", fn); + + } // endif size_read + + } while (rc == RC_OK && size_read > 0); + + fclose(fin); + zutp->closeEntry(); + return rc != RC_OK; +} // end of ZipFile + +/***********************************************************************/ +/* Find and Compress several files in zip when creating a table. */ +/***********************************************************************/ +static bool ZipFiles(PGLOBAL g, ZIPUTIL *zutp, char *pat, char *buf) +{ + char filename[_MAX_PATH]; + int rc; + + /*********************************************************************/ + /* pat is a multiple file name with wildcard characters */ + /*********************************************************************/ + strcpy(filename, pat); + +#if defined(__WIN__) + char drive[_MAX_DRIVE], direc[_MAX_DIR]; + WIN32_FIND_DATA FileData; + HANDLE hSearch; + + _splitpath(filename, drive, direc, NULL, NULL); + + // Start searching files in the target directory. + hSearch = FindFirstFile(filename, &FileData); + + if (hSearch == INVALID_HANDLE_VALUE) { + rc = GetLastError(); + + if (rc != ERROR_FILE_NOT_FOUND) { + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), 0, (LPTSTR)&filename, sizeof(filename), NULL); + sprintf(g->Message, MSG(BAD_FILE_HANDLE), filename); + return true; + } else { + strcpy(g->Message, "Cannot find any file to load"); + return true; + } // endif rc + + } // endif hSearch + + while (true) { + if (!(FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + strcat(strcat(strcpy(filename, drive), direc), FileData.cFileName); + + if (ZipFile(g, zutp, filename, FileData.cFileName, buf)) { + FindClose(hSearch); + return true; + } // endif ZipFile + + } // endif dwFileAttributes + + if (!FindNextFile(hSearch, &FileData)) { + rc = GetLastError(); + + if (rc != ERROR_NO_MORE_FILES) { + sprintf(g->Message, MSG(NEXT_FILE_ERROR), rc); + FindClose(hSearch); + return true; + } // endif rc + + break; + } // endif FindNextFile + + } // endwhile n + + // Close the search handle. + if (!FindClose(hSearch)) { + strcpy(g->Message, MSG(SRCH_CLOSE_ERR)); + return true; + } // endif FindClose + +#else // !__WIN__ + struct stat fileinfo; + char fn[FN_REFLEN], direc[FN_REFLEN], pattern[FN_HEADLEN], ftype[FN_EXTLEN]; + DIR *dir; + struct dirent *entry; + + _splitpath(filename, NULL, direc, pattern, ftype); + strcat(pattern, ftype); + + // Start searching files in the target directory. + if (!(dir = opendir(direc))) { + sprintf(g->Message, MSG(BAD_DIRECTORY), direc, strerror(errno)); + return true; + } // endif dir + + while ((entry = readdir(dir))) { + strcat(strcpy(fn, direc), entry->d_name); + + if (lstat(fn, &fileinfo) < 0) { + sprintf(g->Message, "%s: %s", fn, strerror(errno)); + return true; + } else if (!S_ISREG(fileinfo.st_mode)) + continue; // Not a regular file (should test for links) + + /*******************************************************************/ + /* Test whether the file name matches the table name filter. */ + /*******************************************************************/ + if (fnmatch(pattern, entry->d_name, 0)) + continue; // Not a match + + strcat(strcpy(filename, direc), entry->d_name); + + if (ZipFile(g, zutp, filename, entry->d_name, buf)) { + closedir(dir); + return true; + } // endif ZipFile + + } // endwhile readdir + + // Close the dir handle. + closedir(dir); +#endif // !__WIN__ + + return false; +} // end of ZipFiles + +/***********************************************************************/ +/* Load and Compress a file in zip when creating a table. */ +/***********************************************************************/ +bool ZipLoadFile(PGLOBAL g, char *zfn, char *fn, char *entry, bool append, bool mul) +{ + char *buf; + bool err; + ZIPUTIL *zutp = new(g) ZIPUTIL(NULL); + + if (zutp->open(g, zfn, append)) + return true; + + buf = (char*)PlugSubAlloc(g, NULL, WRITEBUFFERSIZE); + + if (mul) + err = ZipFiles(g, zutp, fn, buf); + else + err = ZipFile(g, zutp, fn, entry, buf); + + zutp->close(); + return err; +} // end of ZipLoadFile + /* -------------------------- class ZIPUTIL -------------------------- */ /***********************************************************************/ /* Constructors. */ /***********************************************************************/ -ZIPUTIL::ZIPUTIL(PSZ tgt, bool mul) +ZIPUTIL::ZIPUTIL(PSZ tgt) +{ + zipfile = NULL; + target = tgt; + fp = NULL; + entryopen = false; +} // end of ZIPUTIL standard constructor + +#if 0 +ZIPUTIL::ZIPUTIL(ZIPUTIL *zutp) +{ + zipfile = zutp->zipfile; + target = zutp->target; + fp = zutp->fp; + entryopen = zutp->entryopen; +} // end of UNZIPUTL copy constructor +#endif // 0 + +/***********************************************************************/ +/* Fill the zip time structure */ +/* param: tmZip time structure to be filled */ +/***********************************************************************/ +void ZIPUTIL::getTime(tm_zip& tmZip) +{ + time_t rawtime; + time(&rawtime); + struct tm *timeinfo = localtime(&rawtime); + tmZip.tm_sec = timeinfo->tm_sec; + tmZip.tm_min = timeinfo->tm_min; + tmZip.tm_hour = timeinfo->tm_hour; + tmZip.tm_mday = timeinfo->tm_mday; + tmZip.tm_mon = timeinfo->tm_mon; + tmZip.tm_year = timeinfo->tm_year; +} // end of getTime + +/***********************************************************************/ +/* open a zip file for deflate. */ +/* param: filename path and the filename of the zip file to open. */ +/* append: set true to append the zip file */ +/* return: true if open, false otherwise. */ +/***********************************************************************/ +bool ZIPUTIL::open(PGLOBAL g, char *filename, bool append) +{ + if (!zipfile && !(zipfile = zipOpen64(filename, + append ? APPEND_STATUS_ADDINZIP + : APPEND_STATUS_CREATE))) + sprintf(g->Message, "Zipfile open error on %s", filename); + + return (zipfile == NULL); +} // end of open + +/***********************************************************************/ +/* Close the zip file. */ +/***********************************************************************/ +void ZIPUTIL::close() +{ + if (zipfile) { + closeEntry(); + zipClose(zipfile, 0); + zipfile = NULL; + } // endif zipfile + +} // end of close + +/***********************************************************************/ +/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ +/***********************************************************************/ +bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn, bool append) +{ + /*********************************************************************/ + /* The file will be compressed. */ + /*********************************************************************/ + if (mode == MODE_INSERT) { + bool b = open(g, fn, append); + + if (!b) { + if (addEntry(g, target)) + return true; + + /*****************************************************************/ + /* Link a Fblock. This make possible to automatically close it */ + /* in case of error g->jump. */ + /*****************************************************************/ + PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr; + + fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK)); + fp->Type = TYPE_FB_ZIP; + fp->Fname = PlugDup(g, fn); + fp->Next = dbuserp->Openlist; + dbuserp->Openlist = fp; + fp->Count = 1; + fp->Length = 0; + fp->Memory = NULL; + fp->Mode = mode; + fp->File = this; + fp->Handle = 0; + } else + return true; + + } else { + strcpy(g->Message, "Only INSERT mode supported for ZIPPING files"); + return true; + } // endif mode + + return false; +} // end of OpenTableFile + +/***********************************************************************/ +/* Add target in zip file. */ +/***********************************************************************/ +bool ZIPUTIL::addEntry(PGLOBAL g, char *entry) +{ + //?? we dont need the stinking time + zip_fileinfo zi = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + getTime(zi.tmz_date); + target = entry; + + int err = zipOpenNewFileInZip(zipfile, target, &zi, + NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); + + return !(entryopen = (err == ZIP_OK)); +} // end of addEntry + +/***********************************************************************/ +/* writeEntry: Deflate the buffer to the zip file. */ +/***********************************************************************/ +int ZIPUTIL::writeEntry(PGLOBAL g, char *buf, int len) +{ + if (zipWriteInFileInZip(zipfile, buf, len) < 0) { + sprintf(g->Message, "Error writing %s in the zipfile", target); + return RC_FX; + } // endif zipWriteInFileInZip + + return RC_OK; +} // end of writeEntry + +/***********************************************************************/ +/* Close the zip file. */ +/***********************************************************************/ +void ZIPUTIL::closeEntry() +{ + if (entryopen) { + zipCloseFileInZip(zipfile); + entryopen = false; + } // endif entryopen + +} // end of closeEntry + +/* ------------------------- class UNZIPUTL -------------------------- */ + +/***********************************************************************/ +/* Constructors. */ +/***********************************************************************/ +UNZIPUTL::UNZIPUTL(PSZ tgt, bool mul) { zipfile = NULL; target = tgt; @@ -62,10 +399,10 @@ ZIPUTIL::ZIPUTIL(PSZ tgt, bool mul) #else for (int i = 0; i < 256; ++i) mapCaseTable[i] = i; #endif -} // end of ZIPUTIL standard constructor +} // end of UNZIPUTL standard constructor #if 0 -ZIPUTIL::ZIPUTIL(PZIPUTIL zutp) +UNZIPUTL::UNZIPUTL(PZIPUTIL zutp) { zipfile = zutp->zipfile; target = zutp->target; @@ -74,14 +411,14 @@ ZIPUTIL::ZIPUTIL(PZIPUTIL zutp) entryopen = zutp->entryopen; multiple = zutp->multiple; for (int i = 0; i < 256; ++i) mapCaseTable[i] = zutp->mapCaseTable[i]; -} // end of ZIPUTIL copy constructor +} // end of UNZIPUTL copy constructor #endif // 0 /***********************************************************************/ /* This code is the copyright property of Alessandro Felice Cantatore. */ /* http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html */ /***********************************************************************/ -bool ZIPUTIL::WildMatch(PSZ pat, PSZ str) { +bool UNZIPUTL::WildMatch(PSZ pat, PSZ str) { PSZ s, p; bool star = FALSE; @@ -116,7 +453,7 @@ starCheck: /* param: filename path and the filename of the zip file to open. */ /* return: true if open, false otherwise. */ /***********************************************************************/ -bool ZIPUTIL::open(PGLOBAL g, char *filename) +bool UNZIPUTL::open(PGLOBAL g, char *filename) { if (!zipfile && !(zipfile = unzOpen64(filename))) sprintf(g->Message, "Zipfile open error on %s", filename); @@ -127,7 +464,7 @@ bool ZIPUTIL::open(PGLOBAL g, char *filename) /***********************************************************************/ /* Close the zip file. */ /***********************************************************************/ -void ZIPUTIL::close() +void UNZIPUTL::close() { if (zipfile) { closeEntry(); @@ -140,7 +477,7 @@ void ZIPUTIL::close() /***********************************************************************/ /* Find next entry matching target pattern. */ /***********************************************************************/ -int ZIPUTIL::findEntry(PGLOBAL g, bool next) +int UNZIPUTL::findEntry(PGLOBAL g, bool next) { int rc; @@ -183,7 +520,7 @@ int ZIPUTIL::findEntry(PGLOBAL g, bool next) /***********************************************************************/ /* Get the next used entry. */ /***********************************************************************/ -int ZIPUTIL::nextEntry(PGLOBAL g) +int UNZIPUTL::nextEntry(PGLOBAL g) { if (multiple) { int rc; @@ -206,7 +543,7 @@ int ZIPUTIL::nextEntry(PGLOBAL g) /***********************************************************************/ /* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ /***********************************************************************/ -bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn) +bool UNZIPUTL::OpenTable(PGLOBAL g, MODE mode, char *fn) { /*********************************************************************/ /* The file will be decompressed into virtual memory. */ @@ -268,7 +605,7 @@ bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn) return true; } else { - strcpy(g->Message, "Only READ mode supported for ZIP files"); + strcpy(g->Message, "Only READ mode supported for ZIPPED tables"); return true; } // endif mode @@ -278,7 +615,7 @@ bool ZIPUTIL::OpenTable(PGLOBAL g, MODE mode, char *fn) /***********************************************************************/ /* Open target in zip file. */ /***********************************************************************/ -bool ZIPUTIL::openEntry(PGLOBAL g) +bool UNZIPUTL::openEntry(PGLOBAL g) { int rc; @@ -316,7 +653,7 @@ bool ZIPUTIL::openEntry(PGLOBAL g) /***********************************************************************/ /* Close the zip file. */ /***********************************************************************/ -void ZIPUTIL::closeEntry() +void UNZIPUTL::closeEntry() { if (entryopen) { unzCloseCurrentFile(zipfile); @@ -330,36 +667,29 @@ void ZIPUTIL::closeEntry() } // end of closeEntry -/* -------------------------- class ZIPFAM --------------------------- */ +/* -------------------------- class UNZFAM --------------------------- */ /***********************************************************************/ /* Constructors. */ /***********************************************************************/ -ZIPFAM::ZIPFAM(PDOSDEF tdp) : MAPFAM(tdp) +UNZFAM::UNZFAM(PDOSDEF tdp) : MAPFAM(tdp) { zutp = NULL; target = tdp->GetEntry(); mul = tdp->GetMul(); -} // end of ZIPFAM standard constructor - -ZIPFAM::ZIPFAM(PZIPFAM txfp) : MAPFAM(txfp) -{ - zutp = txfp->zutp; - target = txfp->target; - mul = txfp->mul; -} // end of ZIPFAM copy constructor +} // end of UNZFAM standard constructor -ZIPFAM::ZIPFAM(PDOSDEF tdp, PZPXFAM txfp) : MAPFAM(tdp) +UNZFAM::UNZFAM(PUNZFAM txfp) : MAPFAM(txfp) { zutp = txfp->zutp; target = txfp->target; mul = txfp->mul; -} // end of ZIPFAM constructor used in ResetTableOpt +} // end of UNZFAM copy constructor /***********************************************************************/ /* ZIP GetFileLength: returns file size in number of bytes. */ /***********************************************************************/ -int ZIPFAM::GetFileLength(PGLOBAL g) +int UNZFAM::GetFileLength(PGLOBAL g) { int len = (zutp && zutp->entryopen) ? Top - Memory : TXTFAM::GetFileLength(g) * 3; @@ -373,7 +703,7 @@ int ZIPFAM::GetFileLength(PGLOBAL g) /***********************************************************************/ /* ZIP Cardinality: return the number of rows if possible. */ /***********************************************************************/ -int ZIPFAM::Cardinality(PGLOBAL g) +int UNZFAM::Cardinality(PGLOBAL g) { if (!g) return 1; @@ -388,7 +718,7 @@ int ZIPFAM::Cardinality(PGLOBAL g) /***********************************************************************/ /* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ /***********************************************************************/ -bool ZIPFAM::OpenTableFile(PGLOBAL g) +bool UNZFAM::OpenTableFile(PGLOBAL g) { char filename[_MAX_PATH]; MODE mode = Tdbp->GetMode(); @@ -396,7 +726,7 @@ bool ZIPFAM::OpenTableFile(PGLOBAL g) /*********************************************************************/ /* Allocate the ZIP utility class. */ /*********************************************************************/ - zutp = new(g) ZIPUTIL(target, mul); + zutp = new(g) UNZIPUTL(target, mul); // We used the file name relative to recorded datapath PlugSetPath(filename, To_File, Tdbp->GetPath()); @@ -415,7 +745,7 @@ bool ZIPFAM::OpenTableFile(PGLOBAL g) /***********************************************************************/ /* GetNext: go to next entry. */ /***********************************************************************/ -int ZIPFAM::GetNext(PGLOBAL g) +int UNZFAM::GetNext(PGLOBAL g) { int rc = zutp->nextEntry(g); @@ -431,7 +761,7 @@ int ZIPFAM::GetNext(PGLOBAL g) /***********************************************************************/ /* ReadBuffer: Read one line for a ZIP file. */ /***********************************************************************/ -int ZIPFAM::ReadBuffer(PGLOBAL g) +int UNZFAM::ReadBuffer(PGLOBAL g) { int rc, len; @@ -497,37 +827,37 @@ int ZIPFAM::ReadBuffer(PGLOBAL g) /***********************************************************************/ /* Table file close routine for MAP access method. */ /***********************************************************************/ -void ZIPFAM::CloseTableFile(PGLOBAL g, bool) +void UNZFAM::CloseTableFile(PGLOBAL g, bool) { close(); } // end of CloseTableFile #endif // 0 -/* -------------------------- class ZPXFAM --------------------------- */ +/* -------------------------- class UZXFAM --------------------------- */ /***********************************************************************/ /* Constructors. */ /***********************************************************************/ -ZPXFAM::ZPXFAM(PDOSDEF tdp) : MPXFAM(tdp) +UZXFAM::UZXFAM(PDOSDEF tdp) : MPXFAM(tdp) { zutp = NULL; target = tdp->GetEntry(); mul = tdp->GetMul(); //Lrecl = tdp->GetLrecl(); -} // end of ZPXFAM standard constructor +} // end of UZXFAM standard constructor -ZPXFAM::ZPXFAM(PZPXFAM txfp) : MPXFAM(txfp) +UZXFAM::UZXFAM(PUZXFAM txfp) : MPXFAM(txfp) { zutp = txfp->zutp; target = txfp->target; mul = txfp->mul; //Lrecl = txfp->Lrecl; -} // end of ZPXFAM copy constructor +} // end of UZXFAM copy constructor /***********************************************************************/ /* ZIP GetFileLength: returns file size in number of bytes. */ /***********************************************************************/ -int ZPXFAM::GetFileLength(PGLOBAL g) +int UZXFAM::GetFileLength(PGLOBAL g) { int len; @@ -545,7 +875,7 @@ int ZPXFAM::GetFileLength(PGLOBAL g) /***********************************************************************/ /* ZIP Cardinality: return the number of rows if possible. */ /***********************************************************************/ -int ZPXFAM::Cardinality(PGLOBAL g) +int UZXFAM::Cardinality(PGLOBAL g) { if (!g) return 1; @@ -566,7 +896,7 @@ int ZPXFAM::Cardinality(PGLOBAL g) /***********************************************************************/ /* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ /***********************************************************************/ -bool ZPXFAM::OpenTableFile(PGLOBAL g) +bool UZXFAM::OpenTableFile(PGLOBAL g) { // May have been already opened in GetFileLength if (!zutp || !zutp->zipfile) { @@ -577,7 +907,7 @@ bool ZPXFAM::OpenTableFile(PGLOBAL g) /* Allocate the ZIP utility class. */ /*********************************************************************/ if (!zutp) - zutp = new(g)ZIPUTIL(target, mul); + zutp = new(g)UNZIPUTL(target, mul); // We used the file name relative to recorded datapath PlugSetPath(filename, To_File, Tdbp->GetPath()); @@ -600,7 +930,7 @@ bool ZPXFAM::OpenTableFile(PGLOBAL g) /***********************************************************************/ /* GetNext: go to next entry. */ /***********************************************************************/ -int ZPXFAM::GetNext(PGLOBAL g) +int UZXFAM::GetNext(PGLOBAL g) { int rc = zutp->nextEntry(g); @@ -620,3 +950,146 @@ int ZPXFAM::GetNext(PGLOBAL g) return RC_OK; } // end of GetNext +/* -------------------------- class ZIPFAM --------------------------- */ + +/***********************************************************************/ +/* Constructor. */ +/***********************************************************************/ +ZIPFAM::ZIPFAM(PDOSDEF tdp) : DOSFAM(tdp) +{ + zutp = NULL; + target = tdp->GetEntry(); + append = tdp->GetAppend(); +} // end of ZIPFAM standard constructor + +/***********************************************************************/ +/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ +/***********************************************************************/ +bool ZIPFAM::OpenTableFile(PGLOBAL g) +{ + char filename[_MAX_PATH]; + MODE mode = Tdbp->GetMode(); + + /*********************************************************************/ + /* Allocate the ZIP utility class. */ + /*********************************************************************/ + zutp = new(g) ZIPUTIL(target); + + // We used the file name relative to recorded datapath + PlugSetPath(filename, To_File, Tdbp->GetPath()); + + if (!zutp->OpenTable(g, mode, filename, append)) { + To_Fb = zutp->fp; // Useful when closing + } else + return true; + + return AllocateBuffer(g); +} // end of OpenTableFile + +/***********************************************************************/ +/* ReadBuffer: Read one line for a ZIP file. */ +/***********************************************************************/ +int ZIPFAM::ReadBuffer(PGLOBAL g) +{ + strcpy(g->Message, "ReadBuffer should not been called when zipping"); + return RC_FX; +} // end of ReadBuffer + +/***********************************************************************/ +/* WriteBuffer: Deflate the buffer to the zip file. */ +/***********************************************************************/ +int ZIPFAM::WriteBuffer(PGLOBAL g) +{ + int len; + + // Prepare to write the new line + strcat(strcpy(To_Buf, Tdbp->GetLine()), (Bin) ? CrLf : "\n"); + len = strchr(To_Buf, '\n') - To_Buf + 1; + return zutp->writeEntry(g, To_Buf, len); +} // end of WriteBuffer + +/***********************************************************************/ +/* Table file close routine for ZIP access method. */ +/***********************************************************************/ +void ZIPFAM::CloseTableFile(PGLOBAL g, bool) +{ + To_Fb->Count = 0; + zutp->close(); +} // end of CloseTableFile + +/* -------------------------- class ZPXFAM --------------------------- */ + +/***********************************************************************/ +/* Constructor. */ +/***********************************************************************/ +ZPXFAM::ZPXFAM(PDOSDEF tdp) : FIXFAM(tdp) +{ + zutp = NULL; + target = tdp->GetEntry(); + append = tdp->GetAppend(); + //Lrecl = tdp->GetLrecl(); +} // end of UZXFAM standard constructor + +/***********************************************************************/ +/* OpenTableFile: Open a DOS/UNIX table file from a ZIP file. */ +/***********************************************************************/ +bool ZPXFAM::OpenTableFile(PGLOBAL g) +{ + char filename[_MAX_PATH]; + MODE mode = Tdbp->GetMode(); + + /*********************************************************************/ + /* Allocate the ZIP utility class. */ + /*********************************************************************/ + zutp = new(g) ZIPUTIL(target); + + // We used the file name relative to recorded datapath + PlugSetPath(filename, To_File, Tdbp->GetPath()); + + if (!zutp->OpenTable(g, mode, filename, append)) { + To_Fb = zutp->fp; // Useful when closing + } else + return true; + + return AllocateBuffer(g); +} // end of OpenTableFile + +/***********************************************************************/ +/* WriteBuffer: Deflate the buffer to the zip file. */ +/***********************************************************************/ +int ZPXFAM::WriteBuffer(PGLOBAL g) +{ + /*********************************************************************/ + /* In Insert mode, we write only full blocks. */ + /*********************************************************************/ + if (++CurNum != Rbuf) { + Tdbp->IncLine(Lrecl); // Used by DOSCOL functions + return RC_OK; + } // endif CurNum + + // Now start the compress process. + if (zutp->writeEntry(g, To_Buf, Lrecl * Rbuf) != RC_OK) { + Closing = true; + return RC_FX; + } // endif writeEntry + + CurBlk++; + CurNum = 0; + Tdbp->SetLine(To_Buf); + return RC_OK; +} // end of WriteBuffer + +/***********************************************************************/ +/* Table file close routine for ZIP access method. */ +/***********************************************************************/ +void ZPXFAM::CloseTableFile(PGLOBAL g, bool) +{ + if (CurNum && !Closing) { + // Some more inserted lines remain to be written + Rbuf = CurNum--; + WriteBuffer(g); + } // endif Curnum + + To_Fb->Count = 0; + zutp->close(); +} // end of CloseTableFile diff --git a/storage/connect/filamzip.h b/storage/connect/filamzip.h index 9312fb2f70e..3160703bd20 100644 --- a/storage/connect/filamzip.h +++ b/storage/connect/filamzip.h @@ -1,7 +1,7 @@ /************** filamzip H Declares Source Code File (.H) **************/ -/* Name: filamzip.h Version 1.0 */ +/* Name: filamzip.h Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ /* */ /* This file contains the ZIP file access method classes declares. */ /***********************************************************************/ @@ -10,10 +10,14 @@ #include "block.h" #include "filamap.h" +#include "filamfix.h" +#include "zip.h" #include "unzip.h" #define DLLEXPORT extern "C" +typedef class UNZFAM *PUNZFAM; +typedef class UZXFAM *PUZXFAM; typedef class ZIPFAM *PZIPFAM; typedef class ZPXFAM *PZPXFAM; @@ -21,16 +25,50 @@ typedef class ZPXFAM *PZPXFAM; /* This is the ZIP utility fonctions class. */ /***********************************************************************/ class DllExport ZIPUTIL : public BLOCK { -public: + public: // Constructor - ZIPUTIL(PSZ tgt, bool mul); -//ZIPUTIL(ZIPUTIL *zutp); + ZIPUTIL(PSZ tgt); + //ZIPUTIL(ZIPUTIL *zutp); // Implementation -//PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZIPFAM(this); } + //PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)UNZFAM(this); } // Methods - virtual bool OpenTable(PGLOBAL g, MODE mode, char *fn); + bool OpenTable(PGLOBAL g, MODE mode, char *fn, bool append); + bool open(PGLOBAL g, char *fn, bool append); + bool addEntry(PGLOBAL g, char *entry); + void close(void); + void closeEntry(void); + int writeEntry(PGLOBAL g, char *buf, int len); + void getTime(tm_zip& tmZip); + + // Members + zipFile zipfile; // The ZIP container file + PSZ target; // The target file name +//unz_file_info finfo; // The current file info + PFBLOCK fp; +//char *memory; +//uint size; +//int multiple; // Multiple targets + bool entryopen; // True when open current entry +//char fn[FILENAME_MAX]; // The current entry file name +//char mapCaseTable[256]; +}; // end of ZIPUTIL + +/***********************************************************************/ +/* This is the unZIP utility fonctions class. */ +/***********************************************************************/ +class DllExport UNZIPUTL : public BLOCK { + public: + // Constructor + UNZIPUTL(PSZ tgt, bool mul); +//UNZIPUTL(UNZIPUTL *zutp); + + // Implementation +//PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)UNZFAM(this); } + + // Methods + bool OpenTable(PGLOBAL g, MODE mode, char *fn); bool open(PGLOBAL g, char *fn); bool openEntry(PGLOBAL g); void close(void); @@ -50,68 +88,120 @@ public: bool entryopen; // True when open current entry char fn[FILENAME_MAX]; // The current entry file name char mapCaseTable[256]; -}; // end of ZIPFAM +}; // end of UNZIPUTL /***********************************************************************/ -/* This is the ZIP file access method. */ +/* This is the unzip file access method. */ /***********************************************************************/ -class DllExport ZIPFAM : public MAPFAM { - friend class ZPXFAM; -public: +class DllExport UNZFAM : public MAPFAM { +//friend class UZXFAM; + public: // Constructors - ZIPFAM(PDOSDEF tdp); - ZIPFAM(PZIPFAM txfp); - ZIPFAM(PDOSDEF tdp, PZPXFAM txfp); + UNZFAM(PDOSDEF tdp); + UNZFAM(PUNZFAM txfp); // Implementation - virtual AMT GetAmType(void) { return TYPE_AM_ZIP; } - virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZIPFAM(this); } + virtual AMT GetAmType(void) {return TYPE_AM_ZIP;} + virtual PTXF Duplicate(PGLOBAL g) {return (PTXF) new(g) UNZFAM(this);} // Methods virtual int Cardinality(PGLOBAL g); virtual int GetFileLength(PGLOBAL g); -//virtual int MaxBlkSize(PGLOBAL g, int s) {return s;} + //virtual int MaxBlkSize(PGLOBAL g, int s) {return s;} virtual bool OpenTableFile(PGLOBAL g); virtual bool DeferReading(void) { return false; } virtual int GetNext(PGLOBAL g); -//virtual int ReadBuffer(PGLOBAL g); -//virtual int WriteBuffer(PGLOBAL g); -//virtual int DeleteRecords(PGLOBAL g, int irc); -//virtual void CloseTableFile(PGLOBAL g, bool abort); + //virtual int ReadBuffer(PGLOBAL g); + //virtual int WriteBuffer(PGLOBAL g); + //virtual int DeleteRecords(PGLOBAL g, int irc); + //virtual void CloseTableFile(PGLOBAL g, bool abort); -protected: + protected: // Members - ZIPUTIL *zutp; - PSZ target; - bool mul; -}; // end of ZIPFAM + UNZIPUTL *zutp; + PSZ target; + bool mul; +}; // end of UNZFAM /***********************************************************************/ -/* This is the fixed ZIP file access method. */ +/* This is the fixed unzip file access method. */ /***********************************************************************/ -class DllExport ZPXFAM : public MPXFAM { - friend class ZIPFAM; -public: +class DllExport UZXFAM : public MPXFAM { +//friend class UNZFAM; + public: // Constructors - ZPXFAM(PDOSDEF tdp); - ZPXFAM(PZPXFAM txfp); + UZXFAM(PDOSDEF tdp); + UZXFAM(PUZXFAM txfp); // Implementation virtual AMT GetAmType(void) { return TYPE_AM_ZIP; } - virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)ZPXFAM(this); } + virtual PTXF Duplicate(PGLOBAL g) { return (PTXF) new(g)UZXFAM(this); } // Methods virtual int GetFileLength(PGLOBAL g); virtual int Cardinality(PGLOBAL g); virtual bool OpenTableFile(PGLOBAL g); virtual int GetNext(PGLOBAL g); -//virtual int ReadBuffer(PGLOBAL g); + //virtual int ReadBuffer(PGLOBAL g); + + protected: + // Members + UNZIPUTL *zutp; + PSZ target; + bool mul; +}; // end of UZXFAM + +/***********************************************************************/ +/* This is the zip file access method. */ +/***********************************************************************/ +class DllExport ZIPFAM : public DOSFAM { + public: + // Constructors + ZIPFAM(PDOSDEF tdp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_ZIP;} + + // Methods + virtual int Cardinality(PGLOBAL g) {return 0;} + virtual int GetFileLength(PGLOBAL g) {return g ? 0 : 1;} + //virtual int MaxBlkSize(PGLOBAL g, int s) {return s;} + virtual bool OpenTableFile(PGLOBAL g); + virtual int ReadBuffer(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + //virtual int DeleteRecords(PGLOBAL g, int irc); + virtual void CloseTableFile(PGLOBAL g, bool abort); + + protected: + // Members + ZIPUTIL *zutp; + PSZ target; + bool append; +}; // end of ZIPFAM + +/***********************************************************************/ +/* This is the fixed zip file access method. */ +/***********************************************************************/ +class DllExport ZPXFAM : public FIXFAM { + public: + // Constructors + ZPXFAM(PDOSDEF tdp); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_ZIP;} + + // Methods + virtual int Cardinality(PGLOBAL g) {return 0;} + virtual int GetFileLength(PGLOBAL g) {return g ? 0 : 1;} + virtual bool OpenTableFile(PGLOBAL g); + virtual int WriteBuffer(PGLOBAL g); + virtual void CloseTableFile(PGLOBAL g, bool abort); -protected: + protected: // Members ZIPUTIL *zutp; PSZ target; - bool mul; + bool append; }; // end of ZPXFAM #endif // __FILAMZIP_H diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index b542ca180c5..f2727ba15f7 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1,4 +1,4 @@ -/* Copyright (C) Olivier Bertrand 2004 - 2016 +/* Copyright (C) Olivier Bertrand 2004 - 2017 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file ha_connect.cc @@ -125,6 +125,8 @@ #endif // UNIX #include "global.h" #include "plgdbsem.h" +#include "xtable.h" +#include "tabext.h" #if defined(ODBC_SUPPORT) #include "odbccat.h" #endif // ODBC_SUPPORT @@ -132,12 +134,11 @@ #include "tabjdbc.h" #include "jdbconn.h" #endif // JDBC_SUPPORT -#include "xtable.h" #include "tabmysql.h" #include "filamdbf.h" #include "tabxcl.h" #include "tabfmt.h" -#include "reldef.h" +//#include "reldef.h" #include "tabcol.h" #include "xindex.h" #if defined(__WIN__) @@ -171,9 +172,9 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.05.0001 December 13, 2016"; + char version[]= "Version 1.05.0003 February 27, 2017"; #if defined(__WIN__) - char compver[]= "Version 1.05.0001 " __DATE__ " " __TIME__; + char compver[]= "Version 1.05.0003 " __DATE__ " " __TIME__; char slash= '\\'; #else // !__WIN__ char slash= '/'; @@ -214,6 +215,7 @@ int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v); void PushWarning(PGLOBAL g, THD *thd, int level); bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, const char *db, char *tab, const char *src, int port); +bool ZipLoadFile(PGLOBAL, char*, char*, char*, bool, bool); bool ExactInfo(void); USETEMP UseTemp(void); int GetConvSize(void); @@ -556,7 +558,7 @@ ha_create_table_option connect_index_option_list[]= /***********************************************************************/ /* Push G->Message as a MySQL warning. */ /***********************************************************************/ -bool PushWarning(PGLOBAL g, PTDBASE tdbp, int level) +bool PushWarning(PGLOBAL g, PTDB tdbp, int level) { PHC phc; THD *thd; @@ -1024,7 +1026,7 @@ char *GetListOption(PGLOBAL g, const char *opname, char key[16], val[256]; char *pk, *pv, *pn; - char *opval= (char*) def; + char *opval= (char*)def; int n; for (pk= (char*)oplist; pk; pk= ++pn) { @@ -1032,26 +1034,17 @@ char *GetListOption(PGLOBAL g, const char *opname, pv= strchr(pk, '='); if (pv && (!pn || pv < pn)) { - n= pv - pk; + n= MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1); memcpy(key, pk, n); key[n]= 0; pv++; - - if (pn) { - n= pn - pv; - memcpy(val, pv, n); - val[n]= 0; - } else - strcpy(val, pv); - + n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1); + memcpy(val, pv, n); + val[n]= 0; } else { - if (pn) { - n= MY_MIN(pn - pk, 15); - memcpy(key, pk, n); - key[n]= 0; - } else - strcpy(key, pk); - + n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1); + memcpy(key, pk, n); + key[n]= 0; val[0]= 0; } // endif pv @@ -1105,7 +1098,7 @@ char *GetStringTableOption(PGLOBAL g, PTOS options, char *opname, char *sdef) else if (!stricmp(opname, "Data_charset")) opval= options->data_charset; - if (!opval && options && options->oplist) + if (!opval && options->oplist) opval= GetListOption(g, opname, options->oplist); return opval ? (char*)opval : sdef; @@ -2113,7 +2106,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *) PCOL colp; PVAL value, sdvalin; Field *fp; - PTDBASE tp= (PTDBASE)tdbp; +//PTDBASE tp= (PTDBASE)tdbp; String attribute(attr_buffer, sizeof(attr_buffer), table->s->table_charset); my_bitmap_map *bmap= dbug_tmp_use_all_columns(table, table->read_set); @@ -2131,7 +2124,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *) && tdbp->GetAmType() != TYPE_AM_ODBC && tdbp->GetAmType() != TYPE_AM_JDBC) || bitmap_is_set(table->write_set, fp->field_index)) { - for (colp= tp->GetSetCols(); colp; colp= colp->GetNext()) + for (colp= tdbp->GetSetCols(); colp; colp= colp->GetNext()) if (!stricmp(colp->GetName(), fp->field_name)) break; @@ -2218,7 +2211,7 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *) } else if (xmod == MODE_UPDATE) { PCOL cp; - for (cp= tp->GetColumns(); cp; cp= cp->GetNext()) + for (cp= tdbp->GetColumns(); cp; cp= cp->GetNext()) if (!stricmp(colp->GetName(), cp->GetName())) break; @@ -2685,7 +2678,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) { AMT tty = filp->Type; char *body= filp->Body; - unsigned int i; + char *havg= filp->Having; + unsigned int i; bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC); bool nonul= ((tty == TYPE_AM_ODBC || tty == TYPE_AM_JDBC) && (tdbp->GetMode() == MODE_INSERT || tdbp->GetMode() == MODE_DELETE)); @@ -2698,7 +2692,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) htrc("Cond type=%d\n", cond->type()); if (cond->type() == COND::COND_ITEM) { - char *p1, *p2; + char *pb0, *pb1, *pb2, *ph0, *ph1, *ph2; + bool bb = false, bh = false; Item_cond *cond_item= (Item_cond *)cond; if (x) @@ -2718,38 +2713,78 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) List_iterator<Item> li(*arglist); const Item *subitem; - p1= body + strlen(body); - strcpy(p1, "("); - p2= p1 + 1; + pb0= pb1= body + strlen(body); + strcpy(pb0, "("); + pb2= pb1 + 1; + + if (havg) { + ph0= ph1= havg + strlen(havg); + strcpy(ph0, "("); + ph2= ph1 + 1; + } // endif havg for (i= 0; i < arglist->elements; i++) if ((subitem= li++)) { if (!CheckCond(g, filp, subitem)) { if (vop == OP_OR || nonul) return NULL; - else - *p2= 0; + else { + *pb2= 0; + if (havg) *ph2= 0; + } // endelse } else { - p1= p2 + strlen(p2); - strcpy(p1, GetValStr(vop, false)); - p2= p1 + strlen(p1); + if (filp->Bd) { + pb1= pb2 + strlen(pb2); + strcpy(pb1, GetValStr(vop, false)); + pb2= pb1 + strlen(pb1); + } // endif Bd + + if (filp->Hv) { + ph1= ph2 + strlen(ph2); + strcpy(ph1, GetValStr(vop, false)); + ph2= ph1 + strlen(ph1); + } // endif Hv + } // endif CheckCond + bb |= filp->Bd; + bh |= filp->Hv; + filp->Bd = filp->Hv = false; } else return NULL; - if (*p1 != '(') - strcpy(p1, ")"); - else - return NULL; + if (bb) { + strcpy(pb1, ")"); + filp->Bd = bb; + } else + *pb0= 0; + + if (havg) { + if (bb && bh && vop == OP_OR) { + // Cannot or'ed a where clause with a having clause + bb= bh= 0; + *pb0 = 0; + *ph0 = 0; + } else if (bh) { + strcpy(ph1, ")"); + filp->Hv= bh; + } else + *ph0 = 0; + + } // endif havg + + if (!bb && !bh) + return NULL; } else if (cond->type() == COND::FUNC_ITEM) { unsigned int i; - bool iscol, neg= FALSE; + bool iscol, ishav= false, neg= false; Item_func *condf= (Item_func *)cond; Item* *args= condf->arguments(); + filp->Bd = filp->Hv = false; + if (trace) htrc("Func type=%d argnum=%d\n", condf->functype(), condf->argument_count()); @@ -2798,8 +2833,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) ha_field_option_struct *fop; Item_field *pField= (Item_field *)args[i]; - if (x && i) - return NULL; + // IN and BETWEEN clauses should be col VOP list + if (i && (x || ismul)) + return NULL; // IN and BETWEEN clauses should be col VOP list else if (pField->field->table != table) return NULL; // Field does not belong to this table else if (tty != TYPE_AM_WMI && IsIndexed(pField->field)) @@ -2815,10 +2851,19 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) else return NULL; - } else if (tty == TYPE_AM_TBL) - return NULL; - else - fnm= pField->field->field_name; + } else if (tty == TYPE_AM_TBL) { + return NULL; + } else { + bool h; + + fnm = filp->Chk(pField->field->field_name, &h); + + if (h && i && !ishav) + return NULL; // Having should be col VOP arg + else + ishav = h; + + } // endif's if (trace) { htrc("Field index=%d\n", pField->field->field_index); @@ -2827,11 +2872,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) htrc("Field_type=%d\n", args[i]->field_type()); } // endif trace - // IN and BETWEEN clauses should be col VOP list - if (i && ismul) - return NULL; - - strcat(body, fnm); + strcat((ishav ? havg : body), fnm); } else if (args[i]->type() == COND::FUNC_ITEM) { if (tty == TYPE_AM_MYSQL) { if (!CheckCond(g, filp, args[i])) @@ -2870,32 +2911,34 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) return NULL; if (!x) { + char *s = (ishav) ? havg : body; + // Append the value to the filter switch (args[i]->field_type()) { case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: if (tty == TYPE_AM_ODBC) { - strcat(body, "{ts '"); - strncat(body, res->ptr(), res->length()); + strcat(s, "{ts '"); + strncat(s, res->ptr(), res->length()); if (res->length() < 19) - strcat(body, &"1970-01-01 00:00:00"[res->length()]); + strcat(s, &"1970-01-01 00:00:00"[res->length()]); - strcat(body, "'}"); + strcat(s, "'}"); break; } // endif ODBC case MYSQL_TYPE_DATE: if (tty == TYPE_AM_ODBC) { - strcat(body, "{d '"); - strcat(strncat(body, res->ptr(), res->length()), "'}"); + strcat(s, "{d '"); + strcat(strncat(s, res->ptr(), res->length()), "'}"); break; } // endif ODBC case MYSQL_TYPE_TIME: if (tty == TYPE_AM_ODBC) { - strcat(body, "{t '"); - strcat(strncat(body, res->ptr(), res->length()), "'}"); + strcat(s, "{t '"); + strcat(strncat(s, res->ptr(), res->length()), "'}"); break; } // endif ODBC @@ -2904,39 +2947,39 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) switch (args[0]->field_type()) { case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DATETIME: - strcat(body, "{ts '"); - strncat(body, res->ptr(), res->length()); + strcat(s, "{ts '"); + strncat(s, res->ptr(), res->length()); if (res->length() < 19) - strcat(body, &"1970-01-01 00:00:00"[res->length()]); + strcat(s, &"1970-01-01 00:00:00"[res->length()]); - strcat(body, "'}"); + strcat(s, "'}"); break; case MYSQL_TYPE_DATE: - strcat(body, "{d '"); - strncat(body, res->ptr(), res->length()); - strcat(body, "'}"); + strcat(s, "{d '"); + strncat(s, res->ptr(), res->length()); + strcat(s, "'}"); break; case MYSQL_TYPE_TIME: - strcat(body, "{t '"); - strncat(body, res->ptr(), res->length()); - strcat(body, "'}"); + strcat(s, "{t '"); + strncat(s, res->ptr(), res->length()); + strcat(s, "'}"); break; default: - strcat(body, "'"); - strncat(body, res->ptr(), res->length()); - strcat(body, "'"); + strcat(s, "'"); + strncat(s, res->ptr(), res->length()); + strcat(s, "'"); } // endswitch field type } else { - strcat(body, "'"); - strncat(body, res->ptr(), res->length()); - strcat(body, "'"); + strcat(s, "'"); + strncat(s, res->ptr(), res->length()); + strcat(s, "'"); } // endif tty break; default: - strncat(body, res->ptr(), res->length()); + strncat(s, res->ptr(), res->length()); } // endswitch field type } else { @@ -2952,22 +2995,28 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) } // endif x - } // endif + } // endif's Type if (!x) { - if (!i) - strcat(body, GetValStr(vop, neg)); + char *s = (ishav) ? havg : body; + + if (!i) + strcat(s, GetValStr(vop, neg)); else if (vop == OP_XX && i == 1) - strcat(body, " AND "); + strcat(s, " AND "); else if (vop == OP_IN) - strcat(body, (i == condf->argument_count() - 1) ? ")" : ","); + strcat(s, (i == condf->argument_count() - 1) ? ")" : ","); } // endif x } // endfor i - if (x) - filp->Op= vop; + if (x) + filp->Op = vop; + else if (ishav) + filp->Hv = true; + else + filp->Bd = true; } else { if (trace) @@ -3024,16 +3073,28 @@ const COND *ha_connect::cond_push(const COND *cond) if (b) { PCFIL filp; + int rc; if ((filp= tdbp->GetCondFil()) && filp->Cond == cond && filp->Idx == active_index && filp->Type == tty) goto fin; // Already done filp= new(g) CONDFIL(cond, active_index, tty); - filp->Body= (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0); - *filp->Body= 0; + rc = filp->Init(g, this); + + if (rc == RC_INFO) { + filp->Having = (char*)PlugSubAlloc(g, NULL, 256); + *filp->Having = 0; + } else if (rc == RC_FX) + goto fin; + + filp->Body = (char*)PlugSubAlloc(g, NULL, (x) ? 128 : 0); + *filp->Body = 0; if (CheckCond(g, filp, cond)) { + if (filp->Having && strlen(filp->Having) > 255) + goto fin; // Memory collapse + if (trace) htrc("cond_push: %s\n", filp->Body); @@ -3206,9 +3267,9 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*) tdbp= GetTDB(g); dup->Check |= CHK_OPT; - if (tdbp) { + if (tdbp && !tdbp->IsRemote()) { bool dop= IsTypeIndexable(GetRealType(NULL)); - bool dox= (((PTDBASE)tdbp)->GetDef()->Indexable() == 1); + bool dox= (tdbp->GetDef()->Indexable() == 1); if ((rc= ((PTDBASE)tdbp)->ResetTableOpt(g, dop, dox))) { if (rc == RC_INFO) { @@ -3219,7 +3280,7 @@ int ha_connect::optimize(THD* thd, HA_CHECK_OPT*) } // endif rc - } else + } else if (!tdbp) rc= HA_ERR_INTERNAL_ERROR; return rc; @@ -3462,9 +3523,9 @@ int ha_connect::index_init(uint idx, bool sorted) htrc("index_init CONNECT: %s\n", g->Message); active_index= MAX_KEY; rc= HA_ERR_INTERNAL_ERROR; - } else if (((PTDBDOX)tdbp)->To_Kindex) { + } else if (tdbp->GetKindex()) { if (((PTDBDOX)tdbp)->To_Kindex->GetNum_K()) { - if (((PTDBASE)tdbp)->GetFtype() != RECFM_NAF) + if (tdbp->GetFtype() != RECFM_NAF) ((PTDBDOX)tdbp)->GetTxfp()->ResetBuffer(g); active_index= idx; @@ -3878,11 +3939,10 @@ int ha_connect::rnd_next(uchar *buf) void ha_connect::position(const uchar *) { DBUG_ENTER("ha_connect::position"); -//if (((PTDBASE)tdbp)->GetDef()->Indexable()) - my_store_ptr(ref, ref_length, (my_off_t)((PTDBASE)tdbp)->GetRecpos()); + my_store_ptr(ref, ref_length, (my_off_t)tdbp->GetRecpos()); if (trace > 1) - htrc("position: pos=%d\n", ((PTDBASE)tdbp)->GetRecpos()); + htrc("position: pos=%d\n", tdbp->GetRecpos()); DBUG_VOID_RETURN; } // end of position @@ -3907,14 +3967,14 @@ void ha_connect::position(const uchar *) int ha_connect::rnd_pos(uchar *buf, uchar *pos) { int rc; - PTDBASE tp= (PTDBASE)tdbp; +//PTDBASE tp= (PTDBASE)tdbp; DBUG_ENTER("ha_connect::rnd_pos"); - if (!tp->SetRecpos(xp->g, (int)my_get_ptr(pos, ref_length))) { + if (!tdbp->SetRecpos(xp->g, (int)my_get_ptr(pos, ref_length))) { if (trace) - htrc("rnd_pos: %d\n", tp->GetRecpos()); + htrc("rnd_pos: %d\n", tdbp->GetRecpos()); - tp->SetFilter(NULL); + tdbp->SetFilter(NULL); rc= rnd_next(buf); } else rc= HA_ERR_KEY_NOT_FOUND; @@ -4092,7 +4152,7 @@ int ha_connect::delete_all_rows() if (tdbp && tdbp->GetUse() == USE_OPEN && tdbp->GetAmType() != TYPE_AM_XML && - ((PTDBASE)tdbp)->GetFtype() != RECFM_NAF) + tdbp->GetFtype() != RECFM_NAF) // Close and reopen the table so it will be deleted rc= CloseTable(g); @@ -4470,12 +4530,12 @@ int ha_connect::external_lock(THD *thd, int lock_type) if (!tdbp) { if (!(tdbp= GetTDB(g))) DBUG_RETURN(HA_ERR_INTERNAL_ERROR); - else if (!((PTDBASE)tdbp)->GetDef()->Indexable()) { + else if (!tdbp->GetDef()->Indexable()) { sprintf(g->Message, "external_lock: Table %s is not indexable", tdbp->GetName()); // DBUG_RETURN(HA_ERR_INTERNAL_ERROR); causes assert error push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); DBUG_RETURN(0); - } else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 1) { + } else if (tdbp->GetDef()->Indexable() == 1) { bool oldsep= ((PCHK)g->Xchk)->oldsep; bool newsep= ((PCHK)g->Xchk)->newsep; PTDBDOS tdp= (PTDBDOS)tdbp; @@ -4556,7 +4616,7 @@ int ha_connect::external_lock(THD *thd, int lock_type) rc= 0; } // endif MakeIndex - } else if (((PTDBASE)tdbp)->GetDef()->Indexable() == 3) { + } else if (tdbp->GetDef()->Indexable() == 3) { if (CheckVirtualIndex(NULL)) { // Make it a warning to avoid crash push_warning(thd, Sql_condition::WARN_LEVEL_WARN, @@ -5172,7 +5232,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, TABLE_SHARE *table_s, HA_CREATE_INFO *create_info) { - char v=0, spc= ',', qch= 0; + char v=0; const char *fncn= "?"; const char *user, *fn, *db, *host, *pwd, *sep, *tbl, *src; const char *col, *ocl, *rnk, *pic, *fcl, *skc, *zfn; @@ -5224,8 +5284,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd, fncn= topt->catfunc; fnc= GetFuncID(fncn); sep= topt->separator; - spc= (!sep) ? ',' : *sep; - qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0; mul = (int)topt->multiple; tbl= topt->tablist; col= topt->colist; @@ -5425,8 +5483,8 @@ static int connect_assisted_discovery(handlerton *, THD* thd, if (mydef->GetPassword()) pwd= mydef->GetPassword(); - if (mydef->GetDatabase()) - db= mydef->GetDatabase(); + if (mydef->GetTabschema()) + db = mydef->GetTabschema(); if (mydef->GetTabname()) tab= mydef->GetTabname(); @@ -6052,8 +6110,8 @@ int ha_connect::create(const char *name, TABLE *table_arg, if (mydef->GetHostname()) host= mydef->GetHostname(); - if (mydef->GetDatabase()) - db= mydef->GetDatabase(); + if (mydef->GetTabschema()) + db = mydef->GetTabschema(); if (mydef->GetTabname()) tab= mydef->GetTabname(); @@ -6266,21 +6324,26 @@ int ha_connect::create(const char *name, TABLE *table_arg, // Check for incompatible options if (options->sepindex) { my_message(ER_UNKNOWN_ERROR, - "SEPINDEX is incompatible with unspecified file name", - MYF(0)); + "SEPINDEX is incompatible with unspecified file name", MYF(0)); DBUG_RETURN(HA_ERR_UNSUPPORTED); - } else if (GetTypeID(options->type) == TAB_VEC) - if (!table->s->max_rows || options->split) { - my_printf_error(ER_UNKNOWN_ERROR, - "%s tables whose file name is unspecified cannot be split", - MYF(0), options->type); - DBUG_RETURN(HA_ERR_UNSUPPORTED); - } else if (options->header == 2) { - my_printf_error(ER_UNKNOWN_ERROR, - "header=2 is not allowed for %s tables whose file name is unspecified", - MYF(0), options->type); - DBUG_RETURN(HA_ERR_UNSUPPORTED); - } // endif's + } else if (GetTypeID(options->type) == TAB_VEC) { + if (!table->s->max_rows || options->split) { + my_printf_error(ER_UNKNOWN_ERROR, + "%s tables whose file name is unspecified cannot be split", + MYF(0), options->type); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } else if (options->header == 2) { + my_printf_error(ER_UNKNOWN_ERROR, + "header=2 is not allowed for %s tables whose file name is unspecified", + MYF(0), options->type); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } // endif's + + } else if (options->zipped) { + my_message(ER_UNKNOWN_ERROR, + "ZIPPED is incompatible with unspecified file name", MYF(0)); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } // endif's options // Fold type to lower case for (int i= 0; i < 12; i++) @@ -6333,6 +6396,36 @@ int ha_connect::create(const char *name, TABLE *table_arg, if (trace) htrc("xchk=%p createas=%d\n", g->Xchk, g->Createas); + if (options->zipped) { + // Check whether the zip entry must be made from a file + char *fn = GetListOption(g, "Load", options->oplist, NULL); + + if (fn) { + char zbuf[_MAX_PATH], buf[_MAX_PATH], dbpath[_MAX_PATH]; + char *entry = GetListOption(g, "Entry", options->oplist, NULL); + char *a = GetListOption(g, "Append", options->oplist, "NO"); + bool append = *a == '1' || *a == 'Y' || *a == 'y' || !stricmp(a, "ON"); + char *m = GetListOption(g, "Mulentries", options->oplist, "NO"); + bool mul = *m == '1' || *m == 'Y' || *m == 'y' || !stricmp(m, "ON"); + + if (!entry && !mul) { + my_message(ER_UNKNOWN_ERROR, "Missing entry name", MYF(0)); + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + } // endif entry + + strcat(strcat(strcpy(dbpath, "./"), table->s->db.str), "/"); + PlugSetPath(zbuf, options->filename, dbpath); + PlugSetPath(buf, fn, dbpath); + + if (ZipLoadFile(g, zbuf, buf, entry, append, mul)) { + my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + DBUG_RETURN(HA_ERR_INTERNAL_ERROR); + } // endif LoadFile + + } // endif fn + + } // endif zipped + // To check whether indexes have to be made or remade if (!g->Xchk) { PIXDEF xdp; @@ -6951,10 +7044,10 @@ maria_declare_plugin(connect) PLUGIN_LICENSE_GPL, connect_init_func, /* Plugin Init */ connect_done_func, /* Plugin Deinit */ - 0x0104, /* version number (1.04) */ + 0x0105, /* version number (1.05) */ NULL, /* status variables */ connect_system_variables, /* system variables */ - "1.05.0001", /* string version */ + "1.05.0003", /* string version */ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ } maria_declare_plugin_end; diff --git a/storage/connect/ha_connect.h b/storage/connect/ha_connect.h index 3d9ff967618..cb15d371b5c 100644 --- a/storage/connect/ha_connect.h +++ b/storage/connect/ha_connect.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file ha_connect.h diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.c index 896431b855f..e5eb3567779 100644 --- a/storage/connect/inihandl.c +++ b/storage/connect/inihandl.c @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "my_global.h" diff --git a/storage/connect/ioapi.c b/storage/connect/ioapi.c index 7f5c191b2af..a49da91f7f0 100644 --- a/storage/connect/ioapi.c +++ b/storage/connect/ioapi.c @@ -27,6 +27,7 @@ #include "ioapi.h" +#include "my_attribute.h" voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) { @@ -92,7 +93,7 @@ static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPO static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); -static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +static voidpf ZCALLBACK fopen_file_func (voidpf opaque __attribute__((unused)), const char* filename, int mode) { FILE* file = NULL; const char* mode_fopen = NULL; @@ -110,7 +111,7 @@ static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, in return file; } -static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque __attribute__((unused)), const void* filename, int mode) { FILE* file = NULL; const char* mode_fopen = NULL; @@ -129,21 +130,21 @@ static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, } -static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +static uLong ZCALLBACK fread_file_func (voidpf opaque __attribute__((unused)), voidpf stream, void* buf, uLong size) { uLong ret; ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); return ret; } -static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +static uLong ZCALLBACK fwrite_file_func (voidpf opaque __attribute__((unused)), voidpf stream, const void* buf, uLong size) { uLong ret; ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); return ret; } -static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +static long ZCALLBACK ftell_file_func (voidpf opaque __attribute__((unused)), voidpf stream) { long ret; ret = ftell((FILE *)stream); @@ -151,14 +152,14 @@ static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) } -static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque __attribute__((unused)), voidpf stream) { ZPOS64_T ret; ret = FTELLO_FUNC((FILE *)stream); return ret; } -static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +static long ZCALLBACK fseek_file_func (voidpf opaque __attribute__((unused)), voidpf stream, uLong offset, int origin) { int fseek_origin=0; long ret; @@ -181,7 +182,7 @@ static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offs return ret; } -static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +static long ZCALLBACK fseek64_file_func (voidpf opaque __attribute__((unused)), voidpf stream, ZPOS64_T offset, int origin) { int fseek_origin=0; long ret; @@ -207,14 +208,14 @@ static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T } -static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +static int ZCALLBACK fclose_file_func (voidpf opaque __attribute__((unused)), voidpf stream) { int ret; ret = fclose((FILE *)stream); return ret; } -static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +static int ZCALLBACK ferror_file_func (voidpf opaque __attribute__((unused)), voidpf stream) { int ret; ret = ferror((FILE *)stream); diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index a69f84a94a1..c1d077406b7 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -1,7 +1,7 @@ /************ Jdbconn C++ Functions Source Code File (.CPP) ************/ -/* Name: JDBCONN.CPP Version 1.0 */ +/* Name: JDBCONN.CPP Version 1.1 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ /* */ /* This file contains the JDBC connection classes functions. */ /***********************************************************************/ @@ -45,9 +45,9 @@ #include "plgdbsem.h" #include "xobject.h" #include "xtable.h" +#include "tabext.h" #include "tabjdbc.h" //#include "jdbconn.h" -//#include "plgcnx.h" // For DB types #include "resource.h" #include "valblk.h" #include "osutil.h" @@ -318,13 +318,21 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, /**************************************************************************/ PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp) { + char *sqry; PQRYRES qrp; JDBConn *jcp = new(g)JDBConn(g, NULL); if (jcp->Open(sjp)) return NULL; - qrp = jcp->GetMetaData(g, src); + if (strstr(src, "%s")) { + // Place holder for an eventual where clause + sqry = (char*)PlugSubAlloc(g, NULL, strlen(src) + 2); + sprintf(sqry, src, "1=1"); // dummy where clause + } else + sqry = src; + + qrp = jcp->GetMetaData(g, sqry); jcp->Close(); return qrp; } // end of JDBCSrcCols @@ -818,6 +826,11 @@ int JDBConn::Open(PJPARM sop) jpop->Append(GetPluginDir()); jpop->Append("JdbcInterface.jar"); + // All wrappers are pre-compiled in JavaWrappers.jar in the plugin dir + jpop->Append(sep); + jpop->Append(GetPluginDir()); + jpop->Append("JavaWrappers.jar"); + //================== prepare loading of Java VM ============================ JavaVMInitArgs vm_args; // Initialization arguments JavaVMOption* options = new JavaVMOption[N]; // JVM invocation options @@ -1157,6 +1170,9 @@ void JDBConn::Close() jint rc; jmethodID did = nullptr; + // Could have been detached in case of join + rc = jvm->AttachCurrentThread((void**)&env, nullptr); + if (gmID(m_G, did, "JdbcDisconnect", "()I")) printf("%s\n", Msg); else if (Check(env->CallIntMethod(job, did))) diff --git a/storage/connect/json.cpp b/storage/connect/json.cpp index c45630129f1..b473871e9f7 100644 --- a/storage/connect/json.cpp +++ b/storage/connect/json.cpp @@ -1,7 +1,7 @@ /*************** json CPP Declares Source Code File (.H) ***************/ -/* Name: json.cpp Version 1.2 */ +/* Name: json.cpp Version 1.3 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2014 - 2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */ /* */ /* This file contains the JSON classes functions. */ /***********************************************************************/ @@ -27,8 +27,33 @@ #define EL "\r\n" #else #define EL "\n" +#undef SE_CATCH // Does not work for Linux #endif +#if defined(SE_CATCH) +/**************************************************************************/ +/* This is the support of catching C interrupts to prevent crashes. */ +/**************************************************************************/ +#include <eh.h> + +class SE_Exception { +public: + SE_Exception(unsigned int n, PEXCEPTION_RECORD p) : nSE(n), eRec(p) {} + ~SE_Exception() {} + + unsigned int nSE; + PEXCEPTION_RECORD eRec; +}; // end of class SE_Exception + +void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp) +{ + throw SE_Exception(u, pExp->ExceptionRecord); +} // end of trans_func + +char *GetExceptionDesc(PGLOBAL g, unsigned int e); +#endif // SE_CATCH + + /***********************************************************************/ /* Parse a json string. */ /* Note: when pretty is not known, the caller set pretty to 3. */ @@ -40,6 +65,9 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma) PJSON jsp = NULL; STRG src; + if (trace) + htrc("ParseJson: s=%.10s len=%d\n", s, len); + if (!s || !len) { strcpy(g->Message, "Void JSON object"); return NULL; @@ -53,15 +81,37 @@ PJSON ParseJson(PGLOBAL g, char *s, int len, int *ptyp, bool *comma) if (s[0] == '[' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n'))) pty[0] = false; + // Save stack and allocation environment and prepare error return if (g->jump_level == MAX_JUMP) { strcpy(g->Message, MSG(TOO_MANY_JUMPS)); return NULL; } // endif jump_level - if ((rc= setjmp(g->jumper[++g->jump_level])) != 0) { - goto err; - } // endif rc +#if defined(SE_CATCH) + // Let's try to recover from any kind of interrupt + _se_translator_function f = _set_se_translator(trans_func); + + try { +#endif // SE_CATCH --------------------- try section -------------------- + if ((rc = setjmp(g->jumper[++g->jump_level])) != 0) { + goto err; + } // endif rc + +#if defined(SE_CATCH) // ------------- end of try section ----------------- + } catch (SE_Exception e) { + sprintf(g->Message, "ParseJson: exception doing setjmp: %s (rc=%hd)", + GetExceptionDesc(g, e.nSE), e.nSE); + _set_se_translator(f); + goto err; + } catch (...) { + strcpy(g->Message, "Exception doing setjmp"); + _set_se_translator(f); + goto err; + } // end of try-catches + + _set_se_translator(f); +#endif // SE_CATCH for (i = 0; i < len; i++) switch (s[i]) { @@ -140,7 +190,7 @@ tryit: strcpy(g->Message, "More than one item in file"); err: - g->jump_level--; + g->jump_level--; return NULL; } // end of ParseJson @@ -390,14 +440,14 @@ char *ParseString(PGLOBAL g, int& i, STRG& src) // if (charset == utf8) { char xs[5]; uint hex; - + xs[0] = s[++i]; xs[1] = s[++i]; xs[2] = s[++i]; xs[3] = s[++i]; xs[4] = 0; hex = strtoul(xs, NULL, 16); - + if (hex < 0x80) { p[n] = (uchar)hex; } else if (hex < 0x800) { @@ -414,7 +464,7 @@ char *ParseString(PGLOBAL g, int& i, STRG& src) } else { char xs[3]; UINT hex; - + i += 2; xs[0] = s[++i]; xs[1] = s[++i]; @@ -468,7 +518,7 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src) case '.': if (!found_digit || has_dot || has_e) goto err; - + has_dot = true; break; case 'e': @@ -769,7 +819,7 @@ bool JOUTSTR::Escape(const char *s) for (unsigned int i = 0; s[i]; i++) switch (s[i]) { - case '"': + case '"': case '\\': case '\t': case '\n': @@ -1057,7 +1107,7 @@ void JARRAY::InitArray(PGLOBAL g) int i; PJVAL jvp, *pjvp = &First; - for (Size = 0, jvp = First; jvp; jvp = jvp->Next) + for (Size = 0, jvp = First; jvp; jvp = jvp->Next) if (!jvp->Del) Size++; @@ -1191,8 +1241,8 @@ bool JARRAY::IsNull(void) /***********************************************************************/ JVALUE::JVALUE(PGLOBAL g, PVAL valp) : JSON() { - Jsp = NULL; - Value = AllocateValue(g, valp); + Jsp = NULL; + Value = AllocateValue(g, valp); Next = NULL; Del = false; } // end of JVALUE constructor @@ -1297,7 +1347,7 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text) } // end of GetText void JVALUE::SetValue(PJSON jsp) -{ +{ if (jsp && jsp->GetType() == TYPE_JVAL) { Jsp = jsp->GetJsp(); Value = jsp->GetValue(); diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index bc7f231814d..f07a1ac818f 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1,6 +1,6 @@ /****************** jsonudf C++ Program Source Code File (.CPP) ******************/ -/* PROGRAM NAME: jsonudf Version 1.4 */ -/* (C) Copyright to the author Olivier BERTRAND 2015-2016 */ +/* PROGRAM NAME: jsonudf Version 1.5 */ +/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */ /* This program are the JSON User Defined Functions . */ /*********************************************************************************/ @@ -242,13 +242,16 @@ my_bool JSNX::ParseJpath(PGLOBAL g) // Jpath = Name; return true; - pbuf = PlugDup(g, Jpath); + if (!(pbuf = PlgDBDup(g, Jpath))) + return true; // The Jpath must be analyzed for (i = 0, p = pbuf; (p = strchr(p, ':')); i++, p++) Nod++; // One path node found - Nodes = (PJNODE)PlugSubAlloc(g, NULL, (++Nod) * sizeof(JNODE)); + if (!(Nodes = (PJNODE)PlgDBSubAlloc(g, NULL, (++Nod) * sizeof(JNODE)))) + return true; + memset(Nodes, 0, (Nod)* sizeof(JNODE)); // Analyze the Jpath for this column @@ -1086,9 +1089,10 @@ inline void JsonFreeMem(PGLOBAL g) /*********************************************************************************/ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args, char *message, my_bool mbn, - unsigned long reslen, unsigned long memlen) + unsigned long reslen, unsigned long memlen, + unsigned long more = 0) { - PGLOBAL g = PlugInit(NULL, memlen); + PGLOBAL g = PlugInit(NULL, memlen + more); if (!g) { strcpy(message, "Allocation error"); @@ -1100,6 +1104,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args, } // endif g g->Mrr = (args->arg_count && args->args[0]) ? 1 : 0; + g->ActivityStart = (PACTIVITY)more; initid->maybe_null = mbn; initid->max_length = reslen; initid->ptr = (char*)g; @@ -1443,6 +1448,8 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n, } // endif b + ml += (unsigned long)g->ActivityStart; // more + if (ml > g->Sarea_Size) { free(g->Sarea); @@ -2757,7 +2764,7 @@ void json_item_merge_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen, more; int n = IsJson(args, 0); if (args->arg_count < 2) { @@ -2766,7 +2773,7 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else if (!n && args->arg_type[0] != STRING_RESULT) { strcpy(message, "First argument must be a json item"); return true; - } else if (args->arg_type[1] != STRING_RESULT) { + } else if (args->arg_type[1] != STRING_RESULT) { strcpy(message, "Second argument is not a string (jpath)"); return true; } else @@ -2779,11 +2786,13 @@ my_bool json_get_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) memcpy(fn, args->args[0], args->lengths[0]); fn[args->lengths[0]] = 0; fl = GetFileLength(fn); - memlen += fl * 3; - } else if (n != 3) - memlen += args->lengths[0] * 3; + more = fl * 3; + } else if (n != 3) { + more = args->lengths[0] * 3; + } else + more = 0; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of json_get_item_init char *json_get_item(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2884,7 +2893,7 @@ my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // endif's CalcLen(args, false, reslen, memlen); - memlen += more; +//memlen += more; if (n == 2 && args->args[0]) { char fn[_MAX_PATH]; @@ -2893,11 +2902,11 @@ my_bool jsonget_string_init(UDF_INIT *initid, UDF_ARGS *args, char *message) memcpy(fn, args->args[0], args->lengths[0]); fn[args->lengths[0]] = 0; fl = GetFileLength(fn); - memlen += fl * 3; + more += fl * 3; } else if (n != 3) - memlen += args->lengths[0] * 3; + more += args->lengths[0] * 3; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsonget_string_init char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2993,7 +3002,7 @@ void jsonget_string_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen, more; if (args->arg_count != 2) { strcpy(message, "This function must have 2 arguments"); @@ -3007,10 +3016,10 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen); - if (IsJson(args, 0) != 3) - memlen += 1000; // TODO: calculate this + // TODO: calculate this + more = (IsJson(args, 0) != 3) ? 1000 : 0; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsonget_int_init long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args, @@ -3099,7 +3108,7 @@ void jsonget_int_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen, more; if (args->arg_count < 2) { strcpy(message, "At least 2 arguments required"); @@ -3122,10 +3131,10 @@ my_bool jsonget_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message) CalcLen(args, false, reslen, memlen); - if (IsJson(args, 0) != 3) - memlen += 1000; // TODO: calculate this + // TODO: calculate this + more = (IsJson(args, 0) != 3) ? 1000 : 0; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsonget_real_init double jsonget_real(UDF_INIT *initid, UDF_ARGS *args, @@ -3233,10 +3242,11 @@ my_bool jsonlocate_init(UDF_INIT *initid, UDF_ARGS *args, char *message) CalcLen(args, false, reslen, memlen); - if (IsJson(args, 0) != 3) - memlen += more; // TODO: calculate this + // TODO: calculate this + if (IsJson(args, 0) == 3) + more = 0; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsonlocate_init char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3357,10 +3367,11 @@ my_bool json_locate_all_init(UDF_INIT *initid, UDF_ARGS *args, char *message) CalcLen(args, false, reslen, memlen); - if (IsJson(args, 0) != 3) - memlen += more; // TODO: calculate this + // TODO: calculate this + if (IsJson(args, 0) == 3) + more = 0; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of json_locate_all_init char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3484,12 +3495,12 @@ my_bool jsoncontains_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // endif's CalcLen(args, false, reslen, memlen); - memlen += more; +//memlen += more; - if (IsJson(args, 0) != 3) - memlen += 1000; // TODO: calculate this + // TODO: calculate this + more += (IsJson(args, 0) != 3 ? 1000 : 0); - return JsonInit(initid, args, message, false, reslen, memlen); + return JsonInit(initid, args, message, false, reslen, memlen, more); } // end of jsoncontains_init long long jsoncontains(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3536,12 +3547,12 @@ my_bool jsoncontains_path_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // endif's CalcLen(args, false, reslen, memlen); - memlen += more; +//memlen += more; - if (IsJson(args, 0) != 3) - memlen += 1000; // TODO: calculate this + // TODO: calculate this + more += (IsJson(args, 0) != 3 ? 1000 : 0); - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jsoncontains_path_init long long jsoncontains_path(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3735,7 +3746,7 @@ fin: /*********************************************************************************/ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen, more = 0; int n = IsJson(args, 0); if (!(args->arg_count % 2)) { @@ -3754,11 +3765,11 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) memcpy(fn, args->args[0], args->lengths[0]); fn[args->lengths[0]] = 0; fl = GetFileLength(fn); - memlen += fl * 3; + more += fl * 3; } else if (n != 3) - memlen += args->lengths[0] * 3; + more += args->lengths[0] * 3; - if (!JsonInit(initid, args, message, true, reslen, memlen)) { + if (!JsonInit(initid, args, message, true, reslen, memlen, more)) { PGLOBAL g = (PGLOBAL)initid->ptr; // This is a constant function @@ -3953,7 +3964,7 @@ void json_file_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jfile_make_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen, more = 1024; + unsigned long reslen, memlen; if (args->arg_count < 1 || args->arg_count > 3) { strcpy(message, "Wrong number of arguments"); @@ -4992,7 +5003,7 @@ fin: /*********************************************************************************/ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen, more = 0; int n = IsJson(args, 0); if (!(args->arg_count % 2)) { @@ -5011,11 +5022,11 @@ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) memcpy(fn, args->args[0], args->lengths[0]); fn[args->lengths[0]] = 0; fl = GetFileLength(fn); - memlen += fl * 3; + more = fl * 3; } else if (n != 3) - memlen += args->lengths[0] * 3; + more = args->lengths[0] * 3; - return JsonInit(initid, args, message, true, reslen, memlen); + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jbin_set_item_init char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -5103,8 +5114,8 @@ my_bool jbin_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) fl = GetFileLength(args->args[0]); reslen += fl; more += fl * M; - memlen += more; - return JsonInit(initid, args, message, true, reslen, memlen); +//memlen += more; + return JsonInit(initid, args, message, true, reslen, memlen, more); } // end of jbin_file_init char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result, diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index 497fe5e1aa8..1fcd8ac78da 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -1,4 +1,4 @@ -/* Copyright (C) Olivier Bertrand 2004 - 2016 +/* Copyright (C) Olivier Bertrand 2004 - 2017 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,14 +11,14 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /*************** Mycat CC Program Source Code File (.CC) ***************/ /* PROGRAM NAME: MYCAT */ /* ------------- */ -/* Version 1.5 */ +/* Version 1.6 */ /* */ -/* Author: Olivier Bertrand 2012 - 2016 */ +/* Author: Olivier Bertrand 2012 - 2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -58,9 +58,10 @@ #endif // UNIX #include "global.h" #include "plgdbsem.h" -#include "reldef.h" -#include "tabcol.h" +//#include "reldef.h" #include "xtable.h" +#include "tabext.h" +#include "tabcol.h" #include "filamtxt.h" #include "tabdos.h" #include "tabfmt.h" @@ -559,13 +560,13 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) case TAB_XML: tdp= new(g) XMLDEF; break; #endif // XML_SUPPORT #if defined(VCT_SUPPORT) - case TAB_VEC: tdp = new(g)VCTDEF; break; + case TAB_VEC: tdp = new(g) VCTDEF; break; #endif // VCT_SUPPORT #if defined(ODBC_SUPPORT) case TAB_ODBC: tdp= new(g) ODBCDEF; break; #endif // ODBC_SUPPORT #if defined(JDBC_SUPPORT) - case TAB_JDBC: tdp= new(g)JDBCDEF; break; + case TAB_JDBC: tdp= new(g) JDBCDEF; break; #endif // JDBC_SUPPORT #if defined(__WIN__) case TAB_MAC: tdp= new(g) MACDEF; break; diff --git a/storage/connect/mycat.h b/storage/connect/mycat.h index 663b68fd4b9..a3682b31f17 100644 --- a/storage/connect/mycat.h +++ b/storage/connect/mycat.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /**************** MYCAT H Declares Source Code File (.H) ***************/ /* Name: MYCAT.H Version 2.3 */ diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index 644ca019e4a..d05254a32a6 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -1,11 +1,11 @@ /************** MyConn C++ Program Source Code File (.CPP) **************/ /* PROGRAM NAME: MYCONN */ /* ------------- */ -/* Version 1.8 */ +/* Version 1.9 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2007-2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2007-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -375,10 +375,18 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db, if (!port) port = mysqld_port; - if (!strnicmp(srcdef, "select ", 7)) { - query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 9); - strcat(strcpy(query, srcdef), " LIMIT 0"); - } else + if (!strnicmp(srcdef, "select ", 7) || strstr(srcdef, "%s")) { + query = (char *)PlugSubAlloc(g, NULL, strlen(srcdef) + 10); + + if (strstr(srcdef, "%s")) + sprintf(query, srcdef, "1=1"); // dummy where clause + else + strcpy(query, srcdef); + + if (!strnicmp(srcdef, "select ", 7)) + strcat(query, " LIMIT 0"); + + } else query = (char *)srcdef; // Open a MySQL connection for this table diff --git a/storage/connect/mysql-test/connect/r/xml_zip.result b/storage/connect/mysql-test/connect/r/xml_zip.result new file mode 100644 index 00000000000..f176149c53f --- /dev/null +++ b/storage/connect/mysql-test/connect/r/xml_zip.result @@ -0,0 +1,98 @@ +Warnings: +Warning 1105 No file name. Table will use t1.xml +# +# Testing zipped XML tables +# +CREATE TABLE t1 ( +ISBN CHAR(13) NOT NULL FIELD_FORMAT='@', +LANG CHAR(2) NOT NULL FIELD_FORMAT='@', +SUBJECT CHAR(12) NOT NULL FIELD_FORMAT='@', +AUTHOR_FIRSTNAME CHAR(15) NOT NULL FIELD_FORMAT='AUTHOR/FIRSTNAME', +AUTHOR_LASTNAME CHAR(8) NOT NULL FIELD_FORMAT='AUTHOR/LASTNAME', +TRANSLATOR_PREFIX CHAR(24) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/@PREFIX', +TRANSLATOR_FIRSTNAME CHAR(6) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/FIRSTNAME', +TRANSLATOR_LASTNAME CHAR(6) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/LASTNAME', +TITLE CHAR(30) NOT NULL, +PUBLISHER_NAME CHAR(15) NOT NULL FIELD_FORMAT='PUBLISHER/NAME', +PUBLISHER_PLACE CHAR(5) NOT NULL FIELD_FORMAT='PUBLISHER/PLACE', +DATEPUB CHAR(4) NOT NULL +) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES +OPTION_LIST='entry=xsample2.xml,load=xsample2.xml,rownode=BOOK,xmlsup=libxml2,expand=1,mulnode=AUTHOR'; +SELECT * FROM t1; +ISBN 9782212090819 +LANG fr +SUBJECT applications +AUTHOR_FIRSTNAME Jean-Christophe +AUTHOR_LASTNAME Bernadac +TRANSLATOR_PREFIX NULL +TRANSLATOR_FIRSTNAME NULL +TRANSLATOR_LASTNAME NULL +TITLE Construire une application XML +PUBLISHER_NAME Eyrolles +PUBLISHER_PLACE Paris +DATEPUB 1999 +ISBN 9782212090819 +LANG fr +SUBJECT applications +AUTHOR_FIRSTNAME François +AUTHOR_LASTNAME Knab +TRANSLATOR_PREFIX NULL +TRANSLATOR_FIRSTNAME NULL +TRANSLATOR_LASTNAME NULL +TITLE Construire une application XML +PUBLISHER_NAME Eyrolles +PUBLISHER_PLACE Paris +DATEPUB 1999 +ISBN 9782840825685 +LANG fr +SUBJECT applications +AUTHOR_FIRSTNAME William J. +AUTHOR_LASTNAME Pardi +TRANSLATOR_PREFIX adapté de l'anglais par +TRANSLATOR_FIRSTNAME James +TRANSLATOR_LASTNAME Guerin +TITLE XML en Action +PUBLISHER_NAME Microsoft Press +PUBLISHER_PLACE Paris +DATEPUB 1999 +ISBN 9782212090529 +LANG fr +SUBJECT général +AUTHOR_FIRSTNAME Alain +AUTHOR_LASTNAME Michard +TRANSLATOR_PREFIX NULL +TRANSLATOR_FIRSTNAME NULL +TRANSLATOR_LASTNAME NULL +TITLE XML, Langage et Applications +PUBLISHER_NAME Eyrolles +PUBLISHER_PLACE Paris +DATEPUB 2003 +CREATE TABLE t2 +ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES +OPTION_LIST='xmlsup=libxml2'; +SELECT * FROM t2; +ISBN 9782212090819 +LANG fr +SUBJECT applications +AUTHOR Jean-Christophe Bernadac +TRANSLATOR NULL +TITLE Construire une application XML +PUBLISHER Eyrolles Paris +DATEPUB 1999 +ISBN 9782840825685 +LANG fr +SUBJECT applications +AUTHOR William J. Pardi +TRANSLATOR James Guerin +TITLE XML en Action +PUBLISHER Microsoft Press Paris +DATEPUB 1999 +ISBN 9782212090529 +LANG fr +SUBJECT général +AUTHOR Alain Michard +TRANSLATOR NULL +TITLE XML, Langage et Applications +PUBLISHER Eyrolles Paris +DATEPUB 2003 +DROP TABLE t1,t2; diff --git a/storage/connect/mysql-test/connect/r/zip.result b/storage/connect/mysql-test/connect/r/zip.result new file mode 100644 index 00000000000..c03b27bd428 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/zip.result @@ -0,0 +1,240 @@ +# +# Testing zipped DOS tables +# +CREATE TABLE t1 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='newdos.zip' +OPTION_LIST='ENTRY=new1.dos' ZIPPED=1; +INSERT INTO t1 VALUES(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),(5,'Five'),(6,'Six'),(7,'Seven'),(8,'Eight'),(9,'Nine'),(10,'Ten'); +SELECT * FROM t1; +digit letter +1 One +2 Two +3 Three +4 Four +5 Five +6 Six +7 Seven +8 Eight +9 Nine +10 Ten +CREATE TABLE t2 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='newdos.zip' +OPTION_LIST='ENTRY=new2.dos,APPEND=1' ZIPPED=1; +INSERT INTO t2 VALUES(11,'Eleven'),(12,'Twelve'),(13,'Thirteen'),(14,'Fourteen'),(15,'Fiften'),(16,'Sixteen'),(17,'Seventeen'),(18,'Eighteen'),(19,'Nineteen'),(20,'Twenty'); +SELECT * FROM t2; +digit letter +11 Eleven +12 Twelve +13 Thirteen +14 Fourteen +15 Fiften +16 Sixteen +17 Seventeen +18 Eighteen +19 Nineteen +20 Twenty +CREATE TABLE t3 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='newdos.zip' +OPTION_LIST='MULENTRIES=1' ZIPPED=1; +SELECT * FROM t3; +digit letter +1 One +2 Two +3 Three +4 Four +5 Five +6 Six +7 Seven +8 Eight +9 Nine +10 Ten +11 Eleven +12 Twelve +13 Thirteen +14 Fourteen +15 Fiften +16 Sixteen +17 Seventeen +18 Eighteen +19 Nineteen +20 Twenty +CREATE TABLE t4 ( +fn VARCHAR(256)NOT NULL, +cmpsize BIGINT NOT NULL FLAG=1, +uncsize BIGINT NOT NULL FLAG=2, +method INT NOT NULL FLAG=3) +ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='newdos.zip'; +SELECT * FROM t4; +fn cmpsize uncsize method +new1.dos 67 79 8 +new2.dos 77 112 8 +DROP TABLE t1,t2,t3,t4; +# +# Testing zipped CSV tables +# +CREATE TABLE t1 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='ENTRY=new1.csv' HEADER=1 ZIPPED=1; +INSERT INTO t1 VALUES(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),(5,'Five'),(6,'Six'),(7,'Seven'),(8,'Eight'),(9,'Nine'),(10,'Ten'); +SELECT * FROM t1; +digit letter +1 One +2 Two +3 Three +4 Four +5 Five +6 Six +7 Seven +8 Eight +9 Nine +10 Ten +CREATE TABLE td1 +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='ENTRY=new1.csv' HEADER=1 ZIPPED=1; +SELECT * FROM td1; +digit letter +1 One +2 Two +3 Three +4 Four +5 Five +6 Six +7 Seven +8 Eight +9 Nine +10 Ten +DROP TABLE td1; +CREATE TABLE t2 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='ENTRY=new2.csv,APPEND=1' HEADER=1 ZIPPED=1; +INSERT INTO t2 VALUES(11,'Eleven'),(12,'Twelve'),(13,'Thirteen'),(14,'Fourteen'),(15,'Fiften'),(16,'Sixteen'),(17,'Seventeen'),(18,'Eighteen'),(19,'Nineteen'),(20,'Twenty'); +SELECT * FROM t2; +digit letter +11 Eleven +12 Twelve +13 Thirteen +14 Fourteen +15 Fiften +16 Sixteen +17 Seventeen +18 Eighteen +19 Nineteen +20 Twenty +CREATE TABLE t3 +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='MULENTRIES=1' HEADER=1 ZIPPED=1; +SELECT * FROM t3; +digit letter +1 One +2 Two +3 Three +4 Four +5 Five +6 Six +7 Seven +8 Eight +9 Nine +10 Ten +11 Eleven +12 Twelve +13 Thirteen +14 Fourteen +15 Fiften +16 Sixteen +17 Seventeen +18 Eighteen +19 Nineteen +20 Twenty +CREATE TABLE t4 ( +fn VARCHAR(256)NOT NULL, +cmpsize BIGINT NOT NULL FLAG=1, +uncsize BIGINT NOT NULL FLAG=2, +method INT NOT NULL FLAG=3) +ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='newcsv.zip'; +SELECT * FROM t4; +fn cmpsize uncsize method +new1.csv 79 83 8 +new2.csv 94 125 8 +DROP TABLE t1,t2,t3,t4; +# +# Testing zipped JSON tables +# +CREATE TABLE t1 ( +_id INT(2) NOT NULL, +name_first CHAR(9) NOT NULL FIELD_FORMAT='name:first', +name_aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka', +name_last CHAR(10) NOT NULL FIELD_FORMAT='name:last', +title CHAR(12) DEFAULT NULL, +birth CHAR(20) DEFAULT NULL, +death CHAR(20) DEFAULT NULL, +contribs CHAR(7) NOT NULL FIELD_FORMAT='contribs:', +awards_award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards::award', +awards_year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards::year', +awards_by CHAR(38) DEFAULT NULL FIELD_FORMAT='awards::by' +) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.zip' OPTION_LIST='ENTRY=bios.json,LOAD=bios.json' ZIPPED=YES; +SELECT * FROM t1; +_id name_first name_aka name_last title birth death contribs awards_award awards_year awards_by +1 John NULL Backus NULL 1924-12-03T05:00:00Z 2007-03-17T04:00:00Z Fortran W.W. McDowell Award 1967 IEEE Computer Society +2 John NULL McCarthy NULL 1927-09-04T04:00:00Z 2011-12-24T05:00:00Z Lisp Turing Award 1971 ACM +3 Grace NULL Hopper Rear Admiral 1906-12-09T05:00:00Z 1992-01-01T05:00:00Z UNIVAC Computer Sciences Man of the Year 1969 Data Processing Management Association +4 Kristen NULL Nygaard NULL 1926-08-27T04:00:00Z 2002-08-10T04:00:00Z OOP Rosing Prize 1999 Norwegian Data Association +5 Ole-Johan NULL Dahl NULL 1931-10-12T04:00:00Z 2002-06-29T04:00:00Z OOP Rosing Prize 1999 Norwegian Data Association +6 Guido NULL van Rossum NULL 1956-01-31T05:00:00Z NULL Python Award for the Advancement of Free Software 2001 Free Software Foundation +7 Dennis NULL Ritchie NULL 1941-09-09T04:00:00Z 2011-10-12T04:00:00Z UNIX Turing Award 1983 ACM +8 Yukihiro Matz Matsumoto NULL 1965-04-14T04:00:00Z NULL Ruby Award for the Advancement of Free Software 2011 Free Software Foundation +9 James NULL Gosling NULL 1955-05-19T04:00:00Z NULL Java The Economist Innovation Award 2002 The Economist +10 Martin NULL Odersky NULL NULL NULL Scala NULL NULL NULL +CREATE TABLE t2 +ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.zip' ZIPPED=1 +OPTION_LIST='LEVEL=5'; +SELECT * FROM t2; +_id name_first name_aka name_last title birth death contribs awards_award awards_year awards_by +1 John NULL Backus NULL 1924-12-03T05:00:00Z 2007-03-17T04:00:00Z Fortran W.W. McDowell Award 1967 IEEE Computer Society +2 John NULL McCarthy NULL 1927-09-04T04:00:00Z 2011-12-24T05:00:00Z Lisp Turing Award 1971 ACM +3 Grace NULL Hopper Rear Admiral 1906-12-09T05:00:00Z 1992-01-01T05:00:00Z UNIVAC Computer Sciences Man of the Year 1969 Data Processing Management Association +4 Kristen NULL Nygaard NULL 1926-08-27T04:00:00Z 2002-08-10T04:00:00Z OOP Rosing Prize 1999 Norwegian Data Association +5 Ole-Johan NULL Dahl NULL 1931-10-12T04:00:00Z 2002-06-29T04:00:00Z OOP Rosing Prize 1999 Norwegian Data Association +6 Guido NULL van Rossum NULL 1956-01-31T05:00:00Z NULL Python Award for the Advancement of Free Software 2001 Free Software Foundation +7 Dennis NULL Ritchie NULL 1941-09-09T04:00:00Z 2011-10-12T04:00:00Z UNIX Turing Award 1983 ACM +8 Yukihiro Matz Matsumoto NULL 1965-04-14T04:00:00Z NULL Ruby Award for the Advancement of Free Software 2011 Free Software Foundation +9 James NULL Gosling NULL 1955-05-19T04:00:00Z NULL Java The Economist Innovation Award 2002 The Economist +10 Martin NULL Odersky NULL NULL NULL Scala NULL NULL NULL +CREATE TABLE t3 ( +_id INT(2) NOT NULL, +firstname CHAR(9) NOT NULL FIELD_FORMAT='name:first', +aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka', +lastname CHAR(10) NOT NULL FIELD_FORMAT='name:last', +title CHAR(12) DEFAULT NULL, +birth date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'", +death date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'", +contribs CHAR(64) NOT NULL FIELD_FORMAT='contribs:[", "]', +award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards:[x]:award', +year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards:[x]:year', +`by` CHAR(38) DEFAULT NULL FIELD_FORMAT='awards:[x]:by' +) ENGINE=CONNECT TABLE_TYPE='json' FILE_NAME='bios.zip' ZIPPED=YES; +SELECT * FROM t3 WHERE _id = 1; +_id firstname aka lastname title birth death contribs award year by +1 John NULL Backus NULL 1924-03-12 2008-05-03 Fortran, ALGOL, Backus-Naur Form, FP W.W. McDowell Award 1967 IEEE Computer Society +1 John NULL Backus NULL 1924-03-12 2008-05-03 Fortran, ALGOL, Backus-Naur Form, FP National Medal of Science 1975 National Science Foundation +1 John NULL Backus NULL 1924-03-12 2008-05-03 Fortran, ALGOL, Backus-Naur Form, FP Turing Award 1977 ACM +1 John NULL Backus NULL 1924-03-12 2008-05-03 Fortran, ALGOL, Backus-Naur Form, FP Draper Prize 1993 National Academy of Engineering +CREATE TABLE t4 ( +fn VARCHAR(256)NOT NULL, +cmpsize BIGINT NOT NULL FLAG=1, +uncsize BIGINT NOT NULL FLAG=2, +method INT NOT NULL FLAG=3) +ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='bios.zip'; +SELECT * FROM t4; +fn cmpsize uncsize method +bios.json 1096 6848 8 +DROP TABLE t1,t2,t3,t4; diff --git a/storage/connect/mysql-test/connect/std_data/bios.json b/storage/connect/mysql-test/connect/std_data/bios.json new file mode 100644 index 00000000000..85e4ecb933f --- /dev/null +++ b/storage/connect/mysql-test/connect/std_data/bios.json @@ -0,0 +1,273 @@ +[ + { + "_id" : 1, + "name" : { + "first" : "John", + "last" : "Backus" + }, + "birth" : "1924-12-03T05:00:00Z", + "death" : "2007-03-17T04:00:00Z", + "contribs" : [ + "Fortran", + "ALGOL", + "Backus-Naur Form", + "FP" + ], + "awards" : [ + { + "award" : "W.W. McDowell Award", + "year" : 1967, + "by" : "IEEE Computer Society" + }, + { + "award" : "National Medal of Science", + "year" : 1975, + "by" : "National Science Foundation" + }, + { + "award" : "Turing Award", + "year" : 1977, + "by" : "ACM" + }, + { + "award" : "Draper Prize", + "year" : 1993, + "by" : "National Academy of Engineering" + } + ] + }, + { + "_id" : 2, + "name" : { + "first" : "John", + "last" : "McCarthy" + }, + "birth" : "1927-09-04T04:00:00Z", + "death" : "2011-12-24T05:00:00Z", + "contribs" : [ + "Lisp", + "Artificial Intelligence", + "ALGOL" + ], + "awards" : [ + { + "award" : "Turing Award", + "year" : 1971, + "by" : "ACM" + }, + { + "award" : "Kyoto Prize", + "year" : 1988, + "by" : "Inamori Foundation" + }, + { + "award" : "National Medal of Science", + "year" : 1990, + "by" : "National Science Foundation" + } + ] + }, + { + "_id" : 3, + "name" : { + "first" : "Grace", + "last" : "Hopper" + }, + "title" : "Rear Admiral", + "birth" : "1906-12-09T05:00:00Z", + "death" : "1992-01-01T05:00:00Z", + "contribs" : [ + "UNIVAC", + "compiler", + "FLOW-MATIC", + "COBOL" + ], + "awards" : [ + { + "award" : "Computer Sciences Man of the Year", + "year" : 1969, + "by" : "Data Processing Management Association" + }, + { + "award" : "Distinguished Fellow", + "year" : 1973, + "by" : " British Computer Society" + }, + { + "award" : "W. W. McDowell Award", + "year" : 1976, + "by" : "IEEE Computer Society" + }, + { + "award" : "National Medal of Technology", + "year" : 1991, + "by" : "United States" + } + ] + }, + { + "_id" : 4, + "name" : { + "first" : "Kristen", + "last" : "Nygaard" + }, + "birth" : "1926-08-27T04:00:00Z", + "death" : "2002-08-10T04:00:00Z", + "contribs" : [ + "OOP", + "Simula" + ], + "awards" : [ + { + "award" : "Rosing Prize", + "year" : 1999, + "by" : "Norwegian Data Association" + }, + { + "award" : "Turing Award", + "year" : 2001, + "by" : "ACM" + }, + { + "award" : "IEEE John von Neumann Medal", + "year" : 2001, + "by" : "IEEE" + } + ] + }, + { + "_id" : 5, + "name" : { + "first" : "Ole-Johan", + "last" : "Dahl" + }, + "birth" : "1931-10-12T04:00:00Z", + "death" : "2002-06-29T04:00:00Z", + "contribs" : [ + "OOP", + "Simula" + ], + "awards" : [ + { + "award" : "Rosing Prize", + "year" : 1999, + "by" : "Norwegian Data Association" + }, + { + "award" : "Turing Award", + "year" : 2001, + "by" : "ACM" + }, + { + "award" : "IEEE John von Neumann Medal", + "year" : 2001, + "by" : "IEEE" + } + ] + }, + { + "_id" : 6, + "name" : { + "first" : "Guido", + "last" : "van Rossum" + }, + "birth" : "1956-01-31T05:00:00Z", + "contribs" : [ + "Python" + ], + "awards" : [ + { + "award" : "Award for the Advancement of Free Software", + "year" : 2001, + "by" : "Free Software Foundation" + }, + { + "award" : "NLUUG Award", + "year" : 2003, + "by" : "NLUUG" + } + ] + }, + { + "_id" : 7, + "name" : { + "first" : "Dennis", + "last" : "Ritchie" + }, + "birth" : "1941-09-09T04:00:00Z", + "death" : "2011-10-12T04:00:00Z", + "contribs" : [ + "UNIX", + "C" + ], + "awards" : [ + { + "award" : "Turing Award", + "year" : 1983, + "by" : "ACM" + }, + { + "award" : "National Medal of Technology", + "year" : 1998, + "by" : "United States" + }, + { + "award" : "Japan Prize", + "year" : 2011, + "by" : "The Japan Prize Foundation" + } + ] + }, + { + "_id" : 8, + "name" : { + "first" : "Yukihiro", + "aka" : "Matz", + "last" : "Matsumoto" + }, + "birth" : "1965-04-14T04:00:00Z", + "contribs" : [ + "Ruby" + ], + "awards" : [ + { + "award" : "Award for the Advancement of Free Software", + "year" : "2011", + "by" : "Free Software Foundation" + } + ] + }, + { + "_id" : 9, + "name" : { + "first" : "James", + "last" : "Gosling" + }, + "birth" : "1955-05-19T04:00:00Z", + "contribs" : [ + "Java" + ], + "awards" : [ + { + "award" : "The Economist Innovation Award", + "year" : 2002, + "by" : "The Economist" + }, + { + "award" : "Officer of the Order of Canada", + "year" : 2007, + "by" : "Canada" + } + ] + }, + { + "_id" : 10, + "name" : { + "first" : "Martin", + "last" : "Odersky" + }, + "contribs" : [ + "Scala" + ] + } +] diff --git a/storage/connect/mysql-test/connect/std_data/xsample2.xml b/storage/connect/mysql-test/connect/std_data/xsample2.xml new file mode 100644 index 00000000000..35295844370 --- /dev/null +++ b/storage/connect/mysql-test/connect/std_data/xsample2.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<BIBLIO SUBJECT="XML"> + <BOOK ISBN="9782212090819" LANG="fr" SUBJECT="applications"> + <AUTHOR> + <FIRSTNAME>Jean-Christophe</FIRSTNAME> + <LASTNAME>Bernadac</LASTNAME> + </AUTHOR> + <AUTHOR> + <FIRSTNAME>François</FIRSTNAME> + <LASTNAME>Knab</LASTNAME> + </AUTHOR> + <TITLE>Construire une application XML</TITLE> + <PUBLISHER> + <NAME>Eyrolles</NAME> + <PLACE>Paris</PLACE> + </PUBLISHER> + <DATEPUB>1999</DATEPUB> + </BOOK> + <BOOK ISBN="9782840825685" LANG="fr" SUBJECT="applications"> + <AUTHOR> + <FIRSTNAME>William J.</FIRSTNAME> + <LASTNAME>Pardi</LASTNAME> + </AUTHOR> + <TRANSLATOR PREFIX="adapté de l'anglais par"> + <FIRSTNAME>James</FIRSTNAME> + <LASTNAME>Guerin</LASTNAME> + </TRANSLATOR> + <TITLE>XML en Action</TITLE> + <PUBLISHER> + <NAME>Microsoft Press</NAME> + <PLACE>Paris</PLACE> + </PUBLISHER> + <DATEPUB>1999</DATEPUB> + </BOOK> + <BOOK ISBN="9782212090529" LANG="fr" SUBJECT="général"> + <AUTHOR> + <FIRSTNAME>Alain</FIRSTNAME> + <LASTNAME>Michard</LASTNAME> + </AUTHOR> + <TITLE>XML, Langage et Applications</TITLE> + <PUBLISHER> + <NAME>Eyrolles</NAME> + <PLACE>Paris</PLACE> + </PUBLISHER> + <DATEPUB>2003</DATEPUB> + </BOOK> +</BIBLIO> diff --git a/storage/connect/mysql-test/connect/t/have_zip.inc b/storage/connect/mysql-test/connect/t/have_zip.inc new file mode 100644 index 00000000000..d1283fc1d38 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/have_zip.inc @@ -0,0 +1,19 @@ +--disable_query_log +--error 0,ER_UNKNOWN_ERROR +CREATE TABLE t1 (a CHAR(10)) ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='test.zip'; +if ($mysql_errno) +{ + Skip No ZIP support; +} +#if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES +# WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1' +# AND ENGINE='CONNECT' +# AND CREATE_OPTIONS LIKE '%`table_type`=ZIP%' +# AND CREATE OPTIONS LIKE "%`file_name`='test.zip'%"`) +#{ +# DROP TABLE IF EXISTS t1; +# Skip Need ZIP support; +#} +DROP TABLE t1; +--enable_query_log + diff --git a/storage/connect/mysql-test/connect/t/xml_zip.test b/storage/connect/mysql-test/connect/t/xml_zip.test new file mode 100644 index 00000000000..d8c7894f861 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/xml_zip.test @@ -0,0 +1,41 @@ +--source have_zip.inc +--source have_libxml2.inc + +let $MYSQLD_DATADIR= `select @@datadir`; + +--vertical_results + +--copy_file $MTR_SUITE_DIR/std_data/xsample2.xml $MYSQLD_DATADIR/test/xsample2.xml + +--echo # +--echo # Testing zipped XML tables +--echo # +CREATE TABLE t1 ( +ISBN CHAR(13) NOT NULL FIELD_FORMAT='@', +LANG CHAR(2) NOT NULL FIELD_FORMAT='@', +SUBJECT CHAR(12) NOT NULL FIELD_FORMAT='@', +AUTHOR_FIRSTNAME CHAR(15) NOT NULL FIELD_FORMAT='AUTHOR/FIRSTNAME', +AUTHOR_LASTNAME CHAR(8) NOT NULL FIELD_FORMAT='AUTHOR/LASTNAME', +TRANSLATOR_PREFIX CHAR(24) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/@PREFIX', +TRANSLATOR_FIRSTNAME CHAR(6) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/FIRSTNAME', +TRANSLATOR_LASTNAME CHAR(6) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/LASTNAME', +TITLE CHAR(30) NOT NULL, +PUBLISHER_NAME CHAR(15) NOT NULL FIELD_FORMAT='PUBLISHER/NAME', +PUBLISHER_PLACE CHAR(5) NOT NULL FIELD_FORMAT='PUBLISHER/PLACE', +DATEPUB CHAR(4) NOT NULL +) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES +OPTION_LIST='entry=xsample2.xml,load=xsample2.xml,rownode=BOOK,xmlsup=libxml2,expand=1,mulnode=AUTHOR'; +SELECT * FROM t1; + +#testing discovery +CREATE TABLE t2 +ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES +OPTION_LIST='xmlsup=libxml2'; +SELECT * FROM t2; +DROP TABLE t1,t2; + +# +# Clean up +# +--remove_file $MYSQLD_DATADIR/test/xsample2.xml +--remove_file $MYSQLD_DATADIR/test/xsample2.zip diff --git a/storage/connect/mysql-test/connect/t/zip.test b/storage/connect/mysql-test/connect/t/zip.test new file mode 100644 index 00000000000..a4892e9ed4e --- /dev/null +++ b/storage/connect/mysql-test/connect/t/zip.test @@ -0,0 +1,136 @@ +--source have_zip.inc +let $MYSQLD_DATADIR= `select @@datadir`; + +--copy_file $MTR_SUITE_DIR/std_data/bios.json $MYSQLD_DATADIR/test/bios.json + +--echo # +--echo # Testing zipped DOS tables +--echo # +CREATE TABLE t1 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='newdos.zip' +OPTION_LIST='ENTRY=new1.dos' ZIPPED=1; +INSERT INTO t1 VALUES(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),(5,'Five'),(6,'Six'),(7,'Seven'),(8,'Eight'),(9,'Nine'),(10,'Ten'); +SELECT * FROM t1; + +CREATE TABLE t2 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='newdos.zip' +OPTION_LIST='ENTRY=new2.dos,APPEND=1' ZIPPED=1; +INSERT INTO t2 VALUES(11,'Eleven'),(12,'Twelve'),(13,'Thirteen'),(14,'Fourteen'),(15,'Fiften'),(16,'Sixteen'),(17,'Seventeen'),(18,'Eighteen'),(19,'Nineteen'),(20,'Twenty'); +SELECT * FROM t2; + +CREATE TABLE t3 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=DOS FILE_NAME='newdos.zip' +OPTION_LIST='MULENTRIES=1' ZIPPED=1; +SELECT * FROM t3; + +CREATE TABLE t4 ( +fn VARCHAR(256)NOT NULL, +cmpsize BIGINT NOT NULL FLAG=1, +uncsize BIGINT NOT NULL FLAG=2, +method INT NOT NULL FLAG=3) +ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='newdos.zip'; +SELECT * FROM t4; +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # Testing zipped CSV tables +--echo # +CREATE TABLE t1 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='ENTRY=new1.csv' HEADER=1 ZIPPED=1; +INSERT INTO t1 VALUES(1,'One'),(2,'Two'),(3,'Three'),(4,'Four'),(5,'Five'),(6,'Six'),(7,'Seven'),(8,'Eight'),(9,'Nine'),(10,'Ten'); +SELECT * FROM t1; + +# Test discovery +CREATE TABLE td1 +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='ENTRY=new1.csv' HEADER=1 ZIPPED=1; +SELECT * FROM td1; +DROP TABLE td1; + +CREATE TABLE t2 ( +digit INT(3) NOT NULL, +letter CHAR(16) NOT NULL) +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='ENTRY=new2.csv,APPEND=1' HEADER=1 ZIPPED=1; +INSERT INTO t2 VALUES(11,'Eleven'),(12,'Twelve'),(13,'Thirteen'),(14,'Fourteen'),(15,'Fiften'),(16,'Sixteen'),(17,'Seventeen'),(18,'Eighteen'),(19,'Nineteen'),(20,'Twenty'); +SELECT * FROM t2; + +CREATE TABLE t3 +ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='newcsv.zip' +OPTION_LIST='MULENTRIES=1' HEADER=1 ZIPPED=1; +SELECT * FROM t3; + +CREATE TABLE t4 ( +fn VARCHAR(256)NOT NULL, +cmpsize BIGINT NOT NULL FLAG=1, +uncsize BIGINT NOT NULL FLAG=2, +method INT NOT NULL FLAG=3) +ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='newcsv.zip'; +SELECT * FROM t4; +DROP TABLE t1,t2,t3,t4; + +--echo # +--echo # Testing zipped JSON tables +--echo # +CREATE TABLE t1 ( +_id INT(2) NOT NULL, +name_first CHAR(9) NOT NULL FIELD_FORMAT='name:first', +name_aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka', +name_last CHAR(10) NOT NULL FIELD_FORMAT='name:last', +title CHAR(12) DEFAULT NULL, +birth CHAR(20) DEFAULT NULL, +death CHAR(20) DEFAULT NULL, +contribs CHAR(7) NOT NULL FIELD_FORMAT='contribs:', +awards_award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards::award', +awards_year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards::year', +awards_by CHAR(38) DEFAULT NULL FIELD_FORMAT='awards::by' +) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.zip' OPTION_LIST='ENTRY=bios.json,LOAD=bios.json' ZIPPED=YES; +SELECT * FROM t1; + +# Test discovery +CREATE TABLE t2 +ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='bios.zip' ZIPPED=1 +OPTION_LIST='LEVEL=5'; +SELECT * FROM t2; + +CREATE TABLE t3 ( +_id INT(2) NOT NULL, +firstname CHAR(9) NOT NULL FIELD_FORMAT='name:first', +aka CHAR(4) DEFAULT NULL FIELD_FORMAT='name:aka', +lastname CHAR(10) NOT NULL FIELD_FORMAT='name:last', +title CHAR(12) DEFAULT NULL, +birth date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'", +death date DEFAULT NULL date_format="YYYY-DD-MM'T'hh:mm:ss'Z'", +contribs CHAR(64) NOT NULL FIELD_FORMAT='contribs:[", "]', +award CHAR(42) DEFAULT NULL FIELD_FORMAT='awards:[x]:award', +year CHAR(4) DEFAULT NULL FIELD_FORMAT='awards:[x]:year', +`by` CHAR(38) DEFAULT NULL FIELD_FORMAT='awards:[x]:by' +) ENGINE=CONNECT TABLE_TYPE='json' FILE_NAME='bios.zip' ZIPPED=YES; +SELECT * FROM t3 WHERE _id = 1; + +CREATE TABLE t4 ( +fn VARCHAR(256)NOT NULL, +cmpsize BIGINT NOT NULL FLAG=1, +uncsize BIGINT NOT NULL FLAG=2, +method INT NOT NULL FLAG=3) +ENGINE=CONNECT TABLE_TYPE=ZIP FILE_NAME='bios.zip'; +SELECT * FROM t4; +DROP TABLE t1,t2,t3,t4; + +# +# Clean up +# +--remove_file $MYSQLD_DATADIR/test/newdos.zip +--remove_file $MYSQLD_DATADIR/test/newcsv.zip +--remove_file $MYSQLD_DATADIR/test/bios.zip +--remove_file $MYSQLD_DATADIR/test/bios.json + diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 7320f4cc1d9..433e392eace 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -35,8 +35,8 @@ #include "global.h" #include "plgdbsem.h" #include "xobject.h" -//#include "kindex.h" #include "xtable.h" +#include "tabext.h" #include "odbccat.h" #include "tabodbc.h" #include "plgcnx.h" // For DB types @@ -413,12 +413,20 @@ PQRYRES ODBCColumns(PGLOBAL g, char *dsn, char *db, char *table, /**************************************************************************/ PQRYRES ODBCSrcCols(PGLOBAL g, char *dsn, char *src, POPARM sop) { + char *sqry; ODBConn *ocp = new(g) ODBConn(g, NULL); if (ocp->Open(dsn, sop, 10) < 1) // openReadOnly + noOdbcDialog return NULL; - return ocp->GetMetaData(g, dsn, src); + if (strstr(src, "%s")) { + // Place holder for an eventual where clause + sqry = (char*)PlugSubAlloc(g, NULL, strlen(src) + 3); + sprintf(sqry, src, "1=1", "1=1"); // dummy where clause + } else + sqry = src; + + return ocp->GetMetaData(g, dsn, sqry); } // end of ODBCSrcCols #if 0 @@ -1417,7 +1425,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) b = true; if (trace) - htrc("ExecDirect hstmt=%p %.64s\n", hstmt, sql); + htrc("ExecDirect hstmt=%p %.256s\n", hstmt, sql); if (m_Tdb->Srcdef) { // Be sure this is a query returning a result set diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index cb408494319..800b1098d50 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -1,7 +1,7 @@ /************** PlgDBSem H Declares Source Code File (.H) **************/ /* Name: PLGDBSEM.H Version 3.7 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */ /* */ /* This file contains the CONNECT storage engine definitions. */ /***********************************************************************/ @@ -57,7 +57,7 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */ TAB_FIX = 2, /* Fixed column offset, fixed LRECL */ TAB_BIN = 3, /* Like FIX but can have binary fields */ TAB_CSV = 4, /* DOS files with CSV records */ - TAB_FMT = 5, /* DOS files with formatted recordss */ + TAB_FMT = 5, /* DOS files with formatted records */ TAB_DBF = 6, /* DBF Dbase or Foxpro files */ TAB_XML = 7, /* XML or HTML files */ TAB_INI = 8, /* INI or CFG files */ @@ -212,11 +212,24 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */ OP_SUB = 17, /* Expression Substract operator */ OP_MULT = 18, /* Expression Multiply operator */ OP_DIV = 19, /* Expression Divide operator */ - OP_NOP = 21, /* Scalar function is nopped */ OP_NUM = 22, /* Scalar function Op Num */ - OP_ABS = 23, /* Scalar function Op Abs */ OP_MAX = 24, /* Scalar function Op Max */ OP_MIN = 25, /* Scalar function Op Min */ + OP_EXP = 36, /* Scalar function Op Exp */ + OP_FDISK = 94, /* Operator Disk of fileid */ + OP_FPATH = 95, /* Operator Path of fileid */ + OP_FNAME = 96, /* Operator Name of fileid */ + OP_FTYPE = 97, /* Operator Type of fileid */ + OP_LAST = 82, /* Index operator Find Last */ + OP_FIRST = 106, /* Index operator Find First */ + OP_NEXT = 107, /* Index operator Find Next */ + OP_SAME = 108, /* Index operator Find Next Same */ + OP_FSTDIF = 109, /* Index operator Find First dif */ + OP_NXTDIF = 110, /* Index operator Find Next dif */ + OP_PREV = 116}; /* Index operator Find Previous */ +#if 0 + OP_NOP = 21, /* Scalar function is nopped */ + OP_ABS = 23, /* Scalar function Op Abs */ OP_CEIL = 26, /* Scalar function Op Ceil */ OP_FLOOR = 27, /* Scalar function Op Floor */ OP_MOD = 28, /* Scalar function Op Mod */ @@ -312,6 +325,7 @@ enum OPVAL {OP_EQ = 1, /* Filtering operator = */ OP_REMOVE = 201, /* Scalar function Op Remove */ OP_RENAME = 202, /* Scalar function Op Rename */ OP_FCOMP = 203}; /* Scalar function Op Compare */ +#endif // 0 enum TUSE {USE_NO = 0, /* Table is not yet linearized */ USE_LIN = 1, /* Table is linearized */ @@ -356,6 +370,7 @@ typedef class XOBJECT *PXOB; typedef class COLBLK *PCOL; typedef class TDB *PTDB; typedef class TDBASE *PTDBASE; +typedef class TDBEXT *PTDBEXT; typedef class TDBDOS *PTDBDOS; typedef class TDBFIX *PTDBFIX; typedef class TDBFMT *PTDBFMT; @@ -374,6 +389,7 @@ typedef class KXYCOL *PXCOL; typedef class CATALOG *PCATLG; typedef class RELDEF *PRELDEF; typedef class TABDEF *PTABDEF; +typedef class EXTDEF *PEXTBDEF; typedef class DOSDEF *PDOSDEF; typedef class CSVDEF *PCSVDEF; typedef class VCTDEF *PVCTDEF; @@ -619,4 +635,4 @@ int global_open(GLOBAL *g, int msgid, const char *filename, int flags, int mode) DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR name, LPCSTR dir); char *MakeEscape(PGLOBAL g, char* str, char q); -DllExport bool PushWarning(PGLOBAL, PTDBASE, int level = 1); +DllExport bool PushWarning(PGLOBAL, PTDB, int level = 1); diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 83975c6d8fa..1910cdcdec8 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -1,11 +1,11 @@ /********** PlgDBUtl Fpe C++ Program Source Code File (.CPP) ***********/ /* PROGRAM NAME: PLGDBUTL */ /* ------------- */ -/* Version 3.9 */ +/* Version 4.0 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -939,7 +939,11 @@ int PlugCloseFile(PGLOBAL g __attribute__((unused)), PFBLOCK fp, bool all) #endif // LIBXML2_SUPPORT #ifdef ZIP_SUPPORT case TYPE_FB_ZIP: - ((ZIPUTIL*)fp->File)->close(); + if (fp->Mode == MODE_INSERT) + ((ZIPUTIL*)fp->File)->close(); + else + ((UNZIPUTL*)fp->File)->close(); + fp->Memory = NULL; fp->Mode = MODE_ANY; fp->Count = 0; @@ -1119,7 +1123,7 @@ char *GetAmName(PGLOBAL g, AMT am, void *memp) return amn; } // end of GetAmName -#if defined(__WIN__) && !defined(NOCATCH) +#if defined(SE_CATCH) /***********************************************************************/ /* GetExceptionDesc: return the description of an exception code. */ /***********************************************************************/ @@ -1207,7 +1211,7 @@ char *GetExceptionDesc(PGLOBAL g, unsigned int e) return p; } // end of GetExceptionDesc -#endif // __WIN__ && !NOCATCH +#endif // SE_CATCH /***********************************************************************/ /* PlgDBalloc: allocates or suballocates memory conditionally. */ diff --git a/storage/connect/plgxml.cpp b/storage/connect/plgxml.cpp index 71b72621b06..eb31e24235b 100644 --- a/storage/connect/plgxml.cpp +++ b/storage/connect/plgxml.cpp @@ -1,6 +1,6 @@ /******************************************************************/ /* Implementation of XML document processing using PdbXML. */ -/* Author: Olivier Bertrand 2007-2012 */ +/* Author: Olivier Bertrand 2007-2017 */ /******************************************************************/ #include "my_global.h" #include "global.h" @@ -49,7 +49,7 @@ bool XMLDOCUMENT::InitZip(PGLOBAL g, char *entry) { #if defined(ZIP_SUPPORT) bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false; - zip = new(g) ZIPUTIL(entry, mul); + zip = new(g) UNZIPUTL(entry, mul); return zip == NULL; #else // !ZIP_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); diff --git a/storage/connect/plgxml.h b/storage/connect/plgxml.h index db7dfa6bda5..6870764c503 100644 --- a/storage/connect/plgxml.h +++ b/storage/connect/plgxml.h @@ -101,7 +101,7 @@ class XMLDOCUMENT : public BLOCK { // Members #if defined(ZIP_SUPPORT) - ZIPUTIL *zip; /* Used for zipped file */ + UNZIPUTL *zip; /* Used for zipped file */ #else // !ZIP_SUPPORT bool zip; /* Always false */ #endif // !ZIP_SUPPORT diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c index 2551b603349..bfac8a5fd99 100644 --- a/storage/connect/plugutil.c +++ b/storage/connect/plugutil.c @@ -244,6 +244,9 @@ LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) char *drive = NULL, *defdrv = NULL; #endif + if (trace > 1) + htrc("prefix=%s fn=%s path=%s\n", prefix, FileName, defpath); + if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) { strcpy(pBuff, FileName); // Remote file return pBuff; diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index ef91414a9ab..c6878737f1d 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -621,8 +621,8 @@ bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int) /***********************************************************************/ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) { - RECFM rfm; - PTDBASE tdbp = NULL; + RECFM rfm; + PTDB tdbp = NULL; // If define block not here yet, get it now if (!Pxdef && !(Pxdef = GetXdef(g))) @@ -632,7 +632,7 @@ PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode) /* Allocate a TDB of the proper type. */ /* Column blocks will be allocated only when needed. */ /*********************************************************************/ - if (!(tdbp = (PTDBASE)Pxdef->GetTable(g, mode))) + if (!(tdbp = Pxdef->GetTable(g, mode))) return NULL; else rfm = tdbp->GetFtype(); diff --git a/storage/connect/reldef.h b/storage/connect/reldef.h index bc1bd2ddd74..52a131dbf3d 100644 --- a/storage/connect/reldef.h +++ b/storage/connect/reldef.h @@ -64,15 +64,16 @@ class DllExport RELDEF : public BLOCK { // Relation definition block }; // end of RELDEF /***********************************************************************/ -/* These classes correspond to the data base description contained in */ -/* a .XDB file the A.M. DOS, FIX, CSV, MAP, BIN, VCT, PLG, ODBC, DOM. */ +/* This class corresponds to the data base description for tables */ +/* of type DOS, FIX, CSV, DBF, BIN, VCT, JSON, XML... */ /***********************************************************************/ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ friend class CATALOG; friend class PLUGCAT; friend class MYCAT; - friend class TDBASE; - public: + friend class TDB; + friend class TDBEXT; +public: // Constructor TABDEF(void); // Constructor @@ -112,11 +113,11 @@ class DllExport TABDEF : public RELDEF { /* Logical table descriptor */ int Sort; /* Table already sorted ??? */ int Multiple; /* 0: No 1: DIR 2: Section 3: filelist */ int Degree; /* Number of columns in the table */ - int Pseudo; /* Bit: 1 ROWID Ok, 2 FILEID Ok */ + int Pseudo; /* Bit: 1 ROWID }Ok, 2 FILEID Ok */ bool Read_Only; /* true for read only tables */ const CHARSET_INFO *m_data_charset; const char *csname; /* Table charset name */ - }; // end of TABDEF +}; // end of TABDEF /***********************************************************************/ /* Externally defined OEM tables. */ @@ -190,11 +191,12 @@ class DllExport COLCRT : public BLOCK { /* Column description block /***********************************************************************/ /* Column definition block. */ /***********************************************************************/ -class DllExport COLDEF : public COLCRT { /* Column description block */ +class DllExport COLDEF : public COLCRT { /* Column description block */ friend class TABDEF; friend class COLBLK; friend class DBFFAM; - friend class TDBASE; + friend class TDB; + friend class TDBASE; friend class TDBDOS; public: COLDEF(void); // Constructor diff --git a/storage/connect/tabdos.cpp b/storage/connect/tabdos.cpp index 16cc6c33b44..d2bb3d7a4af 100644 --- a/storage/connect/tabdos.cpp +++ b/storage/connect/tabdos.cpp @@ -102,6 +102,7 @@ DOSDEF::DOSDEF(void) Mapped = false; Zipped = false; Mulentries = false; + Append = false; Padded = false; Huge = false; Accept = false; @@ -132,10 +133,13 @@ bool DOSDEF::DefineAM(PGLOBAL g, LPCSTR am, int) : (am && (*am == 'B' || *am == 'b')) ? "B" : (am && !stricmp(am, "DBF")) ? "D" : "V"; - if ((Zipped = GetBoolCatInfo("Zipped", false))) - Mulentries = ((Entry = GetStringCatInfo(g, "Entry", NULL))) - ? strchr(Entry, '*') || strchr(Entry, '?') - : GetBoolCatInfo("Mulentries", false); + if ((Zipped = GetBoolCatInfo("Zipped", false))) { + Entry = GetStringCatInfo(g, "Entry", NULL); + Mulentries = (Entry && *Entry) ? strchr(Entry, '*') || strchr(Entry, '?') + : false; + Mulentries = GetBoolCatInfo("Mulentries", Mulentries); + Append = GetBoolCatInfo("Append", false); + } Desc = Fn = GetStringCatInfo(g, "Filename", NULL); Ofn = GetStringCatInfo(g, "Optname", Fn); @@ -347,10 +351,26 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) if (Zipped) { #if defined(ZIP_SUPPORT) if (Recfm == RECFM_VAR) { - txfp = new(g)ZIPFAM(this); - tdbp = new(g)TDBDOS(this, txfp); + if (mode == MODE_READ || mode == MODE_ANY) { + txfp = new(g) UNZFAM(this); + } else if (mode == MODE_INSERT) { + txfp = new(g) ZIPFAM(this); + } else { + strcpy(g->Message, "UPDATE/DELETE not supported for ZIP"); + return NULL; + } // endif's mode + + tdbp = new(g) TDBDOS(this, txfp); } else { - txfp = new(g)ZPXFAM(this); + if (mode == MODE_READ || mode == MODE_ANY) { + txfp = new(g) UZXFAM(this); + } else if (mode == MODE_INSERT) { + txfp = new(g) ZPXFAM(this); + } else { + strcpy(g->Message, "UPDATE/DELETE not supported for ZIP"); + return NULL; + } // endif's mode + tdbp = new(g)TDBFIX(this, txfp); } // endif Recfm @@ -376,7 +396,7 @@ PTDB DOSDEF::GetTable(PGLOBAL g, MODE mode) txfp = new(g) MPXFAM(this); else if (Compressed) { #if defined(GZ_SUPPORT) - txfp = new(g) ZIXFAM(this); + txfp = new(g) GZXFAM(this); #else // !GZ_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "GZ"); return NULL; @@ -484,7 +504,7 @@ TDBDOS::TDBDOS(PGLOBAL g, PTDBDOS tdbp) : TDBASE(tdbp) } // end of TDBDOS copy constructor // Method -PTDB TDBDOS::CopyOne(PTABS t) +PTDB TDBDOS::Clone(PTABS t) { PTDB tp; PDOSCOL cp1, cp2; @@ -498,7 +518,7 @@ PTDB TDBDOS::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate DOS column description block. */ diff --git a/storage/connect/tabdos.h b/storage/connect/tabdos.h index 4c8eb438a26..922d52ee399 100644 --- a/storage/connect/tabdos.h +++ b/storage/connect/tabdos.h @@ -28,7 +28,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */ friend class TDBFIX; friend class TXTFAM; friend class DBFBASE; - friend class ZIPUTIL; + friend class UNZIPUTL; public: // Constructor DOSDEF(void); @@ -43,7 +43,8 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */ PSZ GetOfn(void) {return Ofn;} PSZ GetEntry(void) {return Entry;} bool GetMul(void) {return Mulentries;} - void SetBlock(int block) {Block = block;} + bool GetAppend(void) {return Append;} + void SetBlock(int block) { Block = block; } int GetBlock(void) {return Block;} int GetLast(void) {return Last;} void SetLast(int last) {Last = last;} @@ -81,6 +82,7 @@ class DllExport DOSDEF : public TABDEF { /* Logical table description */ bool Mapped; /* 0: disk file, 1: memory mapped file */ bool Zipped; /* true for zipped table file */ bool Mulentries; /* true for multiple entries */ + bool Append; /* Used when creating zipped table */ bool Padded; /* true for padded table file */ bool Huge; /* true for files larger than 2GB */ bool Accept; /* true if wrong lines are accepted */ @@ -140,7 +142,7 @@ class DllExport TDBDOS : public TDBASE { {return (PTDB)new(g) TDBDOS(g, this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual void ResetDB(void) {Txfp->Reset();} virtual bool IsUsingTemp(PGLOBAL g); virtual bool IsIndexed(void) {return Indxd;} diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp new file mode 100644 index 00000000000..e3518126a49 --- /dev/null +++ b/storage/connect/tabext.cpp @@ -0,0 +1,640 @@ +/************* Tabext C++ Functions Source Code File (.CPP) ************/ +/* Name: TABEXT.CPP Version 1.0 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* */ +/* This file contains the TBX, TDB and OPJOIN classes functions. */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant MariaDB header file. */ +/***********************************************************************/ +#define MYSQL_SERVER 1 +#include "my_global.h" +#include "sql_class.h" +#include "sql_servers.h" +#include "sql_string.h" +#if !defined(__WIN__) +#include "osutil.h" +#endif + +/***********************************************************************/ +/* Include required application header files */ +/* global.h is header containing all global Plug declarations. */ +/* plgdbsem.h is header containing the DB applic. declarations. */ +/* xobject.h is header containing XOBJECT derived classes declares. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "xtable.h" +#include "tabext.h" +#include "ha_connect.h" + +/* -------------------------- Class CONDFIL -------------------------- */ + +/***********************************************************************/ +/* CONDFIL Constructor. */ +/***********************************************************************/ +CONDFIL::CONDFIL(const Item *cond, uint idx, AMT type) +{ + Cond = cond; + Idx = idx; + Type = type; + Op = OP_XX; + Cmds = NULL; + Alist = NULL; + All = true; + Bd = false; + Hv = false; + Body = NULL, + Having = NULL; +} // end of CONDFIL constructor + +/***********************************************************************/ +/* Make and allocate the alias list. */ +/***********************************************************************/ +int CONDFIL::Init(PGLOBAL g, PHC hc) +{ + PTOS options = hc->GetTableOptionStruct(); + char *p, *cn, *cal, *alt = NULL; + int rc = RC_OK; + bool h; + + if (options) + alt = GetListOption(g, "Alias", options->oplist, NULL); + + while (alt) { + if (!(p = strchr(alt, '='))) { + strcpy(g->Message, "Invalid alias list"); + rc = RC_FX; + break; + } // endif !p + + cal = alt; // Alias + *p++ = 0; + + if ((h = *p == '*')) { + rc = RC_INFO; + p++; + } // endif h + + cn = p; // Remote column name + + if ((alt = strchr(p, ';'))) + *alt++ = 0; + + if (*cn == 0) + cn = alt; + + Alist = new(g) ALIAS(Alist, cn, cal, h); + } // endwhile alt + + return rc; +} // end of Init + +/***********************************************************************/ +/* Make and allocate the alias list. */ +/***********************************************************************/ +const char *CONDFIL::Chk(const char *fln, bool *h) +{ + for (PAL pal = Alist; pal; pal = pal->Next) + if (!stricmp(fln, pal->Alias)) { + *h = pal->Having; + return pal->Name; + } // endif fln + + *h = false; + return fln; +} // end of Chk + +/* --------------------------- Class EXTDEF -------------------------- */ + +/***********************************************************************/ +/* EXTDEF Constructor. */ +/***********************************************************************/ +EXTDEF::EXTDEF(void) +{ + Tabname = Tabschema = Username = Password = Tabcat = Tabtyp = NULL; + Colpat = Srcdef = Qchar = Qrystr = Sep = Phpos = NULL; + Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0; + Scrollable = Xsrc = false; +} // end of EXTDEF constructor + +/***********************************************************************/ +/* DefineAM: define specific AM block values from XDB file. */ +/***********************************************************************/ +bool EXTDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) +{ + Desc = NULL; + Tabname = GetStringCatInfo(g, "Name", + (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); + Tabname = GetStringCatInfo(g, "Tabname", Tabname); + Tabschema = GetStringCatInfo(g, "Dbname", NULL); + Tabschema = GetStringCatInfo(g, "Schema", Tabschema); + Tabcat = GetStringCatInfo(g, "Qualifier", NULL); + Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); + Username = GetStringCatInfo(g, "User", NULL); + Password = GetStringCatInfo(g, "Password", NULL); + + if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) + Read_Only = true; + + Qrystr = GetStringCatInfo(g, "Query_String", "?"); + Sep = GetStringCatInfo(g, "Separator", NULL); +//Alias = GetStringCatInfo(g, "Alias", NULL); + Phpos = GetStringCatInfo(g, "Phpos", NULL); + Xsrc = GetBoolCatInfo("Execsrc", FALSE); + Maxerr = GetIntCatInfo("Maxerr", 0); + Maxres = GetIntCatInfo("Maxres", 0); + Quoted = GetIntCatInfo("Quoted", 0); + Options = 0; + Cto = 0; + Qto = 0; + + if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt) + Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch + + if (Catfunc == FNC_COL) + Colpat = GetStringCatInfo(g, "Colpat", NULL); + + if (Catfunc == FNC_TABLE) + Tabtyp = GetStringCatInfo(g, "Tabtype", NULL); + + // Memory was Boolean, it is now integer + if (!(Memory = GetIntCatInfo("Memory", 0))) + Memory = GetBoolCatInfo("Memory", false) ? 1 : 0; + + Pseudo = 2; // FILID is Ok but not ROWID + return false; +} // end of DefineAM + +/* ---------------------------TDBEXT class --------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBEXT class. */ +/***********************************************************************/ +TDBEXT::TDBEXT(EXTDEF *tdp) : TDB(tdp) +{ + Qrp = NULL; + + if (tdp) { + TableName = tdp->Tabname; + Schema = tdp->Tabschema; + User = tdp->Username; + Pwd = tdp->Password; + Catalog = tdp->Tabcat; + Srcdef = tdp->Srcdef; + Qrystr = tdp->Qrystr; + Sep = tdp->GetSep(); + Options = tdp->Options; + Cto = tdp->Cto; + Qto = tdp->Qto; + Quoted = MY_MAX(0, tdp->GetQuoted()); + Rows = tdp->GetElemt(); + Memory = tdp->Memory; + Scrollable = tdp->Scrollable; + } else { + TableName = NULL; + Schema = NULL; + User = NULL; + Pwd = NULL; + Catalog = NULL; + Srcdef = NULL; + Qrystr = NULL; + Sep = 0; + Options = 0; + Cto = 0; + Qto = 0; + Quoted = 0; + Rows = 0; + Memory = 0; + Scrollable = false; + } // endif tdp + + Quote = NULL; + Query = NULL; + Count = NULL; + //Where = NULL; + MulConn = NULL; + DBQ = NULL; + Qrp = NULL; + Fpos = 0; + Curpos = 0; + AftRows = 0; + CurNum = 0; + Rbuf = 0; + BufSize = 0; + Nparm = 0; + Ncol = 0; + Placed = false; +} // end of TDBEXT constructor + +TDBEXT::TDBEXT(PTDBEXT tdbp) : TDB(tdbp) +{ + Qrp = tdbp->Qrp; + TableName = tdbp->TableName; + Schema = tdbp->Schema; + User = tdbp->User; + Pwd = tdbp->Pwd; + Catalog = tdbp->Catalog; + Srcdef = tdbp->Srcdef; + Qrystr = tdbp->Qrystr; + Sep = tdbp->Sep; + Options = tdbp->Options; + Cto = tdbp->Cto; + Qto = tdbp->Qto; + Quoted = tdbp->Quoted; + Rows = tdbp->Rows; + Memory = tdbp->Memory; + Scrollable = tdbp->Scrollable; + Quote = tdbp->Quote; + Query = tdbp->Query; + Count = tdbp->Count; + //Where = tdbp->Where; + MulConn = tdbp->MulConn; + DBQ = tdbp->DBQ; + Fpos = 0; + Curpos = 0; + AftRows = 0; + CurNum = 0; + Rbuf = 0; + BufSize = tdbp->BufSize; + Nparm = tdbp->Nparm; + Ncol = tdbp->Ncol; + Placed = false; +} // end of TDBEXT copy constructor + +/******************************************************************/ +/* Convert an UTF-8 string to latin characters. */ +/******************************************************************/ +int TDBEXT::Decode(char *txt, char *buf, size_t n) +{ + uint dummy_errors; + uint32 len = copy_and_convert(buf, n, &my_charset_latin1, + txt, strlen(txt), + &my_charset_utf8_general_ci, + &dummy_errors); + buf[len] = '\0'; + return 0; +} // end of Decode + +/***********************************************************************/ +/* MakeSQL: make the SQL statement use with remote connection. */ +/* TODO: when implementing remote filtering, column only used in */ +/* local filter should be removed from column list. */ +/***********************************************************************/ +bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt) +{ + char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3]; + int len; + bool oom = false, first = true; + PTABLE tablep = To_Table; + PCOL colp; + + if (Srcdef) { + if ((catp = strstr(Srcdef, "%s"))) { + char *fil1, *fil2; + PSZ ph = ((EXTDEF*)To_Def)->Phpos; + + if (!ph) + ph = (strstr(catp + 2, "%s")) ? const_cast<char*>("WH") : + const_cast<char*>("W"); + + if (stricmp(ph, "H")) { + fil1 = (To_CondFil && *To_CondFil->Body) + ? To_CondFil->Body : PlugDup(g, "1=1"); + } // endif ph + + if (stricmp(ph, "W")) { + fil2 = (To_CondFil && To_CondFil->Having && *To_CondFil->Having) + ? To_CondFil->Having : PlugDup(g, "1=1"); + } // endif ph + + if (!stricmp(ph, "W")) { + Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1)); + Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1)); + } else if (!stricmp(ph, "WH")) { + Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2)); + Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil1, fil2)); + } else if (!stricmp(ph, "H")) { + Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil2)); + Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2)); + } else if (!stricmp(ph, "HW")) { + Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil1) + strlen(fil2)); + Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil2, fil1)); + } else { + strcpy(g->Message, "MakeSQL: Wrong place holders specification"); + return true; + } // endif's ph + + } else + Query = new(g)STRING(g, 0, Srcdef); + + return false; + } // endif Srcdef + + // Allocate the string used to contain the Query + Query = new(g)STRING(g, 1023, "SELECT "); + + if (!cnt) { + if (Columns) { + // Normal SQL statement to retrieve results + for (colp = Columns; colp; colp = colp->GetNext()) + if (!colp->IsSpecial()) { + if (!first) + oom |= Query->Append(", "); + else + first = false; + + // Column name can be encoded in UTF-8 + Decode(colp->GetName(), buf, sizeof(buf)); + + 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); + } else + oom |= Query->Append(buf); + + ((PEXTCOL)colp)->SetRank(++Ncol); + } // endif colp + + } else + // !Columns can occur for queries such that sql count(*) from... + // for which we will count the rows from sql * from... + oom |= Query->Append('*'); + + } else + // SQL statement used to retrieve the size of the result + oom |= Query->Append("count(*)"); + + oom |= Query->Append(" FROM "); + + if (Catalog && *Catalog) + catp = Catalog; + + //if (tablep->GetSchema()) + // schmp = (char*)tablep->GetSchema(); + //else + if (Schema && *Schema) + schmp = Schema; + + if (catp) { + oom |= Query->Append(catp); + + if (schmp) { + oom |= Query->Append('.'); + oom |= Query->Append(schmp); + } // endif schmp + + oom |= Query->Append('.'); + } else if (schmp) { + oom |= Query->Append(schmp); + oom |= Query->Append('.'); + } // endif schmp + + // Table name can be encoded in UTF-8 + Decode(TableName, buf, sizeof(buf)); + + 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); + } else + oom |= Query->Append(buf); + + len = Query->GetLength(); + + if (To_CondFil) { + if (Mode == MODE_READ) { + oom |= Query->Append(" WHERE "); + oom |= Query->Append(To_CondFil->Body); + len = Query->GetLength() + 1; + } else + len += (strlen(To_CondFil->Body) + 256); + + } else + len += ((Mode == MODE_READX) ? 256 : 1); + + if (oom || Query->Resize(len)) { + strcpy(g->Message, "MakeSQL: Out of memory"); + return true; + } // endif oom + + if (trace) + htrc("Query=%s\n", Query->GetStr()); + + return false; +} // end of MakeSQL + +/***********************************************************************/ +/* MakeCommand: make the Update or Delete statement to send to the */ +/* MySQL server. Limited to remote values and filtering. */ +/***********************************************************************/ +bool TDBEXT::MakeCommand(PGLOBAL g) +{ + char *p, *stmt, name[68], *body = NULL; + char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1); + bool qtd = Quoted > 0; + int i = 0, k = 0; + + // Make a lower case copy of the originale query and change + // back ticks to the data source identifier quoting character + do { + qrystr[i] = (Qrystr[i] == '`') ? *Quote : tolower(Qrystr[i]); + } while (Qrystr[i++]); + + if (To_CondFil && (p = strstr(qrystr, " where "))) { + p[7] = 0; // Remove where clause + Qrystr[(p - qrystr) + 7] = 0; + body = To_CondFil->Body; + stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr) + + strlen(body) + 64); + } else + stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); + + // Check whether the table name is equal to a keyword + // If so, it must be quoted in the original query + strlwr(strcat(strcat(strcpy(name, " "), Name), " ")); + + if (strstr(" update delete low_priority ignore quick from ", name)) { + strlwr(strcat(strcat(strcpy(name, Quote), Name), Quote)); + k += 2; + } else + strlwr(strcpy(name, Name)); // Not a keyword + + if ((p = strstr(qrystr, name))) { + for (i = 0; i < p - qrystr; i++) + stmt[i] = (Qrystr[i] == '`') ? *Quote : Qrystr[i]; + + stmt[i] = 0; + k += i + (int)strlen(Name); + + if (qtd && *(p - 1) == ' ') + strcat(strcat(strcat(stmt, Quote), TableName), Quote); + else + strcat(stmt, TableName); + + i = (int)strlen(stmt); + + do { + stmt[i++] = (Qrystr[k] == '`') ? *Quote : Qrystr[k]; + } while (Qrystr[k++]); + + if (body) + strcat(stmt, body); + + } else { + sprintf(g->Message, "Cannot use this %s command", + (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); + return true; + } // endif p + + if (trace) + htrc("Command=%s\n", stmt); + + Query = new(g)STRING(g, 0, stmt); + return (!Query->GetSize()); +} // end of MakeCommand + +/***********************************************************************/ +/* GetRecpos: return the position of last read record. */ +/***********************************************************************/ +int TDBEXT::GetRecpos(void) +{ + return Fpos; +} // end of GetRecpos + +/***********************************************************************/ +/* ODBC GetMaxSize: returns table size estimate in number of lines. */ +/***********************************************************************/ +int TDBEXT::GetMaxSize(PGLOBAL g) +{ + if (MaxSize < 0) { + if (Mode == MODE_DELETE) + // Return 0 in mode DELETE in case of delete all. + MaxSize = 0; + else if (!Cardinality(NULL)) + MaxSize = 10; // To make MySQL happy + else if ((MaxSize = Cardinality(g)) < 0) + MaxSize = 12; // So we can see an error occurred + + } // endif MaxSize + + return MaxSize; +} // end of GetMaxSize + +/***********************************************************************/ +/* Return max size value. */ +/***********************************************************************/ +int TDBEXT::GetProgMax(PGLOBAL g) +{ + return GetMaxSize(g); +} // end of GetProgMax + +/* ---------------------------EXTCOL class --------------------------- */ + +/***********************************************************************/ +/* EXTCOL public constructor. */ +/***********************************************************************/ +EXTCOL::EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) + : COLBLK(cdp, tdbp, i) +{ + if (cprec) { + Next = cprec->GetNext(); + cprec->SetNext(this); + } else { + Next = tdbp->GetColumns(); + tdbp->SetColumns(this); + } // endif cprec + + if (trace) + htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); + + // Set additional remote access method information for column. + Crp = NULL; + Long = Precision; + To_Val = NULL; + Bufp = NULL; + Blkp = NULL; + Rank = 0; // Not known yet +} // end of JDBCCOL constructor + +/***********************************************************************/ +/* EXTCOL private constructor. */ +/***********************************************************************/ +EXTCOL::EXTCOL(void) : COLBLK() +{ + Crp = NULL; + Buf_Type = TYPE_INT; // This is a count(*) column + + // Set additional Dos access method information for column. + Long = sizeof(int); + To_Val = NULL; + Bufp = NULL; + Blkp = NULL; + Rank = 1; +} // end of EXTCOL constructor + +/***********************************************************************/ +/* EXTCOL constructor used for copying columns. */ +/* tdbp is the pointer to the new table descriptor. */ +/***********************************************************************/ +EXTCOL::EXTCOL(PEXTCOL col1, PTDB tdbp) : COLBLK(col1, tdbp) +{ + Crp = col1->Crp; + Long = col1->Long; + To_Val = col1->To_Val; + Bufp = col1->Bufp; + Blkp = col1->Blkp; + Rank = col1->Rank; +} // end of JDBCCOL copy constructor + +/***********************************************************************/ +/* SetBuffer: prepare a column block for write operation. */ +/***********************************************************************/ +bool EXTCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) +{ + if (!(To_Val = value)) { + sprintf(g->Message, MSG(VALUE_ERROR), Name); + return true; + } else if (Buf_Type == value->GetType()) { + // Values are of the (good) column type + if (Buf_Type == TYPE_DATE) { + // If any of the date values is formatted + // output format must be set for the receiving table + if (GetDomain() || ((DTVAL *)value)->IsFormatted()) + goto newval; // This will make a new value; + + } else if (Buf_Type == TYPE_DOUBLE) + // Float values must be written with the correct (column) precision + // Note: maybe this should be forced by ShowValue instead of this ? + value->SetPrec(GetScale()); + + Value = value; // Directly access the external value + } else { + // Values are not of the (good) column type + if (check) { + sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name, + GetTypeName(Buf_Type), GetTypeName(value->GetType())); + return true; + } // endif check + + newval: + if (InitValue(g)) // Allocate the matching value block + return true; + + } // endif's Value, Buf_Type + + // Because Colblk's have been made from a copy of the original TDB in + // case of Update, we must reset them to point to the original one. + if (To_Tdb->GetOrig()) + To_Tdb = (PTDB)To_Tdb->GetOrig(); + + // Set the Column + Status = (ok) ? BUF_EMPTY : BUF_NO; + return false; +} // end of SetBuffer + diff --git a/storage/connect/tabext.h b/storage/connect/tabext.h new file mode 100644 index 00000000000..2ef20c89f2c --- /dev/null +++ b/storage/connect/tabext.h @@ -0,0 +1,200 @@ +/*************** Tabext H Declares Source Code File (.H) ***************/ +/* Name: TABEXT.H Version 1.0 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2017 */ +/* */ +/* This is the EXTDEF, TABEXT and EXTCOL classes definitions. */ +/***********************************************************************/ + +#ifndef __TABEXT_H +#define __TABEXTF_H + +#include "reldef.h" + +typedef class ALIAS *PAL; + +class ALIAS : public BLOCK { + public: + ALIAS(PAL x, PSZ n, PSZ a, bool h) + {Next = x, Name = n, Alias = a, Having = h;} + + PAL Next; + PSZ Name; + PSZ Alias; + bool Having; +}; // end of class ALIAS + +// Condition filter structure +class CONDFIL : public BLOCK { + public: + // Constructor + CONDFIL(const Item *cond, uint idx, AMT type); + + // Functions + int Init(PGLOBAL g, PHC hc); + const char *Chk(const char *cln, bool *h); + + // Members + const Item *Cond; + AMT Type; + uint Idx; + OPVAL Op; + PCMD Cmds; + PAL Alist; + bool All; + bool Bd; + bool Hv; + char *Body; + char *Having; +}; // end of class CONDFIL + +/***********************************************************************/ +/* This class corresponds to the data base description for external */ +/* tables of type MYSQL, ODBC, JDBC... */ +/***********************************************************************/ +class DllExport EXTDEF : public TABDEF { /* EXT table */ + friend class TDBEXT; +public: + // Constructor + EXTDEF(void); // Constructor + + // Implementation + virtual const char *GetType(void) { return "EXT"; } + inline PSZ GetTabname(void) { return Tabname; } + inline PSZ GetTabschema(void) { return Tabschema; } + inline PSZ GetUsername(void) { return Username; }; + inline PSZ GetPassword(void) { return Password; }; + inline PSZ GetTabcat(void) { return Tabcat; } + inline PSZ GetSrcdef(void) { return Srcdef; } + inline char GetSep(void) { return (Sep) ? *Sep : 0; } + inline int GetQuoted(void) { return Quoted; } + inline int GetOptions(void) { return Options; } + + // Methods + virtual int Indexable(void) { return 2; } + virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); + +protected: + // Members + PSZ Tabname; /* External table name */ + PSZ Tabschema; /* External table schema */ + PSZ Username; /* User connect name */ + PSZ Password; /* Password connect info */ + PSZ Tabcat; /* External table catalog */ + PSZ Tabtyp; /* Catalog table type */ + PSZ Colpat; /* Catalog column pattern */ + PSZ Srcdef; /* The source table SQL definition */ + PSZ Qchar; /* Identifier quoting character */ + PSZ Qrystr; /* The original query */ + PSZ Sep; /* Decimal separator */ +//PSZ Alias; /* Column alias list */ + PSZ Phpos; /* Place holer positions */ + int Options; /* Open connection options */ + int Cto; /* Open connection timeout */ + int Qto; /* Query (command) timeout */ + int Quoted; /* Identifier quoting level */ + int Maxerr; /* Maxerr for an Exec table */ + int Maxres; /* Maxres for a catalog table */ + int Memory; /* Put result set in memory */ + bool Scrollable; /* Use scrollable cursor */ + bool Xsrc; /* Execution type */ +}; // end of EXTDEF + +/***********************************************************************/ +/* This is the base class for all external tables. */ +/***********************************************************************/ +class DllExport TDBEXT : public TDB { +public: + // Constructors + TDBEXT(EXTDEF *tdp); + TDBEXT(PTDBEXT tdbp); + + // Implementation + + // Properties + virtual bool IsRemote(void) { return true; } + + // Methods + virtual PSZ GetServer(void) { return "Remote"; } + virtual int GetRecpos(void); + + // Database routines + virtual int GetMaxSize(PGLOBAL g); + virtual int GetProgMax(PGLOBAL g); + +protected: + // Internal functions + virtual bool MakeSQL(PGLOBAL g, bool cnt); + //virtual bool MakeInsert(PGLOBAL g); + virtual bool MakeCommand(PGLOBAL g); + int Decode(char *utf, char *buf, size_t n); + + // Members + PQRYRES Qrp; // Points to storage result + PSTRG Query; // Constructed SQL query + char *TableName; // Points to ODBC table name + char *Schema; // Points to ODBC table Schema + char *User; // User connect info + char *Pwd; // Password connect info + char *Catalog; // Points to ODBC table Catalog + char *Srcdef; // The source table SQL definition + char *Count; // Points to count(*) SQL statement + //char *Where; // Points to local where clause + char *Quote; // The identifier quoting character + char *MulConn; // Used for multiple ODBC tables + char *DBQ; // The address part of Connect string + char *Qrystr; // The original query + char Sep; // The decimal separator + int Options; // Connect options + int Cto; // Connect timeout + int Qto; // Query timeout + int Quoted; // The identifier quoting level + int Fpos; // Position of last read record + int Curpos; // Cursor position of last fetch + int AftRows; // The number of affected rows + int Rows; // Rowset size + int CurNum; // Current buffer line number + int Rbuf; // Number of lines read in buffer + int BufSize; // Size of connect string buffer + int Nparm; // The number of statement parameters + int Memory; // 0: No 1: Alloc 2: Put 3: Get + int Ncol; // The column number (JDBC) + bool Scrollable; // Use scrollable cursor + bool Placed; // True for position reading +}; // end of class TDBEXT + +/***********************************************************************/ +/* Virual class EXTCOL: external column. */ +/***********************************************************************/ +class DllExport EXTCOL : public COLBLK { + friend class TDBEXT; +public: + // Constructor + EXTCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am); + EXTCOL(PEXTCOL colp, PTDB tdbp); // Constructor used in copy process + + // Implementation + inline int GetRank(void) { return Rank; } + inline void SetRank(int k) { Rank = k; } + //inline PVBLK GetBlkp(void) {return Blkp;} + inline void SetCrp(PCOLRES crp) { Crp = crp; } + + // Methods + virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); + virtual void ReadColumn(PGLOBAL) = 0; + virtual void WriteColumn(PGLOBAL) = 0; + +protected: + // Constructor for count(*) column + EXTCOL(void); + + // Members + PCOLRES Crp; // To storage result + void *Bufp; // To extended buffer + PVBLK Blkp; // To Value Block + PVAL To_Val; // To value used for Insert + int Rank; // Rank (position) number in the query + //int Flag; // ??? +}; // end of class EXTCOL + +#endif // __TABEXT_H diff --git a/storage/connect/tabfix.cpp b/storage/connect/tabfix.cpp index d99f7800f26..bf123cd36c8 100644 --- a/storage/connect/tabfix.cpp +++ b/storage/connect/tabfix.cpp @@ -77,7 +77,7 @@ TDBFIX::TDBFIX(PGLOBAL g, PTDBFIX tdbp) : TDBDOS(g, tdbp) } // end of TDBFIX copy constructor // Method -PTDB TDBFIX::CopyOne(PTABS t) +PTDB TDBFIX::Clone(PTABS t) { PTDB tp; PGLOBAL g = t->G; @@ -105,7 +105,7 @@ PTDB TDBFIX::CopyOne(PTABS t) } // endif Ftype return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Reset read/write position values. */ diff --git a/storage/connect/tabfix.h b/storage/connect/tabfix.h index 49956ba0711..4b9f9689992 100644 --- a/storage/connect/tabfix.h +++ b/storage/connect/tabfix.h @@ -34,7 +34,7 @@ class DllExport TDBFIX : public TDBDOS { {return (PTDB)new(g) TDBFIX(g, this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual void ResetDB(void); virtual bool IsUsingTemp(PGLOBAL g); virtual int RowNumber(PGLOBAL g, bool b = false); diff --git a/storage/connect/tabfmt.cpp b/storage/connect/tabfmt.cpp index 183bb8f8d65..1a75d572ecd 100644 --- a/storage/connect/tabfmt.cpp +++ b/storage/connect/tabfmt.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2001 - 2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2001 - 2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -98,8 +98,9 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) int num_read = 0, num_max = 10000000; // Statistics int len[MAXCOL], typ[MAXCOL], prc[MAXCOL]; PCSVDEF tdp; - PTDBCSV tdbp; - PQRYRES qrp; + PTDBCSV tcvp; + PTDBASE tdbp; + PQRYRES qrp; PCOLRES crp; if (info) { @@ -108,10 +109,10 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) goto skipit; } // endif info - if (GetIntegerTableOption(g, topt, "Multiple", 0)) { - strcpy(g->Message, "Cannot find column definition for multiple table"); - return NULL; - } // endif Multiple + //if (GetIntegerTableOption(g, topt, "Multiple", 0)) { + // strcpy(g->Message, "Cannot find column definition for multiple table"); + // return NULL; + //} // endif Multiple // num_max = atoi(p+1); // Max num of record to test imax = hmax = nerr = 0; @@ -127,10 +128,20 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) /* Get the CSV table description block. */ /*********************************************************************/ tdp = new(g) CSVDEF; + tdp->Database = dp; + + if ((tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false))) { #if defined(ZIP_SUPPORT) - tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); - tdp->Zipped = GetBooleanTableOption(g, topt, "Zipped", false); -#endif // ZIP_SUPPORT + tdp->Entry = GetStringTableOption(g, topt, "Entry", NULL); + tdp->Mulentries = (tdp->Entry) + ? strchr(tdp->Entry, '*') || strchr(tdp->Entry, '?') + : GetBooleanTableOption(g, topt, "Mulentries", false); +#else // !ZIP_SUPPORT + strcpy(g->Message, "ZIP not supported by this version"); + return NULL; +#endif // !ZIP_SUPPORT + } // endif // Zipped + fn = tdp->Fn = GetStringTableOption(g, topt, "Filename", NULL); if (!tdp->Fn) { @@ -141,6 +152,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) if (!(tdp->Lrecl = GetIntegerTableOption(g, topt, "Lrecl", 0))) tdp->Lrecl = 4096; + tdp->Multiple = GetIntegerTableOption(g, topt, "Multiple", 0); p = GetStringTableOption(g, topt, "Separator", ","); tdp->Sep = (strlen(p) == 2 && p[0] == '\\' && p[1] == 't') ? '\t' : *p; @@ -177,17 +189,18 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) htrc("File %s Sep=%c Qot=%c Header=%d maxerr=%d\n", SVP(tdp->Fn), tdp->Sep, tdp->Qot, tdp->Header, tdp->Maxerr); - if (tdp->Zipped) { -#if defined(ZIP_SUPPORT) - tdbp = new(g)TDBCSV(tdp, new(g)ZIPFAM(tdp)); -#else // !ZIP_SUPPORT - sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); - return NULL; -#endif // !ZIP_SUPPORT - } else - tdbp = new(g) TDBCSV(tdp, new(g) DOSFAM(tdp)); + if (tdp->Zipped) + tcvp = new(g)TDBCSV(tdp, new(g)UNZFAM(tdp)); + else + tcvp = new(g) TDBCSV(tdp, new(g) DOSFAM(tdp)); + + tcvp->SetMode(MODE_READ); - tdbp->SetMode(MODE_READ); + if (tdp->Multiple) { + tdbp = new(g)TDBMUL(tcvp); + tdbp->SetMode(MODE_READ); + } else + tdbp = tcvp; /*********************************************************************/ /* Open the CSV file. */ @@ -202,7 +215,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) phase = 0; if ((rc = tdbp->ReadDB(g)) == RC_OK) { - p = PlgDBDup(g, tdbp->To_Line); + p = PlgDBDup(g, tcvp->To_Line); //skip leading blanks for (; *p == ' '; p++) ; @@ -245,6 +258,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) for (i = 0; i < hmax; i++) length[0] = MY_MAX(length[0], strlen(colname[i])); + tcvp->Header = true; // In case of multiple table } // endif hdr for (num_read++; num_read <= num_max; num_read++) { @@ -265,7 +279,7 @@ PQRYRES CSVColumns(PGLOBAL g, char *dp, PTOS topt, bool info) /*******************************************************************/ i = n = phase = blank = digit = dec = 0; - for (p = tdbp->To_Line; *p; p++) + for (p = tcvp->To_Line; *p; p++) if (*p == sep) { if (phase != 1) { if (i == MAXCOL - 1) { @@ -503,7 +517,14 @@ PTDB CSVDEF::GetTable(PGLOBAL g, MODE mode) /*******************************************************************/ if (Zipped) { #if defined(ZIP_SUPPORT) - txfp = new(g) ZIPFAM(this); + if (mode == MODE_READ || mode == MODE_ANY) { + txfp = new(g) UNZFAM(this); + } else if (mode == MODE_INSERT) { + txfp = new(g) ZIPFAM(this); + } else { + strcpy(g->Message, "UPDATE/DELETE not supported for ZIP"); + return NULL; + } // endif's mode #else // !ZIP_SUPPORT strcpy(g->Message, "ZIP not supported"); return NULL; @@ -640,7 +661,7 @@ TDBCSV::TDBCSV(PGLOBAL g, PTDBCSV tdbp) : TDBDOS(g, tdbp) } // end of TDBCSV copy constructor // Method -PTDB TDBCSV::CopyOne(PTABS t) +PTDB TDBCSV::Clone(PTABS t) { PTDB tp; PCSVCOL cp1, cp2; @@ -654,7 +675,7 @@ PTDB TDBCSV::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate CSV column description block. */ @@ -1148,7 +1169,7 @@ TDBFMT::TDBFMT(PGLOBAL g, PTDBFMT tdbp) : TDBCSV(g, tdbp) } // end of TDBFMT copy constructor // Method -PTDB TDBFMT::CopyOne(PTABS t) +PTDB TDBFMT::Clone(PTABS t) { PTDB tp; PCSVCOL cp1, cp2; @@ -1165,7 +1186,7 @@ PTDB TDBFMT::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate FMT column description block. */ diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h index 5ce8d399a64..e5655435be7 100644 --- a/storage/connect/tabfmt.h +++ b/storage/connect/tabfmt.h @@ -52,6 +52,7 @@ public: /***********************************************************************/ class DllExport TDBCSV : public TDBDOS { friend class CSVCOL; + friend class MAPFAM; friend PQRYRES CSVColumns(PGLOBAL, char *, PTOS, bool); public: // Constructor @@ -64,7 +65,7 @@ public: {return (PTDB)new(g) TDBCSV(g, this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); //virtual bool IsUsingTemp(PGLOBAL g); virtual int GetBadLines(void) {return (int)Nerr;} @@ -147,7 +148,7 @@ class DllExport TDBFMT : public TDBCSV { {return (PTDB)new(g) TDBFMT(g, this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); // Database routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index c36aa080956..5431e35e0ec 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -1,11 +1,11 @@ /************* TabJDBC C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABJDBC */ /* ------------- */ -/* Version 1.1 */ +/* Version 1.2 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2016-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -69,9 +69,10 @@ #include "plgdbsem.h" #include "mycat.h" #include "xtable.h" +#include "tabext.h" #include "tabjdbc.h" #include "tabmul.h" -#include "reldef.h" +//#include "reldef.h" #include "tabcol.h" #include "valblk.h" #include "ha_connect.h" @@ -96,10 +97,7 @@ bool ExactInfo(void); /***********************************************************************/ JDBCDEF::JDBCDEF(void) { - Driver = Url = Wrapname =Tabname = Tabschema = Username = Colpat = NULL; - Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL; - Options = Quoted = Maxerr = Maxres = Memory = 0; - Scrollable = Xsrc = false; + Driver = Url = Wrapname = NULL; } // end of JDBCDEF constructor /***********************************************************************/ @@ -134,23 +132,26 @@ bool JDBCDEF::SetParms(PJPARM sjp) int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) { if (strncmp(url, "jdbc:", 5)) { + PSZ p; + // No "jdbc:" in connection string. Must be a straight // "server" or "server/table" // ok, so we do a little parsing, but not completely! - if ((Tabname= strchr(url, '/'))) { + if ((p = strchr(url, '/'))) { // If there is a single '/' in the connection string, // this means the user is specifying a table name - *Tabname++= '\0'; + *p++= '\0'; // there better not be any more '/'s ! - if (strchr(Tabname, '/')) + if (strchr(p, '/')) return RC_FX; - } else if (b) { - // Otherwise, straight server name, - Tabname = GetStringCatInfo(g, "Name", NULL); - Tabname = GetStringCatInfo(g, "Tabname", Tabname); - } // endelse + Tabname = p; +// } else if (b) { +// // Otherwise, straight server name, +// Tabname = GetStringCatInfo(g, "Name", NULL); +// Tabname = GetStringCatInfo(g, "Tabname", Tabname); + } // endif if (trace) htrc("server: %s Tabname: %s", url, Tabname); @@ -204,6 +205,9 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { int rc = RC_OK; + if (EXTDEF::DefineAM(g, am, poff)) + return true; + Driver = GetStringCatInfo(g, "Driver", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL); @@ -223,41 +227,41 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) if (rc == RC_FX) // Error return true; - else if (rc == RC_OK) { // Url was not a server name - Tabname = GetStringCatInfo(g, "Name", - (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); - Tabname = GetStringCatInfo(g, "Tabname", Tabname); - Username = GetStringCatInfo(g, "User", NULL); - Password = GetStringCatInfo(g, "Password", NULL); - } // endif rc +//else if (rc == RC_OK) { // Url was not a server name +// Tabname = GetStringCatInfo(g, "Name", +// (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); +// Tabname = GetStringCatInfo(g, "Tabname", Tabname); +// Username = GetStringCatInfo(g, "User", NULL); +// Password = GetStringCatInfo(g, "Password", NULL); +//} // endif rc - if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) - Read_Only = true; +//if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) +// Read_Only = true; Wrapname = GetStringCatInfo(g, "Wrapper", NULL); //Prop = GetStringCatInfo(g, "Properties", NULL); - Tabcat = GetStringCatInfo(g, "Qualifier", NULL); - Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); - Tabschema = GetStringCatInfo(g, "Dbname", NULL); - Tabschema = GetStringCatInfo(g, "Schema", Tabschema); - - if (Catfunc == FNC_COL) - Colpat = GetStringCatInfo(g, "Colpat", NULL); - - if (Catfunc == FNC_TABLE) - Tabtype = GetStringCatInfo(g, "Tabtype", NULL); - - Qrystr = GetStringCatInfo(g, "Query_String", "?"); - Sep = GetStringCatInfo(g, "Separator", NULL); - Xsrc = GetBoolCatInfo("Execsrc", FALSE); - Maxerr = GetIntCatInfo("Maxerr", 0); - Maxres = GetIntCatInfo("Maxres", 0); - Quoted = GetIntCatInfo("Quoted", 0); -//Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); -//Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); - Scrollable = GetBoolCatInfo("Scrollable", false); - Memory = GetIntCatInfo("Memory", 0); - Pseudo = 2; // FILID is Ok but not ROWID +//Tabcat = GetStringCatInfo(g, "Qualifier", NULL); +//Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); +//Tabschema = GetStringCatInfo(g, "Dbname", NULL); +//Tabschema = GetStringCatInfo(g, "Schema", Tabschema); + +//if (Catfunc == FNC_COL) +// Colpat = GetStringCatInfo(g, "Colpat", NULL); + +//if (Catfunc == FNC_TABLE) +// Tabtyp = GetStringCatInfo(g, "Tabtype", NULL); + +//Qrystr = GetStringCatInfo(g, "Query_String", "?"); +//Sep = GetStringCatInfo(g, "Separator", NULL); +//Xsrc = GetBoolCatInfo("Execsrc", FALSE); +//Maxerr = GetIntCatInfo("Maxerr", 0); +//Maxres = GetIntCatInfo("Maxres", 0); +//Quoted = GetIntCatInfo("Quoted", 0); +// Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); +// Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); +//Scrollable = GetBoolCatInfo("Scrollable", false); +//Memory = GetIntCatInfo("Memory", 0); +//Pseudo = 2; // FILID is Ok but not ROWID return false; } // end of DefineAM @@ -266,7 +270,7 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) /***********************************************************************/ PTDB JDBCDEF::GetTable(PGLOBAL g, MODE m) { - PTDBASE tdbp = NULL; + PTDB tdbp = NULL; /*********************************************************************/ /* Allocate a TDB of the proper type. */ @@ -326,7 +330,7 @@ int JDBCPARM::CheckSize(int rows) /***********************************************************************/ /* Implementation of the TDBJDBC class. */ /***********************************************************************/ -TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) +TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBEXT(tdp) { Jcp = NULL; Cnp = NULL; @@ -335,101 +339,45 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) Ops.Driver = tdp->Driver; Ops.Url = tdp->Url; WrapName = tdp->Wrapname; - TableName = tdp->Tabname; - Schema = tdp->Tabschema; Ops.User = tdp->Username; Ops.Pwd = tdp->Password; // Ops.Properties = tdp->Prop; - Catalog = tdp->Tabcat; - Srcdef = tdp->Srcdef; - Qrystr = tdp->Qrystr; - Sep = tdp->GetSep(); - Options = tdp->Options; // Ops.Cto = tdp->Cto; // Ops.Qto = tdp->Qto; - Quoted = MY_MAX(0, tdp->GetQuoted()); - Rows = tdp->GetElemt(); - Memory = tdp->Memory; Ops.Scrollable = tdp->Scrollable; } else { WrapName = NULL; - TableName = NULL; - Schema = NULL; Ops.Driver = NULL; Ops.Url = NULL; Ops.User = NULL; Ops.Pwd = NULL; // Ops.Properties = NULL; - Catalog = NULL; - Srcdef = NULL; - Qrystr = NULL; - Sep = 0; - Options = 0; // Ops.Cto = DEFAULT_LOGIN_TIMEOUT; // Ops.Qto = DEFAULT_QUERY_TIMEOUT; - Quoted = 0; - Rows = 0; - Memory = 0; Ops.Scrollable = false; } // endif tdp - Quote = NULL; - Query = NULL; - Count = NULL; -//Where = NULL; - MulConn = NULL; - DBQ = NULL; - Qrp = NULL; - Fpos = 0; - Curpos = 0; - AftRows = 0; - CurNum = 0; - Rbuf = 0; - BufSize = 0; - Ncol = 0; - Nparm = 0; - Placed = false; +//Ncol = 0; Prepared = false; Werr = false; Rerr = false; Ops.Fsize = Ops.CheckSize(Rows); } // end of TDBJDBC standard constructor -TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp) +TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBEXT(tdbp) { Jcp = tdbp->Jcp; // is that right ? Cnp = tdbp->Cnp; WrapName = tdbp->WrapName; - TableName = tdbp->TableName; - Schema = tdbp->Schema; Ops = tdbp->Ops; - Catalog = tdbp->Catalog; - Srcdef = tdbp->Srcdef; - Qrystr = tdbp->Qrystr; - Memory = tdbp->Memory; -//Scrollable = tdbp->Scrollable; - Quote = tdbp->Quote; - Query = tdbp->Query; - Count = tdbp->Count; -//Where = tdbp->Where; - MulConn = tdbp->MulConn; - DBQ = tdbp->DBQ; - Options = tdbp->Options; - Quoted = tdbp->Quoted; - Rows = tdbp->Rows; - Fpos = 0; - Curpos = 0; - AftRows = 0; - CurNum = 0; - Rbuf = 0; - BufSize = tdbp->BufSize; - Nparm = tdbp->Nparm; - Qrp = tdbp->Qrp; - Placed = false; +//Ncol = tdbp->Ncol; + Prepared = tdbp->Prepared; + Werr = tdbp->Werr; + Rerr = tdbp->Rerr; } // end of TDBJDBC copy constructor // Method -PTDB TDBJDBC::CopyOne(PTABS t) +PTDB TDBJDBC::Clone(PTABS t) { PTDB tp; PJDBCCOL cp1, cp2; @@ -443,7 +391,7 @@ PTDB TDBJDBC::CopyOne(PTABS t) } // endfor cp1 return tp; -} // end of CopyOne +} // end of Clone /***********************************************************************/ /* Allocate JDBC column description block. */ @@ -453,134 +401,6 @@ PCOL TDBJDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) return new(g)JDBCCOL(cdp, this, cprec, n); } // end of MakeCol -/******************************************************************/ -/* Convert an UTF-8 string to latin characters. */ -/******************************************************************/ -int TDBJDBC::Decode(char *txt, char *buf, size_t n) -{ - uint dummy_errors; - uint32 len= copy_and_convert(buf, n, &my_charset_latin1, - txt, strlen(txt), - &my_charset_utf8_general_ci, - &dummy_errors); - buf[len]= '\0'; - return 0; -} // end of Decode - -/***********************************************************************/ -/* MakeSQL: make the SQL statement use with JDBC connection. */ -/* TODO: when implementing EOM filtering, column only used in local */ -/* filter should be removed from column list. */ -/***********************************************************************/ -bool TDBJDBC::MakeSQL(PGLOBAL g, bool cnt) -{ - char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3]; - int len; - bool oom = false, first = true; - PTABLE tablep = To_Table; - PCOL colp; - - if (Srcdef) { - Query = new(g)STRING(g, 0, Srcdef); - return false; - } // endif Srcdef - - // Allocate the string used to contain the Query - Query = new(g)STRING(g, 1023, "SELECT "); - - if (!cnt) { - if (Columns) { - // Normal SQL statement to retrieve results - for (colp = Columns; colp; colp = colp->GetNext()) - if (!colp->IsSpecial()) { - if (!first) - oom |= Query->Append(", "); - else - first = false; - - // Column name can be encoded in UTF-8 - Decode(colp->GetName(), buf, sizeof(buf)); - - 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); - } else - oom |= Query->Append(buf); - - ((PJDBCCOL)colp)->Rank = ++Ncol; - } // endif colp - - } else - // !Columns can occur for queries such that sql count(*) from... - // for which we will count the rows from sql * from... - oom |= Query->Append('*'); - - } else - // SQL statement used to retrieve the size of the result - oom |= Query->Append("count(*)"); - - oom |= Query->Append(" FROM "); - - if (Catalog && *Catalog) - catp = Catalog; - - //if (tablep->GetSchema()) - // schmp = (char*)tablep->GetSchema(); - //else - if (Schema && *Schema) - schmp = Schema; - - if (catp) { - oom |= Query->Append(catp); - - if (schmp) { - oom |= Query->Append('.'); - oom |= Query->Append(schmp); - } // endif schmp - - oom |= Query->Append('.'); - } else if (schmp) { - oom |= Query->Append(schmp); - oom |= Query->Append('.'); - } // endif schmp - - // Table name can be encoded in UTF-8 - Decode(TableName, buf, sizeof(buf)); - - 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); - } else - oom |= Query->Append(buf); - - len = Query->GetLength(); - - if (To_CondFil) { - if (Mode == MODE_READ) { - oom |= Query->Append(" WHERE "); - oom |= Query->Append(To_CondFil->Body); - len = Query->GetLength() + 1; - } else - len += (strlen(To_CondFil->Body) + 256); - - } else - len += ((Mode == MODE_READX) ? 256 : 1); - - if (oom || Query->Resize(len)) { - strcpy(g->Message, "MakeSQL: Out of memory"); - return true; - } // endif oom - - if (trace) - htrc("Query=%s\n", Query->GetStr()); - - return false; -} // end of MakeSQL - /***********************************************************************/ /* MakeInsert: make the Insert statement used with JDBC connection. */ /***********************************************************************/ @@ -601,7 +421,7 @@ bool TDBJDBC::MakeInsert(PGLOBAL g) // Column name can be encoded in UTF-8 Decode(colp->GetName(), buf, sizeof(buf)); len += (strlen(buf) + 6); // comma + quotes + valist - ((PJDBCCOL)colp)->Rank = ++Nparm; + ((PEXTCOL)colp)->SetRank(++Nparm); } // endif colp // Below 32 is enough to contain the fixed part of the query @@ -711,76 +531,6 @@ bool TDBJDBC::SetParameters(PGLOBAL g) } // end of SetParameters /***********************************************************************/ -/* MakeCommand: make the Update or Delete statement to send to the */ -/* MySQL server. Limited to remote values and filtering. */ -/***********************************************************************/ -bool TDBJDBC::MakeCommand(PGLOBAL g) -{ - char *p, *stmt, name[68], *body = NULL, *qc = Jcp->GetQuoteChar(); - char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1); - bool qtd = Quoted > 0; - int i = 0, k = 0; - - // Make a lower case copy of the originale query and change - // back ticks to the data source identifier quoting character - do { - qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]); - } while (Qrystr[i++]); - - if (To_CondFil && (p = strstr(qrystr, " where "))) { - p[7] = 0; // Remove where clause - Qrystr[(p - qrystr) + 7] = 0; - body = To_CondFil->Body; - stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr) - + strlen(body) + 64); - } else - stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); - - // Check whether the table name is equal to a keyword - // If so, it must be quoted in the original query - strlwr(strcat(strcat(strcpy(name, " "), Name), " ")); - - if (strstr(" update delete low_priority ignore quick from ", name)) { - strlwr(strcat(strcat(strcpy(name, qc), Name), qc)); - k += 2; - } else - strlwr(strcpy(name, Name)); // Not a keyword - - if ((p = strstr(qrystr, name))) { - for (i = 0; i < p - qrystr; i++) - stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i]; - - stmt[i] = 0; - k += i + (int)strlen(Name); - - if (qtd && *(p-1) == ' ') - strcat(strcat(strcat(stmt, qc), TableName), qc); - else - strcat(stmt, TableName); - - i = (int)strlen(stmt); - - do { - stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k]; - } while (Qrystr[k++]); - - if (body) - strcat(stmt, body); - - } else { - sprintf(g->Message, "Cannot use this %s command", - (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); - return 1; - } // endif p - - if (trace) - htrc("Command=%s\n", stmt); - - Query = new(g)STRING(g, 0, stmt); - return (!Query->GetSize()); -} // end of MakeCommand - -/***********************************************************************/ /* ResetSize: call by TDBMUL when calculating size estimate. */ /***********************************************************************/ void TDBJDBC::ResetSize(void) @@ -834,33 +584,6 @@ int TDBJDBC::Cardinality(PGLOBAL g) } // end of Cardinality /***********************************************************************/ -/* JDBC GetMaxSize: returns table size estimate in number of lines. */ -/***********************************************************************/ -int TDBJDBC::GetMaxSize(PGLOBAL g) -{ - if (MaxSize < 0) { - if (Mode == MODE_DELETE) - // Return 0 in mode DELETE in case of delete all. - MaxSize = 0; - else if (!Cardinality(NULL)) - MaxSize = 10; // To make MySQL happy - else if ((MaxSize = Cardinality(g)) < 0) - MaxSize = 12; // So we can see an error occured - - } // endif MaxSize - - return MaxSize; -} // end of GetMaxSize - -/***********************************************************************/ -/* Return max size value. */ -/***********************************************************************/ -int TDBJDBC::GetProgMax(PGLOBAL g) -{ - return GetMaxSize(g); -} // end of GetProgMax - -/***********************************************************************/ /* JDBC Access Method opening routine. */ /* New method now that this routine is called recursively (last table */ /* first in reverse order): index blocks are immediately linked to */ @@ -997,6 +720,7 @@ bool TDBJDBC::OpenDB(PGLOBAL g) return false; } // end of OpenDB +#if 0 /***********************************************************************/ /* GetRecpos: return the position of last read record. */ /***********************************************************************/ @@ -1004,6 +728,7 @@ int TDBJDBC::GetRecpos(void) { return Fpos; } // end of GetRecpos +#endif // 0 /***********************************************************************/ /* SetRecpos: set the position of next read record. */ @@ -1105,8 +830,7 @@ int TDBJDBC::ReadDB(PGLOBAL g) int rc; if (trace > 1) - htrc("JDBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n", - GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); + htrc("JDBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode); if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { if (!Query && MakeCommand(g)) @@ -1125,12 +849,6 @@ int TDBJDBC::ReadDB(PGLOBAL g) } // endif Mode - if (To_Kindex) { - // Direct access of JDBC tables is not implemented - strcpy(g->Message, "No JDBC direct access"); - return RC_FX; - } // endif To_Kindex - /*********************************************************************/ /* Now start the reading process. */ /* Here is the place to fetch the line(s). */ @@ -1302,70 +1020,26 @@ void TDBJDBC::CloseDB(PGLOBAL g) /* JDBCCOL public constructor. */ /***********************************************************************/ JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) - : COLBLK(cdp, tdbp, i) + : EXTCOL(cdp, tdbp, cprec, i, am) { - if (cprec) { - Next = cprec->GetNext(); - cprec->SetNext(this); - } else { - Next = tdbp->GetColumns(); - tdbp->SetColumns(this); - } // endif cprec - - // Set additional JDBC access method information for column. - Crp = NULL; - //Long = cdp->GetLong(); - Long = Precision; - //strcpy(F_Date, cdp->F_Date); - To_Val = NULL; -//Slen = 0; -//StrLen = &Slen; -//Sqlbuf = NULL; - Bufp = NULL; - Blkp = NULL; - Rank = 0; // Not known yet - - if (trace) - htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); - } // end of JDBCCOL constructor /***********************************************************************/ /* JDBCCOL private constructor. */ /***********************************************************************/ -JDBCCOL::JDBCCOL(void) : COLBLK() +JDBCCOL::JDBCCOL(void) : EXTCOL() { - Crp = NULL; - Buf_Type = TYPE_INT; // This is a count(*) column - // Set additional Dos access method information for column. - Long = sizeof(int); - To_Val = NULL; -//Slen = 0; -//StrLen = &Slen; -//Sqlbuf = NULL; - Bufp = NULL; - Blkp = NULL; - Rank = 1; } // end of JDBCCOL constructor /***********************************************************************/ /* JDBCCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/ -JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) +JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) { - Crp = col1->Crp; - Long = col1->Long; - //strcpy(F_Date, col1->F_Date); - To_Val = col1->To_Val; -//Slen = col1->Slen; -//StrLen = col1->StrLen; -//Sqlbuf = col1->Sqlbuf; - Bufp = col1->Bufp; - Blkp = col1->Blkp; - Rank = col1->Rank; } // end of JDBCCOL copy constructor +#if 0 /***********************************************************************/ /* SetBuffer: prepare a column block for write operation. */ /***********************************************************************/ @@ -1411,6 +1085,7 @@ bool JDBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) Status = (ok) ? BUF_EMPTY : BUF_NO; return false; } // end of SetBuffer +#endif // 0 /***********************************************************************/ /* ReadColumn: when SQLFetch is used there is nothing to do as the */ @@ -1456,72 +1131,8 @@ void JDBCCOL::ReadColumn(PGLOBAL g) } // end of ReadColumn -#if 0 /***********************************************************************/ -/* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */ -/* or Fetch. Note: we use Long+1 here because JDBC must have space */ -/* for the ending null character. */ -/***********************************************************************/ -void JDBCCOL::AllocateBuffers(PGLOBAL g, int rows) -{ - if (Buf_Type == TYPE_DATE) - Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL, - sizeof(TIMESTAMP_STRUCT)); - - if (!rows) - return; - - if (Buf_Type == TYPE_DATE) - Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT)); - else { - Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(), - GetScale(), true, false, false); - Bufp = Blkp->GetValPointer(); - } // endelse - - if (rows > 1) - StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN)); - -} // end of AllocateBuffers - -/***********************************************************************/ -/* Returns the buffer to use for Fetch or Extended Fetch. */ -/***********************************************************************/ -void *JDBCCOL::GetBuffer(DWORD rows) -{ - if (rows && To_Tdb) { - assert(rows == (DWORD)((TDBJDBC*)To_Tdb)->Rows); - return Bufp; - } else - return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val(); - -} // end of GetBuffer - -/***********************************************************************/ -/* Returns the buffer length to use for Fetch or Extended Fetch. */ -/***********************************************************************/ -SWORD JDBCCOL::GetBuflen(void) -{ - SWORD flen; - - switch (Buf_Type) { - case TYPE_DATE: - flen = (SWORD)sizeof(TIMESTAMP_STRUCT); - break; - case TYPE_STRING: - case TYPE_DECIM: - flen = (SWORD)Value->GetClen() + 1; - break; - default: - flen = (SWORD)Value->GetClen(); - } // endswitch Buf_Type - - return flen; -} // end of GetBuflen -#endif // 0 - -/***********************************************************************/ -/* WriteColumn: make sure the bind buffer is updated. */ +/* WriteColumn: Convert if necessary. */ /***********************************************************************/ void JDBCCOL::WriteColumn(PGLOBAL g) { @@ -1531,30 +1142,6 @@ void JDBCCOL::WriteColumn(PGLOBAL g) if (Value != To_Val) Value->SetValue_pval(To_Val, FALSE); // Convert the inserted value -#if 0 - if (Buf_Type == TYPE_DATE) { - struct tm tm, *dbtime = ((DTVAL*)Value)->GetGmTime(&tm); - - Sqlbuf->second = dbtime->tm_sec; - Sqlbuf->minute = dbtime->tm_min; - Sqlbuf->hour = dbtime->tm_hour; - Sqlbuf->day = dbtime->tm_mday; - Sqlbuf->month = dbtime->tm_mon + 1; - Sqlbuf->year = dbtime->tm_year + 1900; - Sqlbuf->fraction = 0; - } else if (Buf_Type == TYPE_DECIM) { - // Some data sources require local decimal separator - char *p, sep = ((PTDBJDBC)To_Tdb)->Sep; - - if (sep && (p = strchr(Value->GetCharValue(), '.'))) - *p = sep; - - } // endif Buf_Type - - if (Nullable) - *StrLen = (Value->IsNull()) ? SQL_NULL_DATA : - (IsTypeChar(Buf_Type)) ? SQL_NTS : 0; -#endif // 0 } // end of WriteColumn /* -------------------------- Class TDBXJDC -------------------------- */ @@ -1795,7 +1382,7 @@ TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) { Schema = tdp->Tabschema; Tab = tdp->Tabname; - Tabtype = tdp->Tabtype; + Tabtype = tdp->Tabtyp; Ops.Driver = tdp->Driver; Ops.Url = tdp->Url; Ops.User = tdp->Username; diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h index fee8223abaf..46d2073e923 100644 --- a/storage/connect/tabjdbc.h +++ b/storage/connect/tabjdbc.h @@ -21,7 +21,7 @@ typedef class JSRCCOL *PJSRCCOL; /***********************************************************************/ /* JDBC table. */ /***********************************************************************/ -class DllExport JDBCDEF : public TABDEF { /* Logical table description */ +class DllExport JDBCDEF : public EXTDEF { /* Logical table description */ friend class TDBJDBC; friend class TDBXJDC; friend class TDBJDRV; @@ -33,17 +33,8 @@ public: // Implementation virtual const char *GetType(void) { return "JDBC"; } - PSZ GetTabname(void) { return Tabname; } - PSZ GetTabschema(void) { return Tabschema; } - PSZ GetTabcat(void) { return Tabcat; } - PSZ GetSrcdef(void) { return Srcdef; } - char GetSep(void) { return (Sep) ? *Sep : 0; } - int GetQuoted(void) { return Quoted; } -//int GetCatver(void) { return Catver; } - int GetOptions(void) { return Options; } // Methods - virtual int Indexable(void) { return 2; } virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual PTDB GetTable(PGLOBAL g, MODE m); int ParseURL(PGLOBAL g, char *url, bool b = true); @@ -53,28 +44,7 @@ protected: // Members PSZ Driver; /* JDBC driver */ PSZ Url; /* JDBC driver URL */ - PSZ Tabname; /* External table name */ PSZ Wrapname; /* Java wrapper name */ - PSZ Tabschema; /* External table schema */ - PSZ Username; /* User connect name */ - PSZ Password; /* Password connect info */ -//PSZ Prop; /* Connection Properties */ - PSZ Tabcat; /* External table catalog */ - PSZ Tabtype; /* External table type */ - PSZ Colpat; /* Catalog column pattern */ - PSZ Srcdef; /* The source table SQL definition */ - PSZ Qchar; /* Identifier quoting character */ - PSZ Qrystr; /* The original query */ - PSZ Sep; /* Decimal separator */ - int Options; /* Open connection options */ -//int Cto; /* Open connection timeout */ -//int Qto; /* Query (command) timeout */ - int Quoted; /* Identifier quoting level */ - int Maxerr; /* Maxerr for an Exec table */ - int Maxres; /* Maxres for a catalog table */ - int Memory; /* Put result set in memory */ - bool Scrollable; /* Use scrollable cursor */ - bool Xsrc; /* Execution type */ }; // end of JDBCDEF #if !defined(NJDBC) @@ -84,34 +54,34 @@ protected: /* This is the JDBC Access Method class declaration for files from */ /* other DB drivers to be accessed via JDBC. */ /***********************************************************************/ -class TDBJDBC : public TDBASE { +class TDBJDBC : public TDBEXT { friend class JDBCCOL; friend class JDBConn; public: // Constructor TDBJDBC(PJDBCDEF tdp = NULL); - TDBJDBC(PTDBJDBC tdbp); + TDBJDBC(PTDBJDBC tdbp); // Implementation - virtual AMT GetAmType(void) { return TYPE_AM_JDBC; } - virtual PTDB Duplicate(PGLOBAL g) { return (PTDB)new(g)TDBJDBC(this); } + virtual AMT GetAmType(void) {return TYPE_AM_JDBC;} + virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBJDBC(this);} // Methods - virtual PTDB CopyOne(PTABS t); - virtual int GetRecpos(void); + virtual PTDB Clone(PTABS t); +//virtual int GetRecpos(void); virtual bool SetRecpos(PGLOBAL g, int recpos); //virtual PSZ GetFile(PGLOBAL g); //virtual void SetFile(PGLOBAL g, PSZ fn); virtual void ResetSize(void); - //virtual int GetAffectedRows(void) {return AftRows;} +//virtual int GetAffectedRows(void) {return AftRows;} virtual PSZ GetServer(void) { return "JDBC"; } virtual int Indexable(void) { return 2; } // Database routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual int Cardinality(PGLOBAL g); - virtual int GetMaxSize(PGLOBAL g); - virtual int GetProgMax(PGLOBAL g); +//virtual int GetMaxSize(PGLOBAL g); +//virtual int GetProgMax(PGLOBAL g); virtual bool OpenDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g); @@ -121,97 +91,50 @@ public: protected: // Internal functions - int Decode(char *utf, char *buf, size_t n); - bool MakeSQL(PGLOBAL g, bool cnt); +//int Decode(char *utf, char *buf, size_t n); +//bool MakeSQL(PGLOBAL g, bool cnt); bool MakeInsert(PGLOBAL g); - bool MakeCommand(PGLOBAL g); - //bool MakeFilter(PGLOBAL g, bool c); +//virtual bool MakeCommand(PGLOBAL g); +//bool MakeFilter(PGLOBAL g, bool c); bool SetParameters(PGLOBAL g); - //char *MakeUpdate(PGLOBAL g); - //char *MakeDelete(PGLOBAL g); +//char *MakeUpdate(PGLOBAL g); +//char *MakeDelete(PGLOBAL g); // Members JDBConn *Jcp; // Points to a JDBC connection class JDBCCOL *Cnp; // Points to count(*) column JDBCPARM Ops; // Additional parameters - PSTRG Query; // Constructed SQL query char *WrapName; // Points to Java wrapper name - char *TableName; // Points to JDBC table name - char *Schema; // Points to JDBC table Schema - char *User; // User connect info - char *Pwd; // Password connect info - char *Catalog; // Points to JDBC table Catalog - char *Srcdef; // The source table SQL definition - char *Count; // Points to count(*) SQL statement -//char *Where; // Points to local where clause - char *Quote; // The identifier quoting character - char *MulConn; // Used for multiple JDBC tables - char *DBQ; // The address part of Connect string - char *Qrystr; // The original query - char Sep; // The decimal separator - int Options; // Connect options -//int Cto; // Connect timeout -//int Qto; // Query timeout - int Quoted; // The identifier quoting level - int Fpos; // Position of last read record - int Curpos; // Cursor position of last fetch - int AftRows; // The number of affected rows - int Rows; // Rowset size - int CurNum; // Current buffer line number - int Rbuf; // Number of lines read in buffer - int BufSize; // Size of connect string buffer - int Ncol; // The column number - int Nparm; // The number of statement parameters - int Memory; // 0: No 1: Alloc 2: Put 3: Get -//bool Scrollable; // Use scrollable cursor --> in Ops - bool Placed; // True for position reading +//int Ncol; // The column number bool Prepared; // True when using prepared statement bool Werr; // Write error bool Rerr; // Rewind error - PQRYRES Qrp; // Points to storage result }; // end of class TDBJDBC /***********************************************************************/ /* Class JDBCCOL: JDBC access method column descriptor. */ /* This A.M. is used for JDBC tables. */ /***********************************************************************/ -class JDBCCOL : public COLBLK { +class JDBCCOL : public EXTCOL { friend class TDBJDBC; public: // Constructors JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC"); - JDBCCOL(JDBCCOL *colp, PTDB tdbp); // Constructor used in copy process + JDBCCOL(JDBCCOL *colp, PTDB tdbp); // Constructor used in copy process // Implementation - virtual int GetAmType(void) { return TYPE_AM_JDBC; } -//SQLLEN *GetStrLen(void) { return StrLen; } - int GetRank(void) { return Rank; } -//PVBLK GetBlkp(void) {return Blkp;} - void SetCrp(PCOLRES crp) { Crp = crp; } + virtual int GetAmType(void) { return TYPE_AM_JDBC; } // Methods - virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); - virtual void ReadColumn(PGLOBAL g); - virtual void WriteColumn(PGLOBAL g); -//void AllocateBuffers(PGLOBAL g, int rows); -//void *GetBuffer(DWORD rows); -//SWORD GetBuflen(void); - // void Print(PGLOBAL g, FILE *, uint); +//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); + virtual void ReadColumn(PGLOBAL g); + virtual void WriteColumn(PGLOBAL g); protected: - // Constructor used by GetMaxSize - JDBCCOL(void); + // Constructor for count(*) column + JDBCCOL(void); // Members - //TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's - PCOLRES Crp; // To storage result - void *Bufp; // To extended buffer - PVBLK Blkp; // To Value Block - //char F_Date[12]; // Internal Date format - PVAL To_Val; // To value used for Insert -//SQLLEN *StrLen; // As returned by JDBC -//SQLLEN Slen; // Used with Fetch - int Rank; // Rank (position) number in the query }; // end of class JDBCCOL /***********************************************************************/ @@ -268,7 +191,7 @@ public: JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC"); // Implementation - //virtual int GetAmType(void) {return TYPE_AM_JDBC;} + virtual int GetAmType(void) {return TYPE_AM_JDBC;} // Methods virtual void ReadColumn(PGLOBAL g); diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp index 1b9ce8b64c9..1e11d454cfc 100644 --- a/storage/connect/tabjson.cpp +++ b/storage/connect/tabjson.cpp @@ -129,7 +129,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) if (tdp->Pretty == 2) { if (tdp->Zipped) { #if defined(ZIP_SUPPORT) - tjsp = new(g) TDBJSON(tdp, new(g) ZIPFAM(tdp)); + tjsp = new(g) TDBJSON(tdp, new(g) UNZFAM(tdp)); #else // !ZIP_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); return NULL; @@ -151,7 +151,7 @@ PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info) if (tdp->Zipped) { #if defined(ZIP_SUPPORT) - tjnp = new(g)TDBJSN(tdp, new(g)ZIPFAM(tdp)); + tjnp = new(g)TDBJSN(tdp, new(g)UNZFAM(tdp)); #else // !ZIP_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); return NULL; @@ -441,7 +441,14 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) if (Zipped) { #if defined(ZIP_SUPPORT) - txfp = new(g) ZIPFAM(this); + if (m == MODE_READ || m == MODE_UPDATE) { + txfp = new(g) UNZFAM(this); + } else if (m == MODE_INSERT) { + txfp = new(g) ZIPFAM(this); + } else { + strcpy(g->Message, "UPDATE/DELETE not supported for ZIP"); + return NULL; + } // endif's m #else // !ZIP_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); return NULL; @@ -479,7 +486,15 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m) } else { if (Zipped) { #if defined(ZIP_SUPPORT) - txfp = new(g)ZIPFAM(this); + if (m == MODE_READ || m == MODE_UPDATE) { + txfp = new(g) UNZFAM(this); + } else if (m == MODE_INSERT) { + strcpy(g->Message, "INSERT supported only for zipped JSON when pretty=0"); + return NULL; + } else { + strcpy(g->Message, "UPDATE/DELETE not supported for ZIP"); + return NULL; + } // endif's m #else // !ZIP_SUPPORT sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP"); return NULL; @@ -559,7 +574,7 @@ TDBJSN::TDBJSN(TDBJSN *tdbp) : TDBDOS(NULL, tdbp) } // end of TDBJSN copy constructor // Used for update -PTDB TDBJSN::CopyOne(PTABS t) +PTDB TDBJSN::Clone(PTABS t) { G = NULL; PTDB tp; @@ -574,7 +589,7 @@ PTDB TDBJSN::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate JSN column description block. */ @@ -1563,7 +1578,7 @@ TDBJSON::TDBJSON(PJTDB tdbp) : TDBJSN(tdbp) } // end of TDBJSON copy constructor // Used for update -PTDB TDBJSON::CopyOne(PTABS t) +PTDB TDBJSON::Clone(PTABS t) { PTDB tp; PJCOL cp1, cp2; @@ -1577,7 +1592,7 @@ PTDB TDBJSON::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Make the document tree from the object path. */ diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h index c9d30d48f2a..924ce387900 100644 --- a/storage/connect/tabjson.h +++ b/storage/connect/tabjson.h @@ -82,7 +82,7 @@ public: void SetG(PGLOBAL g) {G = g;} // Methods - virtual PTDB CopyOne(PTABS t); + 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) @@ -188,7 +188,7 @@ class TDBJSON : public TDBJSN { PJAR GetDoc(void) {return Doc;} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); // Database routines virtual int Cardinality(PGLOBAL g); diff --git a/storage/connect/table.cpp b/storage/connect/table.cpp index c21bb1660ea..916449be6c6 100644 --- a/storage/connect/table.cpp +++ b/storage/connect/table.cpp @@ -1,7 +1,7 @@ /************** Table C++ Functions Source Code File (.CPP) ************/ -/* Name: TABLE.CPP Version 2.7 */ +/* Name: TABLE.CPP Version 2.8 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 1999-2016 */ +/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */ /* */ /* This file contains the TBX, TDB and OPJOIN classes functions. */ /***********************************************************************/ @@ -10,6 +10,7 @@ /* Include relevant MariaDB header file. */ /***********************************************************************/ #include "my_global.h" +#include "sql_string.h" /***********************************************************************/ /* Include required application header files */ @@ -40,8 +41,9 @@ void AddPointer(PTABS, void *); /* TDB public constructors. */ /***********************************************************************/ TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum) - { - Use = USE_NO; +{ + To_Def = tdp; + Use = USE_NO; To_Orig = NULL; To_Filter = NULL; To_CondFil = NULL; @@ -49,14 +51,20 @@ TDB::TDB(PTABDEF tdp) : Tdb_No(++Tnum) Name = (tdp) ? tdp->GetName() : NULL; To_Table = NULL; Columns = NULL; - Degree = (tdp) ? tdp->GetDegree() : 0; + To_SetCols = NULL; + Degree = (tdp) ? tdp->GetDegree() : 0; Mode = MODE_ANY; Cardinal = -1; - } // end of TDB standard constructor + MaxSize = -1; + Read_Only = (tdp) ? tdp->IsReadOnly() : false; + m_data_charset = (tdp) ? tdp->data_charset() : NULL; + csname = (tdp) ? tdp->csname : NULL; +} // end of TDB standard constructor TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum) - { - Use = tdbp->Use; +{ + To_Def = tdbp->To_Def; + Use = tdbp->Use; To_Orig = tdbp; To_Filter = NULL; To_CondFil = NULL; @@ -64,12 +72,192 @@ TDB::TDB(PTDB tdbp) : Tdb_No(++Tnum) Name = tdbp->Name; To_Table = tdbp->To_Table; Columns = NULL; - Degree = tdbp->Degree; + To_SetCols = tdbp->To_SetCols; // ??? + Degree = tdbp->Degree; Mode = tdbp->Mode; Cardinal = tdbp->Cardinal; - } // end of TDB copy constructor + MaxSize = tdbp->MaxSize; + Read_Only = tdbp->IsReadOnly(); + m_data_charset = tdbp->data_charset(); + csname = tdbp->csname; +} // end of TDB copy constructor // Methods +/***********************************************************************/ +/* Return the pointer on the charset of this table. */ +/***********************************************************************/ +CHARSET_INFO *TDB::data_charset(void) +{ + // If no DATA_CHARSET is specified, we assume that character + // set of the remote data is the same with CHARACTER SET + // definition of the SQL column. + return m_data_charset ? m_data_charset : &my_charset_bin; +} // end of data_charset + +/***********************************************************************/ +/* Return the datapath of the DB this table belongs to. */ +/***********************************************************************/ +PSZ TDB::GetPath(void) +{ + return To_Def->GetPath(); +} // end of GetPath + +/***********************************************************************/ +/* Return true if name is a special column of this table. */ +/***********************************************************************/ +bool TDB::IsSpecial(PSZ name) +{ + for (PCOLDEF cdp = To_Def->GetCols(); cdp; cdp = cdp->GetNext()) + if (!stricmp(cdp->GetName(), name) && (cdp->Flags & U_SPECIAL)) + return true; // Special column to ignore while inserting + + return false; // Not found or not special or not inserting +} // end of IsSpecial + +/***********************************************************************/ +/* Initialize TDB based column description block construction. */ +/* name is used to call columns by name. */ +/* num is used by TBL to construct columns by index number. */ +/* Note: name=Null and num=0 for constructing all columns (select *) */ +/***********************************************************************/ +PCOL TDB::ColDB(PGLOBAL g, PSZ name, int num) +{ + int i; + PCOLDEF cdp; + PCOL cp, colp = NULL, cprec = NULL; + + if (trace) + htrc("ColDB: am=%d colname=%s tabname=%s num=%d\n", + GetAmType(), SVP(name), Name, num); + + for (cdp = To_Def->GetCols(), i = 1; cdp; cdp = cdp->GetNext(), i++) + if ((!name && !num) || + (name && !stricmp(cdp->GetName(), name)) || num == i) { + /*****************************************************************/ + /* Check for existence of desired column. */ + /* Also find where to insert the new block. */ + /*****************************************************************/ + for (cp = Columns; cp; cp = cp->GetNext()) + if ((num && cp->GetIndex() == i) || + (name && !stricmp(cp->GetName(), name))) + break; // Found + else if (cp->GetIndex() < i) + cprec = cp; + + if (trace) + htrc("cdp(%d).Name=%s cp=%p\n", i, cdp->GetName(), cp); + + /*****************************************************************/ + /* Now take care of Column Description Block. */ + /*****************************************************************/ + if (cp) + colp = cp; + else if (!(cdp->Flags & U_SPECIAL)) + colp = MakeCol(g, cdp, cprec, i); + else if (Mode != MODE_INSERT) + colp = InsertSpcBlk(g, cdp); + + if (trace) + htrc("colp=%p\n", colp); + + if (name || num) + break; + else if (colp && !colp->IsSpecial()) + cprec = colp; + + } // endif Name + + return (colp); +} // end of ColDB + +/***********************************************************************/ +/* InsertSpecialColumn: Put a special column ahead of the column list.*/ +/***********************************************************************/ +PCOL TDB::InsertSpecialColumn(PCOL colp) +{ + if (!colp->IsSpecial()) + return NULL; + + colp->SetNext(Columns); + Columns = colp; + return colp; +} // end of InsertSpecialColumn + +/***********************************************************************/ +/* Make a special COLBLK to insert in a table. */ +/***********************************************************************/ +PCOL TDB::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp) +{ + //char *name = cdp->GetName(); + char *name = cdp->GetFmt(); + PCOLUMN cp; + PCOL colp; + + cp = new(g)COLUMN(cdp->GetName()); + + if (!To_Table) { + strcpy(g->Message, "Cannot make special column: To_Table is NULL"); + return NULL; + } else + cp->SetTo_Table(To_Table); + + if (!stricmp(name, "FILEID") || !stricmp(name, "FDISK") || + !stricmp(name, "FPATH") || !stricmp(name, "FNAME") || + !stricmp(name, "FTYPE") || !stricmp(name, "SERVID")) { + if (!To_Def || !(To_Def->GetPseudo() & 2)) { + sprintf(g->Message, MSG(BAD_SPEC_COLUMN)); + return NULL; + } // endif Pseudo + + if (!stricmp(name, "FILEID")) + colp = new(g)FIDBLK(cp, OP_XX); + else if (!stricmp(name, "FDISK")) + colp = new(g)FIDBLK(cp, OP_FDISK); + else if (!stricmp(name, "FPATH")) + colp = new(g)FIDBLK(cp, OP_FPATH); + else if (!stricmp(name, "FNAME")) + colp = new(g)FIDBLK(cp, OP_FNAME); + else if (!stricmp(name, "FTYPE")) + colp = new(g)FIDBLK(cp, OP_FTYPE); + else + colp = new(g)SIDBLK(cp); + + } else if (!stricmp(name, "TABID")) { + colp = new(g)TIDBLK(cp); + } else if (!stricmp(name, "PARTID")) { + colp = new(g)PRTBLK(cp); + //} else if (!stricmp(name, "CONID")) { + // colp = new(g) CIDBLK(cp); + } else if (!stricmp(name, "ROWID")) { + colp = new(g)RIDBLK(cp, false); + } else if (!stricmp(name, "ROWNUM")) { + colp = new(g)RIDBLK(cp, true); + } else { + sprintf(g->Message, MSG(BAD_SPECIAL_COL), name); + return NULL; + } // endif's name + + if (!(colp = InsertSpecialColumn(colp))) { + sprintf(g->Message, MSG(BAD_SPECIAL_COL), name); + return NULL; + } // endif Insert + + return (colp); +} // end of InsertSpcBlk + +/***********************************************************************/ +/* Marks DOS/MAP table columns used in internal joins. */ +/* tdb2 is the top of tree or first tdb in chained tdb's and tdbp */ +/* points to the currently marked tdb. */ +/* Two questions here: exact meaning of U_J_INT ? */ +/* Why is the eventual reference to To_Key_Col not marked U_J_EXT ? */ +/***********************************************************************/ +void TDB::MarkDB(PGLOBAL, PTDB tdb2) +{ + if (trace) + htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2); + +} // end of MarkDB /***********************************************************************/ /* RowNumber: returns the current row ordinal number. */ @@ -86,7 +274,7 @@ PTDB TDB::Copy(PTABS t) //PGLOBAL g = t->G; // Is this really useful ??? for (tdb1 = this; tdb1; tdb1 = tdb1->Next) { - tp = tdb1->CopyOne(t); + tp = tdb1->Clone(t); if (!outp) outp = tp; @@ -100,6 +288,15 @@ PTDB TDB::Copy(PTABS t) return outp; } // end of Copy +/***********************************************************************/ +/* SetRecpos: Replace the table at the specified position. */ +/***********************************************************************/ +bool TDB::SetRecpos(PGLOBAL g, int) +{ + strcpy(g->Message, MSG(SETRECPOS_NIY)); + return true; +} // end of SetRecpos + void TDB::Print(PGLOBAL g, FILE *f, uint n) { PCOL cp; @@ -135,34 +332,34 @@ void TDB::Print(PGLOBAL, char *ps, uint) /***********************************************************************/ TDBASE::TDBASE(PTABDEF tdp) : TDB(tdp) { - To_Def = tdp; +//To_Def = tdp; To_Link = NULL; To_Key_Col = NULL; To_Kindex = NULL; To_Xdp = NULL; - To_SetCols = NULL; +//To_SetCols = NULL; Ftype = RECFM_NAF; - MaxSize = -1; +//MaxSize = -1; Knum = 0; - Read_Only = (tdp) ? tdp->IsReadOnly() : false; - m_data_charset= (tdp) ? tdp->data_charset() : NULL; - csname = (tdp) ? tdp->csname : NULL; +//Read_Only = (tdp) ? tdp->IsReadOnly() : false; +//m_data_charset= (tdp) ? tdp->data_charset() : NULL; +//csname = (tdp) ? tdp->csname : NULL; } // end of TDBASE constructor TDBASE::TDBASE(PTDBASE tdbp) : TDB(tdbp) { - To_Def = tdbp->To_Def; +//To_Def = tdbp->To_Def; To_Link = tdbp->To_Link; To_Key_Col = tdbp->To_Key_Col; To_Kindex = tdbp->To_Kindex; To_Xdp = tdbp->To_Xdp; - To_SetCols = tdbp->To_SetCols; // ??? +//To_SetCols = tdbp->To_SetCols; // ??? Ftype = tdbp->Ftype; - MaxSize = tdbp->MaxSize; +//MaxSize = tdbp->MaxSize; Knum = tdbp->Knum; - Read_Only = tdbp->Read_Only; - m_data_charset= tdbp->m_data_charset; - csname = tdbp->csname; +//Read_Only = tdbp->Read_Only; +//m_data_charset= tdbp->m_data_charset; +//csname = tdbp->csname; } // end of TDBASE copy constructor /***********************************************************************/ @@ -173,6 +370,7 @@ PCATLG TDBASE::GetCat(void) return (To_Def) ? To_Def->GetCat() : NULL; } // end of GetCat +#if 0 /***********************************************************************/ /* Return the pointer on the charset of this table. */ /***********************************************************************/ @@ -334,6 +532,7 @@ PCOL TDBASE::InsertSpcBlk(PGLOBAL g, PCOLDEF cdp) return (colp); } // end of InsertSpcBlk +#endif // 0 /***********************************************************************/ /* ResetTableOpt: Wrong for this table type. */ @@ -362,6 +561,7 @@ void TDBASE::ResetKindex(PGLOBAL g, PKXBASE kxp) To_Kindex = kxp; } // end of ResetKindex +#if 0 /***********************************************************************/ /* SetRecpos: Replace the table at the specified position. */ /***********************************************************************/ @@ -370,6 +570,7 @@ bool TDBASE::SetRecpos(PGLOBAL g, int) strcpy(g->Message, MSG(SETRECPOS_NIY)); return true; } // end of SetRecpos +#endif // 0 /***********************************************************************/ /* Methods */ @@ -379,6 +580,7 @@ void TDBASE::PrintAM(FILE *f, char *m) fprintf(f, "%s AM(%d): mode=%d\n", m, GetAmType(), Mode); } // end of PrintAM +#if 0 /***********************************************************************/ /* Marks DOS/MAP table columns used in internal joins. */ /* tdb2 is the top of tree or first tdb in chained tdb's and tdbp */ @@ -392,6 +594,7 @@ void TDBASE::MarkDB(PGLOBAL, PTDB tdb2) htrc("DOS MarkDB: tdbp=%p tdb2=%p\n", this, tdb2); } // end of MarkDB +#endif // 0 /* ---------------------------TDBCAT class --------------------------- */ diff --git a/storage/connect/tabmac.cpp b/storage/connect/tabmac.cpp index e6e2abb54e2..bbaba591540 100644 --- a/storage/connect/tabmac.cpp +++ b/storage/connect/tabmac.cpp @@ -12,7 +12,7 @@ #include "global.h" #include "plgdbsem.h" //#include "catalog.h" -#include "reldef.h" +//#include "reldef.h" #include "xtable.h" #include "colblk.h" #include "tabmac.h" diff --git a/storage/connect/tabmac.h b/storage/connect/tabmac.h index f9a66e82eaa..47565bb2541 100644 --- a/storage/connect/tabmac.h +++ b/storage/connect/tabmac.h @@ -52,7 +52,7 @@ class TDBMAC : public TDBASE { //virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMAC(g, this);} // Methods -//virtual PTDB CopyOne(PTABS t); +//virtual PTDB Clone(PTABS t); virtual int GetRecpos(void) {return N;} virtual int RowNumber(PGLOBAL g, bool b = false) {return N;} diff --git a/storage/connect/tabmul.cpp b/storage/connect/tabmul.cpp index 22499801d07..78adde81d12 100644 --- a/storage/connect/tabmul.cpp +++ b/storage/connect/tabmul.cpp @@ -1,11 +1,11 @@ /************* TabMul C++ Program Source Code File (.CPP) **************/ /* PROGRAM NAME: TABMUL */ /* ------------- */ -/* Version 1.7 */ +/* Version 1.8 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to PlugDB Software Development 2003 - 2015 */ +/* (C) Copyright to PlugDB Software Development 2003 - 2017 */ /* Author: Olivier BERTRAND */ /* */ /* WHAT THIS PROGRAM DOES: */ @@ -73,7 +73,7 @@ /***********************************************************************/ /* TABMUL constructors. */ /***********************************************************************/ -TDBMUL::TDBMUL(PTDBASE tdbp) : TDBASE(tdbp->GetDef()) +TDBMUL::TDBMUL(PTDB tdbp) : TDBASE(tdbp->GetDef()) { Tdbp = tdbp; Filenames = NULL; @@ -94,22 +94,22 @@ TDBMUL::TDBMUL(PTDBMUL tdbp) : TDBASE(tdbp) } // end of TDBMUL copy constructor // Method -PTDB TDBMUL::CopyOne(PTABS t) +PTDB TDBMUL::Clone(PTABS t) { PTDBMUL tp; PGLOBAL g = t->G; // Is this really useful ??? tp = new(g) TDBMUL(this); - tp->Tdbp = (PTDBASE)Tdbp->CopyOne(t); + tp->Tdbp = Tdbp->Clone(t); tp->Columns = tp->Tdbp->GetColumns(); return tp; - } // end of CopyOne + } // end of Clone PTDB TDBMUL::Duplicate(PGLOBAL g) { PTDBMUL tmup = new(g) TDBMUL(this); - tmup->Tdbp = (PTDBASE)Tdbp->Duplicate(g); + tmup->Tdbp = Tdbp->Duplicate(g); return tmup; } // end of Duplicate @@ -658,7 +658,7 @@ TDBDIR::TDBDIR(PTDBDIR tdbp) : TDBASE(tdbp) } // end of TDBDIR copy constructor // Method -PTDB TDBDIR::CopyOne(PTABS t) +PTDB TDBDIR::Clone(PTABS t) { PTDB tp; PGLOBAL g = t->G; // Is this really useful ??? @@ -666,7 +666,7 @@ PTDB TDBDIR::CopyOne(PTABS t) tp = new(g) TDBDIR(this); tp->SetColumns(Columns); return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Initialize/get the components of the search file pattern. */ @@ -711,7 +711,7 @@ int TDBDIR::GetMaxSize(PGLOBAL g) if (MaxSize < 0) { int n = -1; #if defined(__WIN__) - intptr_t h; + int h; // Start searching files in the target directory. h = _findfirst(Path(g), &FileData); @@ -974,7 +974,7 @@ TDBSDR::TDBSDR(PTDBSDR tdbp) : TDBDIR(tdbp) } // end of TDBSDR copy constructor // Method -PTDB TDBSDR::CopyOne(PTABS t) +PTDB TDBSDR::Clone(PTABS t) { PTDB tp; PGLOBAL g = t->G; // Is this really useful ??? @@ -982,7 +982,7 @@ PTDB TDBSDR::CopyOne(PTABS t) tp = new(g) TDBSDR(this); tp->SetColumns(Columns); return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* SDR GetMaxSize: returns the number of retrieved files. */ @@ -1007,7 +1007,7 @@ int TDBSDR::FindInDir(PGLOBAL g) // Start searching files in the target directory. #if defined(__WIN__) - intptr_t h = _findfirst(Path(g), &FileData); + int h = _findfirst(Path(g), &FileData); if (h != -1) { for (n = 1;; n++) @@ -1251,7 +1251,7 @@ TDBDHR::TDBDHR(PTDBDHR tdbp) : TDBASE(tdbp) } // end of TDBDHR copy constructor // Method -PTDB TDBDHR::CopyOne(PTABS t) +PTDB TDBDHR::Clone(PTABS t) { PTDB tp; PGLOBAL g = t->G; // Is this really useful ??? @@ -1259,7 +1259,7 @@ PTDB TDBDHR::CopyOne(PTABS t) tp = new(g) TDBDHR(this); tp->Columns = Columns; return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate DHR column description block. */ diff --git a/storage/connect/tabmul.h b/storage/connect/tabmul.h index 53d7198eec7..51fa7f9000a 100644 --- a/storage/connect/tabmul.h +++ b/storage/connect/tabmul.h @@ -1,7 +1,7 @@ /*************** Tabmul H Declares Source Code File (.H) ***************/ -/* Name: TABMUL.H Version 1.4 */ +/* Name: TABMUL.H Version 1.5 */ /* */ -/* (C) Copyright to PlugDB Software Development 2003-2012 */ +/* (C) Copyright to PlugDB Software Development 2003-2017 */ /* Author: Olivier BERTRAND */ /* */ /* This file contains the TDBMUL and TDBDIR classes declares. */ @@ -28,7 +28,7 @@ class DllExport TDBMUL : public TDBASE { //friend class MULCOL; public: // Constructor - TDBMUL(PTDBASE tdbp); + TDBMUL(PTDB tdbp); TDBMUL(PTDBMUL tdbp); // Implementation @@ -37,7 +37,7 @@ class DllExport TDBMUL : public TDBASE { // Methods virtual void ResetDB(void); - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual bool IsSame(PTDB tp) {return tp == (PTDB)Tdbp;} virtual PSZ GetFile(PGLOBAL g) {return Tdbp->GetFile(g);} virtual int GetRecpos(void) {return 0;} @@ -61,7 +61,7 @@ class DllExport TDBMUL : public TDBASE { protected: // Members - TDBASE *Tdbp; // Points to a (file) table class + PTDB Tdbp; // Points to a (file) table class char* *Filenames; // Points to file names int Rows; // Total rows of already read files int Mul; // Type of multiple file list @@ -112,7 +112,7 @@ class TDBDIR : public TDBASE { {return (PTDB)new(g) TDBDIR(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual int GetRecpos(void) {return iFile;} // Database routines @@ -134,7 +134,7 @@ class TDBDIR : public TDBASE { int iFile; // Index of currently retrieved file #if defined(__WIN__) _finddata_t FileData; // Find data structure - intptr_t Hsearch; // Search handle + intptr_t Hsearch; // Search handle char Drive[_MAX_DRIVE]; // Drive name #else // !__WIN__ struct stat Fileinfo; // File info structure @@ -168,7 +168,7 @@ class TDBSDR : public TDBDIR { {return (PTDB)new(g) TDBSDR(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); // Database routines virtual int GetMaxSize(PGLOBAL g); @@ -184,7 +184,7 @@ class TDBSDR : public TDBDIR { struct _Sub_Dir *Next; struct _Sub_Dir *Prev; #if defined(__WIN__) - intptr_t H; // Search handle + intptr_t H; // Search handle #else // !__WIN__ DIR *D; #endif // !__WIN__ diff --git a/storage/connect/tabmysql.cpp b/storage/connect/tabmysql.cpp index 98a476bf94f..1a715819fc8 100644 --- a/storage/connect/tabmysql.cpp +++ b/storage/connect/tabmysql.cpp @@ -1,11 +1,11 @@ /************* TabMySQL C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABMYSQL */ /* ------------- */ -/* Version 1.9 */ +/* Version 2.0 */ /* */ /* AUTHOR: */ /* ------- */ -/* Olivier BERTRAND 2007-2015 */ +/* Olivier BERTRAND 2007-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -54,9 +54,10 @@ #include "global.h" #include "plgdbsem.h" #include "xtable.h" +#include "tabext.h" #include "tabcol.h" #include "colblk.h" -#include "reldef.h" +//#include "reldef.h" #include "tabmysql.h" #include "valblk.h" #include "tabutil.h" @@ -84,16 +85,16 @@ MYSQLDEF::MYSQLDEF(void) { Pseudo = 2; // SERVID is Ok but not ROWID Hostname = NULL; - Database = NULL; - Tabname = NULL; - Srcdef = NULL; - Username = NULL; - Password = NULL; +//Tabschema = NULL; +//Tabname = NULL; +//Srcdef = NULL; +//Username = NULL; +//Password = NULL; Portnumber = 0; Isview = false; Bind = false; Delayed = false; - Xsrc = false; +//Xsrc = false; Huge = false; } // end of MYSQLDEF constructor @@ -128,7 +129,7 @@ bool MYSQLDEF::GetServerInfo(PGLOBAL g, const char *server_name) // TODO: We need to examine which of these can really be NULL Hostname = PlugDup(g, server->host); - Database = PlugDup(g, server->db); + Tabschema = PlugDup(g, server->db); Username = PlugDup(g, server->username); Password = PlugDup(g, server->password); Portnumber = (server->port) ? server->port : GetDefaultPort(); @@ -200,7 +201,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b) Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL; if (trace) - htrc("server: %s Tabname: %s", url, Tabname); + htrc("server: %s TableName: %s", url, Tabname); Server = url; return GetServerInfo(g, url); @@ -253,10 +254,10 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b) return true; } // endif - if ((Database = strchr(Hostname, '/'))) { - *Database++ = 0; + if ((Tabschema = strchr(Hostname, '/'))) { + *Tabschema++ = 0; - if ((Tabname = strchr(Database, '/'))) { + if ((Tabname = strchr(Tabschema, '/'))) { *Tabname++ = 0; // Make sure there's not an extra / @@ -265,7 +266,7 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b) return true; } // endif / - } // endif Tabname + } // endif TableName } // endif database @@ -283,8 +284,8 @@ bool MYSQLDEF::ParseURL(PGLOBAL g, char *url, bool b) if (Hostname[0] == 0) Hostname = (b) ? GetStringCatInfo(g, "Host", "localhost") : NULL; - if (!Database || !*Database) - Database = (b) ? GetStringCatInfo(g, "Database", "*") : NULL; + if (!Tabschema || !*Tabschema) + Tabschema = (b) ? GetStringCatInfo(g, "Database", "*") : NULL; if (!Tabname || !*Tabname) Tabname = (b) ? GetStringCatInfo(g, "Tabname", Name) : NULL; @@ -320,7 +321,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) if (!url || !*url) { // Not using the connection URL Hostname = GetStringCatInfo(g, "Host", "localhost"); - Database = GetStringCatInfo(g, "Database", "*"); + Tabschema = GetStringCatInfo(g, "Database", "*"); Tabname = GetStringCatInfo(g, "Name", Name); // Deprecated Tabname = GetStringCatInfo(g, "Tabname", Tabname); Username = GetStringCatInfo(g, "User", "*"); @@ -334,7 +335,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) Delayed = !!GetIntCatInfo("Delayed", 0); } else { // MYSQL access from a PROXY table - Database = GetStringCatInfo(g, "Database", Schema ? Schema : PlugDup(g, "*")); + Tabschema = GetStringCatInfo(g, "Database", Tabschema ? Tabschema : PlugDup(g, "*")); Isview = GetBoolCatInfo("View", false); // We must get other connection parms from the calling table @@ -348,12 +349,12 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) Portnumber = GetIntCatInfo("Port", GetDefaultPort()); Server = Hostname; } else { - char *locdb = Database; + char *locdb = Tabschema; if (ParseURL(g, url)) return true; - Database = locdb; + Tabschema = locdb; } // endif url Tabname = Name; @@ -362,7 +363,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) { Read_Only = true; Isview = true; - } else if (CheckSelf(g, Hc->GetTable()->s, Hostname, Database, + } else if (CheckSelf(g, Hc->GetTable()->s, Hostname, Tabschema, Tabname, Srcdef, Portnumber)) return true; @@ -372,7 +373,7 @@ bool MYSQLDEF::DefineAM(PGLOBAL g, LPCSTR am, int) // Specific for command executing tables Xsrc = GetBoolCatInfo("Execsrc", false); - Mxr = GetIntCatInfo("Maxerr", 0); + Maxerr = GetIntCatInfo("Maxerr", 0); Huge = GetBoolCatInfo("Huge", false); return false; } // end of DefineAM @@ -396,17 +397,17 @@ PTDB MYSQLDEF::GetTable(PGLOBAL g, MODE) /***********************************************************************/ /* Implementation of the TDBMYSQL class. */ /***********************************************************************/ -TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp) +TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBEXT(tdp) { if (tdp) { Host = tdp->Hostname; - Database = tdp->Database; - Tabname = tdp->Tabname; - Srcdef = tdp->Srcdef; - User = tdp->Username; - Pwd = tdp->Password; +// Schema = tdp->Tabschema; +// TableName = tdp->Tabname; +// Srcdef = tdp->Srcdef; +// User = tdp->Username; +// Pwd = tdp->Password; Server = tdp->Server; - Qrystr = tdp->Qrystr; +// Qrystr = tdp->Qrystr; Quoted = MY_MAX(0, tdp->Quoted); Port = tdp->Portnumber; Isview = tdp->Isview; @@ -415,14 +416,14 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp) Myc.m_Use = tdp->Huge; } else { Host = NULL; - Database = NULL; - Tabname = NULL; - Srcdef = NULL; - User = NULL; - Pwd = NULL; +// Schema = NULL; +// TableName = NULL; +// Srcdef = NULL; +// User = NULL; +// Pwd = NULL; Server = NULL; - Qrystr = NULL; - Quoted = 0; +// Qrystr = NULL; +// Quoted = 0; Port = 0; Isview = false; Prep = false; @@ -430,39 +431,40 @@ TDBMYSQL::TDBMYSQL(PMYDEF tdp) : TDBASE(tdp) } // endif tdp Bind = NULL; - Query = NULL; +//Query = NULL; Fetched = false; m_Rc = RC_FX; - AftRows = 0; +//AftRows = 0; N = -1; - Nparm = 0; +//Nparm = 0; } // end of TDBMYSQL constructor -TDBMYSQL::TDBMYSQL(PTDBMY tdbp) : TDBASE(tdbp) +TDBMYSQL::TDBMYSQL(PTDBMY tdbp) : TDBEXT(tdbp) { Host = tdbp->Host; - Database = tdbp->Database; - Tabname = tdbp->Tabname; - Srcdef = tdbp->Srcdef; - User = tdbp->User; - Pwd = tdbp->Pwd; - Qrystr = tdbp->Qrystr; - Quoted = tdbp->Quoted; +//Schema = tdbp->Schema; +//TableName = tdbp->TableName; +//Srcdef = tdbp->Srcdef; +//User = tdbp->User; +//Pwd = tdbp->Pwd; +//Qrystr = tdbp->Qrystr; +//Quoted = tdbp->Quoted; + Server = tdbp->Server; Port = tdbp->Port; Isview = tdbp->Isview; Prep = tdbp->Prep; Delayed = tdbp->Delayed; Bind = NULL; - Query = tdbp->Query; +//Query = tdbp->Query; Fetched = tdbp->Fetched; m_Rc = tdbp->m_Rc; - AftRows = tdbp->AftRows; +//AftRows = tdbp->AftRows; N = tdbp->N; - Nparm = tdbp->Nparm; +//Nparm = tdbp->Nparm; } // end of TDBMYSQL copy constructor -// Is this really useful ??? -PTDB TDBMYSQL::CopyOne(PTABS t) +// Is this really useful ??? --> Yes for UPDATE +PTDB TDBMYSQL::Clone(PTABS t) { PTDB tp; PCOL cp1, cp2; @@ -477,7 +479,7 @@ PTDB TDBMYSQL::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate MYSQL column description block. */ @@ -504,10 +506,18 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) if (Query) return false; // already done - if (Srcdef) { - Query = new(g)STRING(g, 0, Srcdef); - return false; - } // endif Srcdef + if (Srcdef) { + if (strstr(Srcdef, "%s")) { + char *fil; + + fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1"); + Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil)); + Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil)); + } else + Query = new(g)STRING(g, 0, Srcdef); + + return false; + } // endif Srcdef // Allocate the string used to contain Query Query = new(g) STRING(g, 1023, "SELECT "); @@ -540,7 +550,7 @@ bool TDBMYSQL::MakeSelect(PGLOBAL g, bool mx) oom |= Query->Append(" FROM "); oom |= Query->Append(tk); - oom |= Query->Append(Tabname); + oom |= Query->Append(TableName); oom |= Query->Append(tk); len = Query->GetLength(); @@ -608,7 +618,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) } // endif colp // Below 40 is enough to contain the fixed part of the query - len += (strlen(Tabname) + 40); + len += (strlen(TableName) + 40); Query = new(g) STRING(g, len); if (Delayed) @@ -617,7 +627,7 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) oom = Query->Set("INSERT INTO "); oom |= Query->Append(tk); - oom |= Query->Append(Tabname); + oom |= Query->Append(TableName); oom |= Query->Append("` ("); for (colp = Columns; colp; colp = colp->GetNext()) { @@ -653,11 +663,11 @@ bool TDBMYSQL::MakeInsert(PGLOBAL g) /* MakeCommand: make the Update or Delete statement to send to the */ /* MySQL server. Limited to remote values and filtering. */ /***********************************************************************/ -int TDBMYSQL::MakeCommand(PGLOBAL g) +bool TDBMYSQL::MakeCommand(PGLOBAL g) { Query = new(g) STRING(g, strlen(Qrystr) + 64); - if (Quoted > 0 || stricmp(Name, Tabname)) { + if (Quoted > 0 || stricmp(Name, TableName)) { char *p, *qrystr, name[68]; bool qtd = Quoted > 0; @@ -678,29 +688,29 @@ int TDBMYSQL::MakeCommand(PGLOBAL g) if (qtd && *(p-1) == ' ') { oom |= Query->Append('`'); - oom |= Query->Append(Tabname); + oom |= Query->Append(TableName); oom |= Query->Append('`'); } else - oom |= Query->Append(Tabname); + oom |= Query->Append(TableName); oom |= Query->Append(Qrystr + (p - qrystr) + strlen(name)); if (oom) { strcpy(g->Message, "MakeCommand: Out of memory"); - return RC_FX; + return true; } else strlwr(strcpy(qrystr, Query->GetStr())); } else { sprintf(g->Message, "Cannot use this %s command", (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); - return RC_FX; + return true; } // endif p } else (void)Query->Set(Qrystr); - return RC_OK; + return false; } // end of MakeCommand #if 0 @@ -727,7 +737,7 @@ int TDBMYSQL::MakeUpdate(PGLOBAL g) } // endif sscanf assert(!stricmp(cmd, "update")); - strcat(strcat(strcat(strcpy(Query, "UPDATE "), qc), Tabname), qc); + strcat(strcat(strcat(strcpy(Query, "UPDATE "), qc), TableName), qc); strcat(Query, end); return RC_OK; } // end of MakeUpdate @@ -754,7 +764,7 @@ int TDBMYSQL::MakeDelete(PGLOBAL g) } // endif sscanf assert(!stricmp(cmd, "delete") && !stricmp(from, "from")); - strcat(strcat(strcat(strcpy(Query, "DELETE FROM "), qc), Tabname), qc); + strcat(strcat(strcat(strcpy(Query, "DELETE FROM "), qc), TableName), qc); if (*end) strcat(Query, end); @@ -776,15 +786,15 @@ int TDBMYSQL::Cardinality(PGLOBAL g) char query[96]; MYSQLC myc; - if (myc.Open(g, Host, Database, User, Pwd, Port, csname)) + if (myc.Open(g, Host, Schema, User, Pwd, Port, csname)) return -1; strcpy(query, "SELECT COUNT(*) FROM "); if (Quoted > 0) - strcat(strcat(strcat(query, "`"), Tabname), "`"); + strcat(strcat(strcat(query, "`"), TableName), "`"); else - strcat(query, Tabname); + strcat(query, TableName); Cardinal = myc.GetTableSize(g, query); myc.Close(); @@ -794,6 +804,7 @@ int TDBMYSQL::Cardinality(PGLOBAL g) return Cardinal; } // end of Cardinality +#if 0 /***********************************************************************/ /* MYSQL GetMaxSize: returns the maximum number of rows in the table. */ /***********************************************************************/ @@ -812,6 +823,7 @@ int TDBMYSQL::GetMaxSize(PGLOBAL g) return MaxSize; } // end of GetMaxSize +#endif // 0 /***********************************************************************/ /* This a fake routine as ROWID does not exist in MySQL. */ @@ -872,7 +884,7 @@ bool TDBMYSQL::OpenDB(PGLOBAL g) /* servers allowing concurency in getting results ??? */ /*********************************************************************/ if (!Myc.Connected()) { - if (Myc.Open(g, Host, Database, User, Pwd, Port, csname)) + if (Myc.Open(g, Host, Schema, User, Pwd, Port, csname)) return true; } // endif Connected @@ -931,14 +943,14 @@ bool TDBMYSQL::OpenDB(PGLOBAL g) char cmd[64]; int w; - sprintf(cmd, "ALTER TABLE `%s` DISABLE KEYS", Tabname); + sprintf(cmd, "ALTER TABLE `%s` DISABLE KEYS", TableName); m_Rc = Myc.ExecSQL(g, cmd, &w); // may fail for some engines } // endif m_Rc } else // m_Rc = (Mode == MODE_DELETE) ? MakeDelete(g) : MakeUpdate(g); - m_Rc = MakeCommand(g); + m_Rc = (MakeCommand(g)) ? RC_FX : RC_OK; if (m_Rc == RC_FX) { Myc.Close(); @@ -1030,7 +1042,7 @@ int TDBMYSQL::SendCommand(PGLOBAL g) if (Myc.ExecSQLcmd(g, Query->GetStr(), &w) == RC_NF) { AftRows = Myc.m_Afrw; - sprintf(g->Message, "%s: %d affected rows", Tabname, AftRows); + sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); PushWarning(g, this, 0); // 0 means a Note if (trace) @@ -1039,7 +1051,7 @@ int TDBMYSQL::SendCommand(PGLOBAL g) if (w && Myc.ExecSQL(g, "SHOW WARNINGS") == RC_OK) { // We got warnings from the remote server while (Myc.Fetch(g, -1) == RC_OK) { - sprintf(g->Message, "%s: (%s) %s", Tabname, + sprintf(g->Message, "%s: (%s) %s", TableName, Myc.GetCharField(1), Myc.GetCharField(2)); PushWarning(g, this); } // endwhile Fetch @@ -1116,8 +1128,7 @@ int TDBMYSQL::ReadDB(PGLOBAL g) int rc; if (trace > 1) - htrc("MySQL ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n", - GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); + htrc("MySQL ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode); if (Mode == MODE_UPDATE || Mode == MODE_DELETE) return SendCommand(g); @@ -1205,7 +1216,7 @@ void TDBMYSQL::CloseDB(PGLOBAL g) PDBUSER dup = PlgGetUser(g); dup->Step = "Enabling indexes"; - sprintf(cmd, "ALTER TABLE `%s` ENABLE KEYS", Tabname); + sprintf(cmd, "ALTER TABLE `%s` ENABLE KEYS", TableName); Myc.m_Rows = -1; // To execute the query m_Rc = Myc.ExecSQL(g, cmd, &w); // May fail for some engines } // endif m_Rc @@ -1463,7 +1474,7 @@ TDBMYEXC::TDBMYEXC(PMYDEF tdp) : TDBMYSQL(tdp) Havew = false; Isw = false; Warnings = 0; - Mxr = tdp->Mxr; + Mxr = tdp->Maxerr; Nerr = 0; } // end of TDBMYEXC constructor @@ -1479,7 +1490,7 @@ TDBMYEXC::TDBMYEXC(PTDBMYX tdbp) : TDBMYSQL(tdbp) } // end of TDBMYEXC copy constructor // Is this really useful ??? -PTDB TDBMYEXC::CopyOne(PTABS t) +PTDB TDBMYEXC::Clone(PTABS t) { PTDB tp; PCOL cp1, cp2; @@ -1494,7 +1505,7 @@ PTDB TDBMYEXC::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate MYSQL column description block. */ @@ -1565,7 +1576,7 @@ bool TDBMYEXC::OpenDB(PGLOBAL g) /* servers allowing concurency in getting results ??? */ /*********************************************************************/ if (!Myc.Connected()) - if (Myc.Open(g, Host, Database, User, Pwd, Port)) + if (Myc.Open(g, Host, Schema, User, Pwd, Port)) return true; Use = USE_OPEN; // Do it now in case we are recursively called @@ -1728,7 +1739,7 @@ void MYXCOL::WriteColumn(PGLOBAL) TDBMCL::TDBMCL(PMYDEF tdp) : TDBCAT(tdp) { Host = tdp->Hostname; - Db = tdp->Database; + Db = tdp->Tabschema; Tab = tdp->Tabname; User = tdp->Username; Pwd = tdp->Password; diff --git a/storage/connect/tabmysql.h b/storage/connect/tabmysql.h index edb15b5cca6..050fa59259b 100644 --- a/storage/connect/tabmysql.h +++ b/storage/connect/tabmysql.h @@ -1,4 +1,4 @@ -// TDBMYSQL.H Olivier Bertrand 2007-2014 +// TDBMYSQL.H Olivier Bertrand 2007-2017 #include "myconn.h" // MySQL connection declares typedef class MYSQLDEF *PMYDEF; @@ -18,7 +18,7 @@ typedef class MYSQLC *PMYC; /***********************************************************************/ /* MYSQL table. */ /***********************************************************************/ -class MYSQLDEF : public TABDEF {/* Logical table description */ +class MYSQLDEF : public EXTDEF {/* Logical table description */ friend class TDBMYSQL; friend class TDBMYEXC; friend class TDBMCL; @@ -27,19 +27,18 @@ class MYSQLDEF : public TABDEF {/* Logical table description */ // Constructor MYSQLDEF(void); - // Implementation virtual const char *GetType(void) {return "MYSQL";} inline PSZ GetHostname(void) {return Hostname;}; - inline PSZ GetDatabase(void) {return Database;}; - inline PSZ GetTabname(void) {return Tabname;} - inline PSZ GetSrcdef(void) {return Srcdef;} - inline PSZ GetUsername(void) {return Username;}; - inline PSZ GetPassword(void) {return Password;}; +//inline PSZ GetDatabase(void) {return Tabschema;}; +//inline PSZ GetTabname(void) {return Tabname;} +//inline PSZ GetSrcdef(void) {return Srcdef;} +//inline PSZ GetUsername(void) {return Username;}; +//inline PSZ GetPassword(void) {return Password;}; inline int GetPortnumber(void) {return Portnumber;} // Methods - virtual int Indexable(void) {return 2;} +//virtual int Indexable(void) {return 2;} virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual PTDB GetTable(PGLOBAL g, MODE m); bool ParseURL(PGLOBAL g, char *url, bool b = true); @@ -48,27 +47,27 @@ class MYSQLDEF : public TABDEF {/* Logical table description */ protected: // Members PSZ Hostname; /* Host machine to use */ - PSZ Database; /* Database to be used by server */ - PSZ Tabname; /* External table name */ - PSZ Srcdef; /* The source table SQL definition */ - PSZ Username; /* User logon name */ - PSZ Password; /* Password logon info */ +//PSZ Tabschema; /* Database to be used by server */ +//PSZ Tabname; /* External table name */ +//PSZ Srcdef; /* The source table SQL definition */ +//PSZ Username; /* User logon name */ +//PSZ Password; /* Password logon info */ PSZ Server; /* PServerID */ - PSZ Qrystr; /* The original query */ +//PSZ Qrystr; /* The original query */ int Portnumber; /* MySQL port number (0 = default) */ - int Mxr; /* Maxerr for an Exec table */ - int Quoted; /* Identifier quoting level */ +//int Maxerr; /* Maxerr for an Exec table */ +//int Quoted; /* Identifier quoting level */ bool Isview; /* true if this table is a MySQL view */ bool Bind; /* Use prepared statement on insert */ bool Delayed; /* Delayed insert */ - bool Xsrc; /* Execution type */ +//bool Xsrc; /* Execution type */ bool Huge; /* True for big table */ }; // end of MYSQLDEF /***********************************************************************/ /* This is the class declaration for the MYSQL table. */ /***********************************************************************/ -class TDBMYSQL : public TDBASE { +class TDBMYSQL : public TDBEXT { friend class MYSQLCOL; public: // Constructor @@ -80,7 +79,7 @@ class TDBMYSQL : public TDBASE { virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYSQL(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); //virtual int GetAffectedRows(void) {return AftRows;} virtual int GetRecpos(void) {return N;} virtual int GetProgMax(PGLOBAL g); @@ -88,12 +87,12 @@ class TDBMYSQL : public TDBASE { virtual int RowNumber(PGLOBAL g, bool b = false); virtual bool IsView(void) {return Isview;} virtual PSZ GetServer(void) {return Server;} - void SetDatabase(LPCSTR db) {Database = (char*)db;} + void SetDatabase(LPCSTR db) {Schema = (char*)db;} - // Database routines + // Schema routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual int Cardinality(PGLOBAL g); - virtual int GetMaxSize(PGLOBAL g); +//virtual int GetMaxSize(PGLOBAL g); virtual bool OpenDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g); @@ -111,7 +110,7 @@ class TDBMYSQL : public TDBASE { bool MakeSelect(PGLOBAL g, bool mx); bool MakeInsert(PGLOBAL g); int BindColumns(PGLOBAL g); - int MakeCommand(PGLOBAL g); + virtual bool MakeCommand(PGLOBAL g); //int MakeUpdate(PGLOBAL g); //int MakeDelete(PGLOBAL g); int SendCommand(PGLOBAL g); @@ -119,25 +118,25 @@ class TDBMYSQL : public TDBASE { // Members MYSQLC Myc; // MySQL connection class MYSQL_BIND *Bind; // To the MySQL bind structure array - PSTRG Query; // Constructed SQL query +//PSTRG Query; // Constructed SQL query char *Host; // Host machine to use - char *User; // User logon info - char *Pwd; // Password logon info - char *Database; // Database to be used by server - char *Tabname; // External table name - char *Srcdef; // The source table SQL definition +//char *User; // User logon info +//char *Pwd; // Password logon info +//char *Schema; // Database to be used by server +//char *TableName; // External table name +//char *Srcdef; // The source table SQL definition char *Server; // The server ID - char *Qrystr; // The original query +//char *Qrystr; // The original query bool Fetched; // True when fetch was done bool Isview; // True if this table is a MySQL view bool Prep; // Use prepared statement on insert bool Delayed; // Use delayed insert int m_Rc; // Return code from command - int AftRows; // The number of affected rows +//int AftRows; // The number of affected rows int N; // The current table index int Port; // MySQL port number (0 = default) - int Nparm; // The number of statement parameters - int Quoted; // The identifier quoting level +//int Nparm; // The number of statement parameters +//int Quoted; // The identifier quoting level }; // end of class TDBMYSQL /***********************************************************************/ @@ -162,9 +161,6 @@ class MYSQLCOL : public COLBLK { bool FindRank(PGLOBAL g); protected: - // Default constructor not to be used - MYSQLCOL(void) {} - // Members MYSQL_BIND *Bind; // This column bind structure pointer PVAL To_Val; // To value used for Update/Insert @@ -187,7 +183,7 @@ class TDBMYEXC : public TDBMYSQL { virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBMYEXC(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual bool IsView(void) {return Isview;} // Database routines @@ -228,9 +224,6 @@ class MYXCOL : public MYSQLCOL { virtual void WriteColumn(PGLOBAL g); protected: - // Default constructor not to be used - MYXCOL(void) {} - // Members char *Buffer; // To get returned message int Flag; // Column content desc diff --git a/storage/connect/taboccur.cpp b/storage/connect/taboccur.cpp index 07e260154e0..07272d1b298 100644 --- a/storage/connect/taboccur.cpp +++ b/storage/connect/taboccur.cpp @@ -1,7 +1,7 @@ /************ TabOccur CPP Declares Source Code File (.CPP) ************/ -/* Name: TABOCCUR.CPP Version 1.1 */ +/* Name: TABOCCUR.CPP Version 1.2 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2013 - 2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */ /* */ /* OCCUR: Table that provides a view of a source table where the */ /* contain of several columns of the source table is placed in only */ @@ -39,12 +39,13 @@ /***********************************************************************/ #include "global.h" #include "plgdbsem.h" -#include "reldef.h" +#include "xtable.h" +#include "tabext.h" +//#include "reldef.h" #include "filamtxt.h" #include "tabdos.h" #include "tabcol.h" #include "taboccur.h" -#include "xtable.h" #include "tabmysql.h" #include "ha_connect.h" diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index f3ffc99ac15..488acdd330d 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -67,10 +67,11 @@ #include "plgdbsem.h" #include "mycat.h" #include "xtable.h" +#include "tabext.h" #include "odbccat.h" #include "tabodbc.h" #include "tabmul.h" -#include "reldef.h" +//#include "reldef.h" #include "tabcol.h" #include "valblk.h" #include "ha_connect.h" @@ -95,10 +96,9 @@ bool ExactInfo(void); /***********************************************************************/ ODBCDEF::ODBCDEF(void) { - Connect = Tabname = Tabschema = Username = Password = NULL; - Tabcat = Colpat = Srcdef = Qchar = Qrystr = Sep = NULL; - Catver = Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0; - Scrollable = Xsrc = UseCnc = false; + Connect = NULL; + Catver = 0; + UseCnc = false; } // end of ODBCDEF constructor /***********************************************************************/ @@ -113,47 +113,50 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) return true; } // endif Connect - Tabname = GetStringCatInfo(g, "Name", - (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); - Tabname = GetStringCatInfo(g, "Tabname", Tabname); - Tabschema = GetStringCatInfo(g, "Dbname", NULL); - Tabschema = GetStringCatInfo(g, "Schema", Tabschema); - Tabcat = GetStringCatInfo(g, "Qualifier", NULL); - Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); - Username = GetStringCatInfo(g, "User", NULL); - Password = GetStringCatInfo(g, "Password", NULL); - - if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) - Read_Only = true; - - Qrystr = GetStringCatInfo(g, "Query_String", "?"); - Sep = GetStringCatInfo(g, "Separator", NULL); + if (EXTDEF::DefineAM(g, am, poff)) + return true; + + // Tabname = GetStringCatInfo(g, "Name", + // (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); + // Tabname = GetStringCatInfo(g, "Tabname", Tabname); + // Tabschema = GetStringCatInfo(g, "Dbname", NULL); + // Tabschema = GetStringCatInfo(g, "Schema", Tabschema); + // Tabcat = GetStringCatInfo(g, "Qualifier", NULL); + // Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); + //Username = GetStringCatInfo(g, "User", NULL); + // Password = GetStringCatInfo(g, "Password", NULL); + + // if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) + // Read_Only = true; + + // Qrystr = GetStringCatInfo(g, "Query_String", "?"); + // Sep = GetStringCatInfo(g, "Separator", NULL); Catver = GetIntCatInfo("Catver", 2); - Xsrc = GetBoolCatInfo("Execsrc", FALSE); - Maxerr = GetIntCatInfo("Maxerr", 0); - Maxres = GetIntCatInfo("Maxres", 0); - Quoted = GetIntCatInfo("Quoted", 0); + //Xsrc = GetBoolCatInfo("Execsrc", FALSE); + //Maxerr = GetIntCatInfo("Maxerr", 0); + //Maxres = GetIntCatInfo("Maxres", 0); + //Quoted = GetIntCatInfo("Quoted", 0); Options = ODBConn::noOdbcDialog; //Options = ODBConn::noOdbcDialog | ODBConn::useCursorLib; Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); - if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt) - Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch + //if ((Scrollable = GetBoolCatInfo("Scrollable", false)) && !Elemt) + // Elemt = 1; // Cannot merge SQLFetch and SQLExtendedFetch - if (Catfunc == FNC_COL) - Colpat = GetStringCatInfo(g, "Colpat", NULL); + //if (Catfunc == FNC_COL) + // Colpat = GetStringCatInfo(g, "Colpat", NULL); - if (Catfunc == FNC_TABLE) - Tabtyp = GetStringCatInfo(g, "Tabtype", NULL); + //if (Catfunc == FNC_TABLE) + // Tabtyp = GetStringCatInfo(g, "Tabtype", NULL); UseCnc = GetBoolCatInfo("UseDSN", false); // Memory was Boolean, it is now integer - if (!(Memory = GetIntCatInfo("Memory", 0))) - Memory = GetBoolCatInfo("Memory", false) ? 1 : 0; + //if (!(Memory = GetIntCatInfo("Memory", 0))) + // Memory = GetBoolCatInfo("Memory", false) ? 1 : 0; - Pseudo = 2; // FILID is Ok but not ROWID + //Pseudo = 2; // FILID is Ok but not ROWID return false; } // end of DefineAM @@ -162,7 +165,7 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) /***********************************************************************/ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) { - PTDBASE tdbp = NULL; + PTDB tdbp = NULL; /*********************************************************************/ /* Allocate a TDB of the proper type. */ @@ -200,103 +203,103 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m) /***********************************************************************/ /* Implementation of the TDBODBC class. */ /***********************************************************************/ -TDBODBC::TDBODBC(PODEF tdp) : TDBASE(tdp) +TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp) { Ocp = NULL; Cnp = NULL; if (tdp) { Connect = tdp->Connect; - TableName = tdp->Tabname; - Schema = tdp->Tabschema; + //TableName = tdp->Tabname; + //Schema = tdp->Tabschema; Ops.User = tdp->Username; Ops.Pwd = tdp->Password; - Catalog = tdp->Tabcat; - Srcdef = tdp->Srcdef; - Qrystr = tdp->Qrystr; - Sep = tdp->GetSep(); - Options = tdp->Options; + //Catalog = tdp->Tabcat; + //Srcdef = tdp->Srcdef; + //Qrystr = tdp->Qrystr; + //Sep = tdp->GetSep(); + //Options = tdp->Options; Ops.Cto = tdp->Cto; Ops.Qto = tdp->Qto; - Quoted = MY_MAX(0, tdp->GetQuoted()); - Rows = tdp->GetElemt(); + //Quoted = MY_MAX(0, tdp->GetQuoted()); + //Rows = tdp->GetElemt(); Catver = tdp->Catver; - Memory = tdp->Memory; - Scrollable = tdp->Scrollable; + //Memory = tdp->Memory; + //Scrollable = tdp->Scrollable; Ops.UseCnc = tdp->UseCnc; } else { Connect = NULL; - TableName = NULL; - Schema = NULL; + //TableName = NULL; + //Schema = NULL; Ops.User = NULL; Ops.Pwd = NULL; - Catalog = NULL; - Srcdef = NULL; - Qrystr = NULL; - Sep = 0; - Options = 0; + //Catalog = NULL; + //Srcdef = NULL; + //Qrystr = NULL; + //Sep = 0; + //Options = 0; Ops.Cto = DEFAULT_LOGIN_TIMEOUT; Ops.Qto = DEFAULT_QUERY_TIMEOUT; - Quoted = 0; - Rows = 0; + //Quoted = 0; + //Rows = 0; Catver = 0; - Memory = 0; - Scrollable = false; + //Memory = 0; + //Scrollable = false; Ops.UseCnc = false; } // endif tdp - Quote = NULL; - Query = NULL; - Count = NULL; + //Quote = NULL; + //Query = NULL; + //Count = NULL; //Where = NULL; - MulConn = NULL; - DBQ = NULL; - Qrp = NULL; - Fpos = 0; - Curpos = 0; - AftRows = 0; - CurNum = 0; - Rbuf = 0; - BufSize = 0; - Nparm = 0; - Placed = false; + //MulConn = NULL; + //DBQ = NULL; + //Qrp = NULL; + //Fpos = 0; + //Curpos = 0; + //AftRows = 0; + //CurNum = 0; + //Rbuf = 0; + //BufSize = 0; + //Nparm = 0; + //Placed = false; } // end of TDBODBC standard constructor -TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBASE(tdbp) +TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp) { Ocp = tdbp->Ocp; // is that right ? Cnp = tdbp->Cnp; Connect = tdbp->Connect; - TableName = tdbp->TableName; - Schema = tdbp->Schema; + //TableName = tdbp->TableName; + //Schema = tdbp->Schema; Ops = tdbp->Ops; - Catalog = tdbp->Catalog; - Srcdef = tdbp->Srcdef; - Qrystr = tdbp->Qrystr; - Memory = tdbp->Memory; - Scrollable = tdbp->Scrollable; - Quote = tdbp->Quote; - Query = tdbp->Query; - Count = tdbp->Count; + //Catalog = tdbp->Catalog; + //Srcdef = tdbp->Srcdef; + //Qrystr = tdbp->Qrystr; + //Memory = tdbp->Memory; + //Scrollable = tdbp->Scrollable; + //Quote = tdbp->Quote; + //Query = tdbp->Query; + //Count = tdbp->Count; //Where = tdbp->Where; - MulConn = tdbp->MulConn; - DBQ = tdbp->DBQ; - Options = tdbp->Options; - Quoted = tdbp->Quoted; - Rows = tdbp->Rows; - Fpos = 0; - Curpos = 0; - AftRows = 0; - CurNum = 0; - Rbuf = 0; - BufSize = tdbp->BufSize; - Nparm = tdbp->Nparm; - Qrp = tdbp->Qrp; - Placed = false; + //MulConn = tdbp->MulConn; + //DBQ = tdbp->DBQ; + //Options = tdbp->Options; + //Quoted = tdbp->Quoted; + //Rows = tdbp->Rows; + //Fpos = 0; + //Curpos = 0; + //AftRows = 0; + //CurNum = 0; + //Rbuf = 0; + //BufSize = tdbp->BufSize; + //Nparm = tdbp->Nparm; + //Qrp = tdbp->Qrp; + //Placed = false; } // end of TDBODBC copy constructor // Method -PTDB TDBODBC::CopyOne(PTABS t) +PTDB TDBODBC::Clone(PTABS t) { PTDB tp; PODBCCOL cp1, cp2; @@ -386,6 +389,7 @@ void TDBODBC::SetFile(PGLOBAL g, PSZ fn) DBQ = fn; } // end of SetFile +#if 0 /******************************************************************/ /* Convert an UTF-8 string to latin characters. */ /******************************************************************/ @@ -414,7 +418,15 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt) PCOL colp; if (Srcdef) { - Query = new(g)STRING(g, 0, Srcdef); + if (strstr(Srcdef, "%s")) { + char *fil; + + fil = (To_CondFil) ? To_CondFil->Body : PlugDup(g, "1=1"); + Query = new(g)STRING(g, strlen(Srcdef) + strlen(fil)); + Query->SetLength(sprintf(Query->GetStr(), Srcdef, fil)); + } else + Query = new(g)STRING(g, 0, Srcdef); + return false; } // endif Srcdef @@ -442,7 +454,8 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt) } else oom |= Query->Append(buf); - } // endif colp + ((PEXTCOL)colp)->SetRank(++Ncol); + } // endif colp } else // !Columns can occur for queries such that sql count(*) from... @@ -458,10 +471,6 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt) if (Catalog && *Catalog) catp = Catalog; - // Following lines are commented because of MSDEV-10520 - // Indeed the schema in the tablep is the local table database and - // is normally not related to the remote table database. - // TODO: Try to remember why this was done and if it was useful in some case. //if (tablep->GetSchema()) // schmp = (char*)tablep->GetSchema(); //else @@ -516,6 +525,7 @@ bool TDBODBC::MakeSQL(PGLOBAL g, bool cnt) return false; } // end of MakeSQL +#endif // 0 /***********************************************************************/ /* MakeInsert: make the Insert statement used with ODBC connection. */ @@ -536,7 +546,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g) // Column name can be encoded in UTF-8 Decode(colp->GetName(), buf, sizeof(buf)); len += (strlen(buf) + 6); // comma + quotes + valist - ((PODBCCOL)colp)->Rank = ++Nparm; + ((PEXTCOL)colp)->SetRank(++Nparm); } // endif colp // Below 32 is enough to contain the fixed part of the query @@ -555,7 +565,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g) if (schmp) len += strlen(schmp) + 1; - // Column name can be encoded in UTF-8 + // Table name can be encoded in UTF-8 Decode(TableName, buf, sizeof(buf)); len += (strlen(buf) + 32); Query = new(g) STRING(g, len, "INSERT INTO "); @@ -634,6 +644,7 @@ bool TDBODBC::BindParameters(PGLOBAL g) return false; } // end of BindParameters +#if 0 /***********************************************************************/ /* MakeCommand: make the Update or Delete statement to send to the */ /* MySQL server. Limited to remote values and filtering. */ @@ -664,19 +675,20 @@ bool TDBODBC::MakeCommand(PGLOBAL g) // If so, it must be quoted in the original query strlwr(strcat(strcat(strcpy(name, " "), Name), " ")); - if (!strstr(" update delete low_priority ignore quick from ", name)) - strlwr(strcpy(name, Name)); // Not a keyword - else - strlwr(strcat(strcat(strcpy(name, qc), Name), qc)); + if (strstr(" update delete low_priority ignore quick from ", name)) { + strlwr(strcat(strcat(strcpy(name, qc), Name), qc)); + k += 2; + } else + strlwr(strcpy(name, Name)); // Not a keyword if ((p = strstr(qrystr, name))) { for (i = 0; i < p - qrystr; i++) stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i]; stmt[i] = 0; - k = i + (int)strlen(Name); + k += i + (int)strlen(Name); - if (qtd && *(p-1) == ' ') + if (qtd && *(p - 1) == ' ') strcat(strcat(strcat(stmt, qc), TableName), qc); else strcat(stmt, TableName); @@ -692,15 +704,14 @@ bool TDBODBC::MakeCommand(PGLOBAL g) } else { sprintf(g->Message, "Cannot use this %s command", - (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); - return false; + (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); + return true; } // endif p Query = new(g) STRING(g, 0, stmt); return (!Query->GetSize()); } // end of MakeCommand -#if 0 /***********************************************************************/ /* MakeUpdate: make the SQL statement to send to ODBC connection. */ /***********************************************************************/ @@ -818,6 +829,7 @@ int TDBODBC::Cardinality(PGLOBAL g) return Cardinal; } // end of Cardinality +#if 0 /***********************************************************************/ /* ODBC GetMaxSize: returns table size estimate in number of lines. */ /***********************************************************************/ @@ -844,6 +856,7 @@ int TDBODBC::GetProgMax(PGLOBAL g) { return GetMaxSize(g); } // end of GetProgMax +#endif // 0 /***********************************************************************/ /* ODBC Access Method opening routine. */ @@ -981,6 +994,7 @@ bool TDBODBC::OpenDB(PGLOBAL g) return false; } // end of OpenDB +#if 0 /***********************************************************************/ /* GetRecpos: return the position of last read record. */ /***********************************************************************/ @@ -988,6 +1002,7 @@ int TDBODBC::GetRecpos(void) { return Fpos; } // end of GetRecpos +#endif // 0 /***********************************************************************/ /* SetRecpos: set the position of next read record. */ @@ -1081,8 +1096,9 @@ int TDBODBC::ReadDB(PGLOBAL g) int rc; if (trace > 1) - htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n", - GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); + htrc("ODBC ReadDB: R%d Mode=%d\n", GetTdb_No(), Mode); + //htrc("ODBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n", + // GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { if (!Query && MakeCommand(g)) @@ -1102,11 +1118,11 @@ int TDBODBC::ReadDB(PGLOBAL g) } // endif Mode - if (To_Kindex) { - // Direct access of ODBC tables is not implemented yet - strcpy(g->Message, MSG(NO_ODBC_DIRECT)); - return RC_FX; - } // endif To_Kindex + //if (To_Kindex) { + // // Direct access of ODBC tables is not implemented yet + // strcpy(g->Message, MSG(NO_ODBC_DIRECT)); + // return RC_FX; + // } // endif To_Kindex /*********************************************************************/ /* Now start the reading process. */ @@ -1212,70 +1228,58 @@ void TDBODBC::CloseDB(PGLOBAL g) /* ODBCCOL public constructor. */ /***********************************************************************/ ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) - : COLBLK(cdp, tdbp, i) + : EXTCOL(cdp, tdbp, cprec, i, am) { - if (cprec) { - Next = cprec->GetNext(); - cprec->SetNext(this); - } else { - Next = tdbp->GetColumns(); - tdbp->SetColumns(this); - } // endif cprec - // Set additional ODBC access method information for column. - Crp = NULL; -//Long = cdp->GetLong(); - Long = Precision; +//Crp = NULL; +//Long = Precision; //strcpy(F_Date, cdp->F_Date); - To_Val = NULL; +//To_Val = NULL; Slen = 0; StrLen = &Slen; Sqlbuf = NULL; - Bufp = NULL; - Blkp = NULL; - Rank = 0; // Not known yet - - if (trace) - htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); - +//Bufp = NULL; +//Blkp = NULL; +//Rank = 0; // Not known yet } // end of ODBCCOL constructor /***********************************************************************/ /* ODBCCOL private constructor. */ /***********************************************************************/ -ODBCCOL::ODBCCOL(void) : COLBLK() +ODBCCOL::ODBCCOL(void) : EXTCOL() { - Crp = NULL; - Buf_Type = TYPE_INT; // This is a count(*) column - // Set additional Dos access method information for column. - Long = sizeof(int); - To_Val = NULL; +//Crp = NULL; +//Buf_Type = TYPE_INT; // This is a count(*) column +//// Set additional Dos access method information for column. +//Long = sizeof(int); +//To_Val = NULL; Slen = 0; StrLen = &Slen; Sqlbuf = NULL; - Bufp = NULL; - Blkp = NULL; - Rank = 1; +//Bufp = NULL; +//Blkp = NULL; +//Rank = 1; } // end of ODBCCOL constructor /***********************************************************************/ /* ODBCCOL constructor used for copying columns. */ /* tdbp is the pointer to the new table descriptor. */ /***********************************************************************/ -ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) +ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp) { - Crp = col1->Crp; - Long = col1->Long; +//Crp = col1->Crp; +//Long = col1->Long; //strcpy(F_Date, col1->F_Date); - To_Val = col1->To_Val; +//To_Val = col1->To_Val; Slen = col1->Slen; StrLen = col1->StrLen; Sqlbuf = col1->Sqlbuf; - Bufp = col1->Bufp; - Blkp = col1->Blkp; - Rank = col1->Rank; +//Bufp = col1->Bufp; +//Blkp = col1->Blkp; +//Rank = col1->Rank; } // end of ODBCCOL copy constructor +#if 0 /***********************************************************************/ /* SetBuffer: prepare a column block for write operation. */ /***********************************************************************/ @@ -1321,6 +1325,7 @@ bool ODBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) Status = (ok) ? BUF_EMPTY : BUF_NO; return false; } // end of SetBuffer +#endif // 0 /***********************************************************************/ /* ReadColumn: when SQLFetch is used there is nothing to do as the */ @@ -1526,7 +1531,7 @@ TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp) Nerr = tdbp->Nerr; } // end of TDBXDBC copy constructor -PTDB TDBXDBC::CopyOne(PTABS t) +PTDB TDBXDBC::Clone(PTABS t) { PTDB tp; PXSRCCOL cp1, cp2; diff --git a/storage/connect/tabodbc.h b/storage/connect/tabodbc.h index aa6592d8abf..fcefad5647b 100644 --- a/storage/connect/tabodbc.h +++ b/storage/connect/tabodbc.h @@ -20,7 +20,7 @@ typedef class TDBSRC *PTDBSRC; /***********************************************************************/ /* ODBC table. */ /***********************************************************************/ -class DllExport ODBCDEF : public TABDEF { /* Logical table description */ +class DllExport ODBCDEF : public EXTDEF { /* Logical table description */ friend class TDBODBC; friend class TDBXDBC; friend class TDBDRV; @@ -33,14 +33,14 @@ public: // Implementation virtual const char *GetType(void) {return "ODBC";} PSZ GetConnect(void) {return Connect;} - PSZ GetTabname(void) {return Tabname;} - PSZ GetTabschema(void) {return Tabschema;} - PSZ GetTabcat(void) {return Tabcat;} - PSZ GetSrcdef(void) {return Srcdef;} - char GetSep(void) {return (Sep) ? *Sep : 0;} - int GetQuoted(void) {return Quoted;} + //PSZ GetTabname(void) {return Tabname;} + //PSZ GetTabschema(void) {return Tabschema;} + //PSZ GetTabcat(void) {return Tabcat;} + //PSZ GetSrcdef(void) {return Srcdef;} + //char GetSep(void) {return (Sep) ? *Sep : 0;} + //int GetQuoted(void) {return Quoted;} int GetCatver(void) {return Catver;} - int GetOptions(void) {return Options;} + //int GetOptions(void) {return Options;} // Methods virtual int Indexable(void) {return 2;} @@ -50,27 +50,27 @@ public: protected: // Members PSZ Connect; /* ODBC connection string */ - PSZ Tabname; /* External table name */ - PSZ Tabschema; /* External table schema */ - PSZ Username; /* User connect name */ - PSZ Password; /* Password connect info */ - PSZ Tabcat; /* External table catalog */ - PSZ Tabtyp; /* Catalog table type */ - PSZ Colpat; /* Catalog column pattern */ - PSZ Srcdef; /* The source table SQL definition */ - PSZ Qchar; /* Identifier quoting character */ - PSZ Qrystr; /* The original query */ - PSZ Sep; /* Decimal separator */ + //PSZ Tabname; /* External table name */ + //PSZ Tabschema; /* External table schema */ + //PSZ Username; /* User connect name */ + //PSZ Password; /* Password connect info */ + //PSZ Tabcat; /* External table catalog */ + //PSZ Tabtyp; /* Catalog table type */ + //PSZ Colpat; /* Catalog column pattern */ + //PSZ Srcdef; /* The source table SQL definition */ + //PSZ Qchar; /* Identifier quoting character */ + //PSZ Qrystr; /* The original query */ + //PSZ Sep; /* Decimal separator */ int Catver; /* ODBC version for catalog functions */ - int Options; /* Open connection options */ - int Cto; /* Open connection timeout */ - int Qto; /* Query (command) timeout */ - int Quoted; /* Identifier quoting level */ - int Maxerr; /* Maxerr for an Exec table */ - int Maxres; /* Maxres for a catalog table */ - int Memory; /* Put result set in memory */ - bool Scrollable; /* Use scrollable cursor */ - bool Xsrc; /* Execution type */ + //int Options; /* Open connection options */ + //int Cto; /* Open connection timeout */ + //int Qto; /* Query (command) timeout */ + //int Quoted; /* Identifier quoting level */ + //int Maxerr; /* Maxerr for an Exec table */ + //int Maxres; /* Maxres for a catalog table */ + //int Memory; /* Put result set in memory */ + //bool Scrollable; /* Use scrollable cursor */ + //bool Xsrc; /* Execution type */ bool UseCnc; /* Use SQLConnect (!SQLDriverConnect) */ }; // end of ODBCDEF @@ -81,7 +81,7 @@ public: /* This is the ODBC Access Method class declaration for files from */ /* other DB drivers to be accessed via ODBC. */ /***********************************************************************/ -class TDBODBC : public TDBASE { +class TDBODBC : public TDBEXT { friend class ODBCCOL; friend class ODBConn; public: @@ -95,8 +95,8 @@ class TDBODBC : public TDBASE { {return (PTDB)new(g) TDBODBC(this);} // Methods - virtual PTDB CopyOne(PTABS t); - virtual int GetRecpos(void); + virtual PTDB Clone(PTABS t); +//virtual int GetRecpos(void); virtual bool SetRecpos(PGLOBAL g, int recpos); virtual PSZ GetFile(PGLOBAL g); virtual void SetFile(PGLOBAL g, PSZ fn); @@ -108,8 +108,8 @@ class TDBODBC : public TDBASE { // Database routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); virtual int Cardinality(PGLOBAL g); - virtual int GetMaxSize(PGLOBAL g); - virtual int GetProgMax(PGLOBAL g); +//virtual int GetMaxSize(PGLOBAL g); +//virtual int GetProgMax(PGLOBAL g); virtual bool OpenDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g); @@ -119,10 +119,10 @@ class TDBODBC : public TDBASE { protected: // Internal functions - int Decode(char *utf, char *buf, size_t n); - bool MakeSQL(PGLOBAL g, bool cnt); +//int Decode(char *utf, char *buf, size_t n); +//bool MakeSQL(PGLOBAL g, bool cnt); bool MakeInsert(PGLOBAL g); - bool MakeCommand(PGLOBAL g); +//virtual bool MakeCommand(PGLOBAL g); //bool MakeFilter(PGLOBAL g, bool c); bool BindParameters(PGLOBAL g); //char *MakeUpdate(PGLOBAL g); @@ -132,46 +132,16 @@ class TDBODBC : public TDBASE { ODBConn *Ocp; // Points to an ODBC connection class ODBCCOL *Cnp; // Points to count(*) column ODBCPARM Ops; // Additional parameters - PSTRG Query; // Constructed SQL query char *Connect; // Points to connection string - char *TableName; // Points to ODBC table name - char *Schema; // Points to ODBC table Schema - char *User; // User connect info - char *Pwd; // Password connect info - char *Catalog; // Points to ODBC table Catalog - char *Srcdef; // The source table SQL definition - char *Count; // Points to count(*) SQL statement -//char *Where; // Points to local where clause - char *Quote; // The identifier quoting character - char *MulConn; // Used for multiple ODBC tables - char *DBQ; // The address part of Connect string - char *Qrystr; // The original query - char Sep; // The decimal separator - int Options; // Connect options - int Cto; // Connect timeout - int Qto; // Query timeout - int Quoted; // The identifier quoting level - int Fpos; // Position of last read record - int Curpos; // Cursor position of last fetch - int AftRows; // The number of affected rows - int Rows; // Rowset size int Catver; // Catalog ODBC version - int CurNum; // Current buffer line number - int Rbuf; // Number of lines read in buffer - int BufSize; // Size of connect string buffer - int Nparm; // The number of statement parameters - int Memory; // 0: No 1: Alloc 2: Put 3: Get - bool Scrollable; // Use scrollable cursor - bool Placed; // True for position reading bool UseCnc; // Use SQLConnect (!SQLDriverConnect) - PQRYRES Qrp; // Points to storage result }; // end of class TDBODBC /***********************************************************************/ /* Class ODBCCOL: ODBC access method column descriptor. */ /* This A.M. is used for ODBC tables. */ /***********************************************************************/ -class ODBCCOL : public COLBLK { +class ODBCCOL : public EXTCOL { friend class TDBODBC; public: // Constructors @@ -181,12 +151,12 @@ class ODBCCOL : public COLBLK { // Implementation virtual int GetAmType(void) {return TYPE_AM_ODBC;} SQLLEN *GetStrLen(void) {return StrLen;} - int GetRank(void) {return Rank;} +// int GetRank(void) {return Rank;} // PVBLK GetBlkp(void) {return Blkp;} - void SetCrp(PCOLRES crp) {Crp = crp;} +// void SetCrp(PCOLRES crp) {Crp = crp;} // Methods - virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); +//virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); virtual void ReadColumn(PGLOBAL g); virtual void WriteColumn(PGLOBAL g); void AllocateBuffers(PGLOBAL g, int rows); @@ -195,19 +165,19 @@ class ODBCCOL : public COLBLK { // void Print(PGLOBAL g, FILE *, uint); protected: - // Constructor used by GetMaxSize + // Constructor for count(*) column ODBCCOL(void); // Members TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's - PCOLRES Crp; // To storage result - void *Bufp; // To extended buffer - PVBLK Blkp; // To Value Block +//PCOLRES Crp; // To storage result +//void *Bufp; // To extended buffer +//PVBLK Blkp; // To Value Block //char F_Date[12]; // Internal Date format - PVAL To_Val; // To value used for Insert +//PVAL To_Val; // To value used for Insert SQLLEN *StrLen; // As returned by ODBC SQLLEN Slen; // Used with Fetch - int Rank; // Rank (position) number in the query +//int Rank; // Rank (position) number in the query }; // end of class ODBCCOL /***********************************************************************/ @@ -228,28 +198,19 @@ class TDBXDBC : public TDBODBC { {return (PTDB)new(g) TDBXDBC(this);} // Methods - virtual PTDB CopyOne(PTABS t); -//virtual int GetRecpos(void); -//virtual PSZ GetFile(PGLOBAL g); -//virtual void SetFile(PGLOBAL g, PSZ fn); -//virtual void ResetSize(void); -//virtual int GetAffectedRows(void) {return AftRows;} -//virtual PSZ GetServer(void) {return "ODBC";} + virtual PTDB Clone(PTABS t); // Database routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); -//virtual int GetProgMax(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); protected: // Internal functions PCMD MakeCMD(PGLOBAL g); -//bool BindParameters(PGLOBAL g); // Members PCMD Cmdlist; // The commands to execute diff --git a/storage/connect/tabpivot.cpp b/storage/connect/tabpivot.cpp index 256b454741c..c6d32884417 100644 --- a/storage/connect/tabpivot.cpp +++ b/storage/connect/tabpivot.cpp @@ -1,11 +1,11 @@ /************ TabPivot C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABPIVOT */ /* ------------- */ -/* Version 1.6 */ +/* Version 1.7 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2005-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2005-2017 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -41,6 +41,7 @@ #include "global.h" #include "plgdbsem.h" #include "xtable.h" +#include "tabext.h" #include "tabcol.h" #include "colblk.h" #include "tabmysql.h" @@ -883,7 +884,7 @@ SRCCOL::SRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int n) /***********************************************************************/ /* Initialize the column as pointing to the source column. */ /***********************************************************************/ -bool SRCCOL::Init(PGLOBAL g, PTDBASE tp) +bool SRCCOL::Init(PGLOBAL g, PTDB tp) { if (PRXCOL::Init(g, tp)) return true; diff --git a/storage/connect/tabpivot.h b/storage/connect/tabpivot.h index c397af05234..07d5c3e456b 100644 --- a/storage/connect/tabpivot.h +++ b/storage/connect/tabpivot.h @@ -183,7 +183,7 @@ class SRCCOL : public PRXCOL { using PRXCOL::Init; virtual void Reset(void) {} void SetColumn(void); - virtual bool Init(PGLOBAL g, PTDBASE tp); + virtual bool Init(PGLOBAL g, PTDB tp); bool CompareLast(void); protected: diff --git a/storage/connect/tabsys.cpp b/storage/connect/tabsys.cpp index 76890e84429..2ddd1c3c753 100644 --- a/storage/connect/tabsys.cpp +++ b/storage/connect/tabsys.cpp @@ -159,7 +159,7 @@ TDBINI::TDBINI(PTDBINI tdbp) : TDBASE(tdbp) } // end of TDBINI copy constructor // Is this really useful ??? -PTDB TDBINI::CopyOne(PTABS t) +PTDB TDBINI::Clone(PTABS t) { PTDB tp; PINICOL cp1, cp2; @@ -173,7 +173,7 @@ PTDB TDBINI::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Get the section list from the INI file. */ @@ -565,7 +565,7 @@ TDBXIN::TDBXIN(PTDBXIN tdbp) : TDBINI(tdbp) } // end of TDBXIN copy constructor // Is this really useful ??? -PTDB TDBXIN::CopyOne(PTABS t) +PTDB TDBXIN::Clone(PTABS t) { PTDB tp; PXINCOL cp1, cp2; @@ -579,7 +579,7 @@ PTDB TDBXIN::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Get the key list from the INI file. */ diff --git a/storage/connect/tabsys.h b/storage/connect/tabsys.h index 6b454322906..ff1b8335690 100644 --- a/storage/connect/tabsys.h +++ b/storage/connect/tabsys.h @@ -57,7 +57,7 @@ class TDBINI : public TDBASE { virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBINI(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual int GetRecpos(void) {return N;} virtual int GetProgCur(void) {return N;} //virtual int GetAffectedRows(void) {return 0;} @@ -136,7 +136,7 @@ class TDBXIN : public TDBINI { virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBXIN(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual int GetRecpos(void); virtual bool SetRecpos(PGLOBAL g, int recpos); virtual void ResetDB(void) diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index e3baf7c3da5..0bf3f6beb43 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -1,11 +1,11 @@ /************* TabTbl C++ Program Source Code File (.CPP) **************/ /* PROGRAM NAME: TABTBL */ /* ------------- */ -/* Version 1.7 */ +/* Version 1.8 */ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to PlugDB Software Development 2008-2016 */ +/* (C) Copyright to PlugDB Software Development 2008-2017 */ /* Author: Olivier BERTRAND */ /* */ /* WHAT THIS PROGRAM DOES: */ @@ -70,6 +70,7 @@ #include "tabcol.h" #include "tabdos.h" // TDBDOS and DOSCOL class dcls #include "tabtbl.h" +#include "tabext.h" #include "tabmysql.h" #include "ha_connect.h" @@ -411,9 +412,9 @@ void TDBTBL::ResetDB(void) colp->COLBLK::Reset(); for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) - ((PTDBASE)tabp->GetTo_Tdb())->ResetDB(); + tabp->GetTo_Tdb()->ResetDB(); - Tdbp = (PTDBASE)Tablist->GetTo_Tdb(); + Tdbp = Tablist->GetTo_Tdb(); Crp = 0; } // end of ResetDB @@ -458,7 +459,7 @@ bool TDBTBL::OpenDB(PGLOBAL g) return TRUE; if ((CurTable = Tablist)) { - Tdbp = (PTDBASE)CurTable->GetTo_Tdb(); + Tdbp = CurTable->GetTo_Tdb(); // Tdbp->SetMode(Mode); // Tdbp->ResetDB(); // Tdbp->ResetSize(); @@ -515,7 +516,7 @@ int TDBTBL::ReadDB(PGLOBAL g) /* Continue reading from next table file. */ /***************************************************************/ Tdbp->CloseDB(g); - Tdbp = (PTDBASE)CurTable->GetTo_Tdb(); + Tdbp = CurTable->GetTo_Tdb(); // Check and initialize the subtable columns for (PCOL cp = Columns; cp; cp = cp->GetNext()) @@ -609,13 +610,13 @@ void TDBTBM::ResetDB(void) // Local tables for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) - ((PTDBASE)tabp->GetTo_Tdb())->ResetDB(); + tabp->GetTo_Tdb()->ResetDB(); // Remote tables for (PTBMT tp = Tmp; tp; tp = tp->Next) - ((PTDBASE)tp->Tap->GetTo_Tdb())->ResetDB(); + tp->Tap->GetTo_Tdb()->ResetDB(); - Tdbp = (Tablist) ? (PTDBASE)Tablist->GetTo_Tdb() : NULL; + Tdbp = (Tablist) ? Tablist->GetTo_Tdb() : NULL; Crp = 0; } // end of ResetDB @@ -716,7 +717,7 @@ bool TDBTBM::OpenDB(PGLOBAL g) /* Proceed with local tables. */ /*********************************************************************/ if ((CurTable = Tablist)) { - Tdbp = (PTDBASE)CurTable->GetTo_Tdb(); + Tdbp = CurTable->GetTo_Tdb(); // Tdbp->SetMode(Mode); // Check and initialize the subtable columns @@ -808,7 +809,7 @@ int TDBTBM::ReadNextRemote(PGLOBAL g) } // endif Curtable - Tdbp = (PTDBASE)Cmp->Tap->GetTo_Tdb(); + Tdbp = Cmp->Tap->GetTo_Tdb(); // Check and initialize the subtable columns for (PCOL cp = Columns; cp; cp = cp->GetNext()) diff --git a/storage/connect/tabutil.cpp b/storage/connect/tabutil.cpp index 4069cdbed2a..762c61bd1a1 100644 --- a/storage/connect/tabutil.cpp +++ b/storage/connect/tabutil.cpp @@ -1,7 +1,7 @@ /************* Tabutil cpp Declares Source Code File (.CPP) ************/ -/* Name: TABUTIL.CPP Version 1.1 */ +/* Name: TABUTIL.CPP Version 1.2 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2013 - 2016 */ +/* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */ /* */ /* Utility function used by the PROXY, XCOL, OCCUR, and TBL tables. */ /***********************************************************************/ @@ -45,8 +45,9 @@ #include "myutil.h" #include "valblk.h" #include "resource.h" -#include "reldef.h" +//#include "reldef.h" #include "xtable.h" +#include "tabext.h" #include "tabmysql.h" #include "tabcol.h" #include "tabutil.h" @@ -356,7 +357,7 @@ TDBPRX::TDBPRX(PTDBPRX tdbp) : TDBASE(tdbp) } // end of TDBPRX copy constructor // Method -PTDB TDBPRX::CopyOne(PTABS t) +PTDB TDBPRX::Clone(PTABS t) { PTDB tp; PPRXCOL cp1, cp2; @@ -370,12 +371,12 @@ PTDB TDBPRX::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Get the PTDB of the sub-table. */ /***********************************************************************/ -PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b) +PTDB TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b) { const char *sp = NULL; char *db, *name; @@ -456,13 +457,13 @@ PTDBASE TDBPRX::GetSubTable(PGLOBAL g, PTABLE tabp, bool b) if (trace && tdbp) htrc("Subtable %s in %s\n", - name, SVP(((PTDBASE)tdbp)->GetDef()->GetDB())); + name, SVP(tdbp->GetDef()->GetDB())); err: if (s) free_table_share(s); - return (PTDBASE)tdbp; + return tdbp; } // end of GetSubTable /***********************************************************************/ @@ -560,9 +561,9 @@ bool TDBPRX::OpenDB(PGLOBAL g) /* its column blocks in mode write (required by XML tables). */ /*********************************************************************/ if (Mode == MODE_UPDATE) { - PTDBASE utp; + PTDB utp; - if (!(utp= (PTDBASE)Tdbp->Duplicate(g))) { + if (!(utp= Tdbp->Duplicate(g))) { sprintf(g->Message, MSG(INV_UPDT_TABLE), Tdbp->GetName()); return true; } // endif tp @@ -681,7 +682,7 @@ char *PRXCOL::Decode(PGLOBAL g, const char *cnm) /* PRXCOL initialization routine. */ /* Look for the matching column in the object table. */ /***********************************************************************/ -bool PRXCOL::Init(PGLOBAL g, PTDBASE tp) +bool PRXCOL::Init(PGLOBAL g, PTDB tp) { if (!tp) tp = ((PTDBPRX)To_Tdb)->Tdbp; diff --git a/storage/connect/tabutil.h b/storage/connect/tabutil.h index b320d169b36..8e56aecff86 100644 --- a/storage/connect/tabutil.h +++ b/storage/connect/tabutil.h @@ -67,7 +67,7 @@ class DllExport TDBPRX : public TDBASE { {return (PTDB)new(g) TDBPRX(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual int GetRecpos(void) {return Tdbp->GetRecpos();} virtual void ResetDB(void) {Tdbp->ResetDB();} virtual int RowNumber(PGLOBAL g, bool b = FALSE); @@ -83,12 +83,12 @@ class DllExport TDBPRX : public TDBASE { virtual int WriteDB(PGLOBAL g); virtual int DeleteDB(PGLOBAL g, int irc); virtual void CloseDB(PGLOBAL g) {if (Tdbp) Tdbp->CloseDB(g);} - PTDBASE GetSubTable(PGLOBAL g, PTABLE tabp, bool b = false); + PTDB GetSubTable(PGLOBAL g, PTABLE tabp, bool b = false); void RemoveNext(PTABLE tp); protected: // Members - PTDBASE Tdbp; // The object table + PTDB Tdbp; // The object table }; // end of class TDBPRX /***********************************************************************/ @@ -115,7 +115,7 @@ class DllExport PRXCOL : public COLBLK { {return false;} virtual void ReadColumn(PGLOBAL g); virtual void WriteColumn(PGLOBAL g); - virtual bool Init(PGLOBAL g, PTDBASE tp); + virtual bool Init(PGLOBAL g, PTDB tp); protected: char *Decode(PGLOBAL g, const char *cnm); diff --git a/storage/connect/tabvct.cpp b/storage/connect/tabvct.cpp index e788529075f..282fb55a43c 100644 --- a/storage/connect/tabvct.cpp +++ b/storage/connect/tabvct.cpp @@ -241,7 +241,7 @@ PTDB VCTDEF::GetTable(PGLOBAL g, MODE mode) /*********************************************************************/ if (mode != MODE_INSERT) if (tdbp->GetBlockValues(g)) - PushWarning(g, (PTDBASE)tdbp); + PushWarning(g, tdbp); // return NULL; // causes a crash when deleting index return tdbp; @@ -263,7 +263,7 @@ TDBVCT::TDBVCT(PGLOBAL g, PTDBVCT tdbp) : TDBFIX(g, tdbp) } // end of TDBVCT copy constructor // Method -PTDB TDBVCT::CopyOne(PTABS t) +PTDB TDBVCT::Clone(PTABS t) { PTDB tp; PVCTCOL cp1, cp2; @@ -277,7 +277,7 @@ PTDB TDBVCT::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate VCT column description block. */ diff --git a/storage/connect/tabvct.h b/storage/connect/tabvct.h index 8ad3c8e21be..189a9ae2221 100644 --- a/storage/connect/tabvct.h +++ b/storage/connect/tabvct.h @@ -68,7 +68,7 @@ class DllExport TDBVCT : public TDBFIX { bool IsSplit(void) {return ((VCTDEF*)To_Def)->Split;} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual bool IsUsingTemp(PGLOBAL g); // Database routines diff --git a/storage/connect/tabvir.cpp b/storage/connect/tabvir.cpp index 356fc981357..155c71fe268 100644 --- a/storage/connect/tabvir.cpp +++ b/storage/connect/tabvir.cpp @@ -20,7 +20,7 @@ #include "plgdbsem.h" #include "filter.h" #include "xtable.h" -#include "reldef.h" +//#include "reldef.h" #include "colblk.h" #include "mycat.h" // for FNC_COL #include "tabvir.h" diff --git a/storage/connect/tabwmi.cpp b/storage/connect/tabwmi.cpp index 98a44b9d635..4871a1d66dc 100644 --- a/storage/connect/tabwmi.cpp +++ b/storage/connect/tabwmi.cpp @@ -1,5 +1,5 @@ /***********************************************************************/ -/* TABWMI: Author Olivier Bertrand -- PlugDB -- 2012 - 2013 */ +/* TABWMI: Author Olivier Bertrand -- PlugDB -- 2012 - 2017 */ /* TABWMI: Virtual table to get WMI information. */ /***********************************************************************/ #if !defined(__WIN__) @@ -11,8 +11,9 @@ #include "global.h" #include "plgdbsem.h" #include "mycat.h" -#include "reldef.h" +//#include "reldef.h" #include "xtable.h" +#include "tabext.h" #include "colblk.h" //#include "filter.h" //#include "xindex.h" @@ -62,7 +63,7 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname) if (FAILED(res)) { sprintf(g->Message, "Failed to initialize COM library. " - "Error code = %p", res); + "Error code = %x", res); return NULL; } // endif res @@ -85,7 +86,7 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname) (void**) &loc); if (FAILED(res)) { sprintf(g->Message, "Failed to create Locator. " - "Error code = %p", res); + "Error code = %x", res); CoUninitialize(); return NULL; } // endif res @@ -94,7 +95,7 @@ PWMIUT InitWMI(PGLOBAL g, char *nsp, char *classname) NULL, NULL, NULL, 0, NULL, NULL, &wp->Svc); if (FAILED(res)) { - sprintf(g->Message, "Could not connect. Error code = %p", res); + sprintf(g->Message, "Could not connect. Error code = %x", res); loc->Release(); CoUninitialize(); return NULL; @@ -423,7 +424,7 @@ bool TDBWMI::Initialize(PGLOBAL g) if (FAILED(Res)) { sprintf(g->Message, "Failed to initialize COM library. " - "Error code = %p", Res); + "Error code = %x", Res); return true; // Program has failed. } // endif Res @@ -436,7 +437,7 @@ bool TDBWMI::Initialize(PGLOBAL g) if (FAILED(Res)) { sprintf(g->Message, "Failed to create Locator. " - "Error code = %p", Res); + "Error code = %x", Res); CoUninitialize(); return true; // Program has failed. } // endif Res @@ -448,7 +449,7 @@ bool TDBWMI::Initialize(PGLOBAL g) NULL, NULL,0, NULL, 0, 0, &Svc); if (FAILED(Res)) { - sprintf(g->Message, "Could not connect. Error code = %p", Res); + sprintf(g->Message, "Could not connect. Error code = %x", Res); loc->Release(); CoUninitialize(); return true; // Program has failed. @@ -463,7 +464,7 @@ bool TDBWMI::Initialize(PGLOBAL g) RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); if (FAILED(Res)) { - sprintf(g->Message, "Could not set proxy. Error code = 0x", Res); + sprintf(g->Message, "Could not set proxy. Error code = %x", Res); Svc->Release(); CoUninitialize(); return true; // Program has failed. @@ -573,7 +574,7 @@ bool TDBWMI::GetWMIInfo(PGLOBAL g) NULL, &Enumerator); if (FAILED(Rc)) { - sprintf(g->Message, "Query %s failed. Error code = %p", cmd, Rc); + sprintf(g->Message, "Query %s failed. Error code = %x", cmd, Rc); Svc->Release(); CoUninitialize(); return true; // Program has failed. diff --git a/storage/connect/tabxcl.cpp b/storage/connect/tabxcl.cpp index add61431493..93a24accc3c 100644 --- a/storage/connect/tabxcl.cpp +++ b/storage/connect/tabxcl.cpp @@ -1,7 +1,7 @@ /************* TabXcl CPP Declares Source Code File (.CPP) *************/ /* Name: TABXCL.CPP Version 1.0 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 2013 */ +/* (C) Copyright to the author Olivier BERTRAND 2013-2017 */ /* */ /* XCOL: Table having one column containing several values */ /* comma separated. When creating the table, the name of the X */ @@ -45,12 +45,12 @@ #include "plgdbsem.h" #include "plgcnx.h" // For DB types #include "resource.h" -#include "reldef.h" +#include "xtable.h" +#include "tabext.h" #include "filamtxt.h" #include "tabdos.h" #include "tabcol.h" #include "tabxcl.h" -#include "xtable.h" #include "tabmysql.h" #include "ha_connect.h" @@ -246,7 +246,7 @@ XCLCOL::XCLCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i) /* XCLCOL initialization routine. */ /* Allocate Cbuf that will contain the Colp value. */ /***********************************************************************/ -bool XCLCOL::Init(PGLOBAL g, PTDBASE tp) +bool XCLCOL::Init(PGLOBAL g, PTDB tp) { if (PRXCOL::Init(g, tp)) return true; diff --git a/storage/connect/tabxcl.h b/storage/connect/tabxcl.h index 291f0b4263a..fde000ee709 100644 --- a/storage/connect/tabxcl.h +++ b/storage/connect/tabxcl.h @@ -91,7 +91,7 @@ class XCLCOL : public PRXCOL { using PRXCOL::Init; virtual void Reset(void) {} // Evaluated only by TDBXCL virtual void ReadColumn(PGLOBAL g); - virtual bool Init(PGLOBAL g, PTDBASE tp = NULL); + virtual bool Init(PGLOBAL g, PTDB tp = NULL); protected: // Default constructor not to be used diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp index 3b8229fcf51..52cf3d3812f 100644 --- a/storage/connect/tabxml.cpp +++ b/storage/connect/tabxml.cpp @@ -42,7 +42,7 @@ /***********************************************************************/ #include "global.h" #include "plgdbsem.h" -#include "reldef.h" +//#include "reldef.h" #include "xtable.h" #include "colblk.h" #include "mycat.h" @@ -537,6 +537,11 @@ PTDB XMLDEF::GetTable(PGLOBAL g, MODE m) if (Catfunc == FNC_COL) return new(g) TDBXCT(this); + if (Zipped && !(m == MODE_READ || m == MODE_ANY)) { + strcpy(g->Message, "ZIpped XML tables are read only"); + return NULL; + } // endif Zipped + PTDBASE tdbp = new(g) TDBXML(this); if (Multiple) @@ -655,7 +660,7 @@ TDBXML::TDBXML(PTDBXML tdbp) : TDBASE(tdbp) } // end of TDBXML copy constructor // Used for update -PTDB TDBXML::CopyOne(PTABS t) +PTDB TDBXML::Clone(PTABS t) { PTDB tp; PXMLCOL cp1, cp2; @@ -669,7 +674,7 @@ PTDB TDBXML::CopyOne(PTABS t) } // endfor cp1 return tp; - } // end of CopyOne + } // end of Clone /***********************************************************************/ /* Allocate XML column description block. */ @@ -926,7 +931,7 @@ bool TDBXML::Initialize(PGLOBAL g) if (rc) sprintf(g->Message, "%s: %s", MSG(COM_ERROR), buf); else - sprintf(g->Message, "%s hr=%p", MSG(COM_ERROR), e.Error()); + sprintf(g->Message, "%s hr=%x", MSG(COM_ERROR), e.Error()); goto error; #endif // __WIN__ diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h index 6c586d79dec..65b353072cb 100644 --- a/storage/connect/tabxml.h +++ b/storage/connect/tabxml.h @@ -71,7 +71,7 @@ class DllExport TDBXML : public TDBASE { virtual PTDB Duplicate(PGLOBAL g) {return (PTDB)new(g) TDBXML(this);} // Methods - virtual PTDB CopyOne(PTABS t); + virtual PTDB Clone(PTABS t); virtual int GetRecpos(void); virtual int GetProgCur(void) {return N;} virtual PSZ GetFile(PGLOBAL g) {return Xfile;} diff --git a/storage/connect/tabzip.cpp b/storage/connect/tabzip.cpp index 11f414ee154..b91059a3843 100644 --- a/storage/connect/tabzip.cpp +++ b/storage/connect/tabzip.cpp @@ -70,8 +70,12 @@ PCOL TDBZIP::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) /* param: filename path and the filename of the zip file to open. */ /* return: true if open, false otherwise. */ /***********************************************************************/ -bool TDBZIP::open(PGLOBAL g, const char *filename) +bool TDBZIP::open(PGLOBAL g, const char *fn) { + char filename[_MAX_PATH]; + + PlugSetPath(filename, fn, GetPath()); + if (!zipfile && !(zipfile = unzOpen64(filename))) sprintf(g->Message, "Zipfile open error"); @@ -102,7 +106,7 @@ int TDBZIP::Cardinality(PGLOBAL g) unz_global_info64 ginfo; int err = unzGetGlobalInfo64(zipfile, &ginfo); - Cardinal = (err == UNZ_OK) ? ginfo.number_entry : 0; + Cardinal = (err == UNZ_OK) ? (int)ginfo.number_entry : 0; } else Cardinal = 0; @@ -221,6 +225,14 @@ void ZIPCOL::ReadColumn(PGLOBAL g) case 3: Value->SetValue((int)Tdbz->finfo.compression_method); break; + case 4: + Tdbz->finfo.tmu_date.tm_year -= 1900; + + if (((DTVAL*)Value)->MakeTime((tm*)&Tdbz->finfo.tmu_date)) + Value->SetNull(true); + + Tdbz->finfo.tmu_date.tm_year += 1900; + break; default: Value->SetValue_psz((PSZ)Tdbz->fn); } // endswitch flag diff --git a/storage/connect/tabzip.h b/storage/connect/tabzip.h index 6f1735258e7..dcec3475371 100644 --- a/storage/connect/tabzip.h +++ b/storage/connect/tabzip.h @@ -20,7 +20,7 @@ typedef class ZIPCOL *PZIPCOL; /***********************************************************************/ class DllExport ZIPDEF : public DOSDEF { /* Table description */ friend class TDBZIP; - friend class ZIPFAM; + friend class UNZFAM; public: // Constructor ZIPDEF(void) {} diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc index 34d192361a5..ca3557666a4 100644 --- a/storage/connect/user_connect.cc +++ b/storage/connect/user_connect.cc @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file user_connect.cc diff --git a/storage/connect/user_connect.h b/storage/connect/user_connect.h index 7f37973f378..a883eb85934 100644 --- a/storage/connect/user_connect.h +++ b/storage/connect/user_connect.h @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /** @file user_connect.h diff --git a/storage/connect/value.h b/storage/connect/value.h index a670ade4c28..14a568c3549 100644 --- a/storage/connect/value.h +++ b/storage/connect/value.h @@ -271,7 +271,7 @@ class DllExport TYPVAL<PSZ>: public VALUE { virtual void Reset(void) {*Strp = 0;} virtual int GetValLen(void) {return Len;}; virtual int GetValPrec() {return (Ci) ? 1 : 0;} - virtual int GetSize(void) {return (Strp) ? strlen(Strp) : 0;} + virtual int GetSize(void) {return (Strp) ? (int)strlen(Strp) : 0;} virtual PSZ GetCharValue(void) {return Strp;} virtual char GetTinyValue(void); virtual uchar GetUTinyValue(void); diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index a2cf4e77b80..15fb71ab88a 100755 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -81,7 +81,7 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add) { int rc; PTABLE tablep; - PTDBASE tdbp; + PTDB tdbp; PCATLG cat = PlgGetCatalog(g, true); /*********************************************************************/ @@ -89,12 +89,12 @@ int PlgMakeIndex(PGLOBAL g, PSZ name, PIXDEF pxdf, bool add) /*********************************************************************/ tablep = new(g) XTAB(name); - if (!(tdbp = (PTDBASE)cat->GetTable(g, tablep))) + if (!(tdbp = cat->GetTable(g, tablep))) rc = RC_NF; else if (!tdbp->GetDef()->Indexable()) { sprintf(g->Message, MSG(TABLE_NO_INDEX), name); rc = RC_NF; - } else if ((rc = tdbp->MakeIndex(g, pxdf, add)) == RC_INFO) + } else if ((rc = ((PTDBASE)tdbp)->MakeIndex(g, pxdf, add)) == RC_INFO) rc = RC_OK; // No or remote index return rc; @@ -2738,7 +2738,7 @@ bool XHUGE::Read(PGLOBAL g, void *buf, int n, int size) } // endif nbr } else { - char *buf[256]; + char buf[256]; DWORD drc = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | diff --git a/storage/connect/xindex.h b/storage/connect/xindex.h index ef2e934e5ee..2d10d72722e 100644 --- a/storage/connect/xindex.h +++ b/storage/connect/xindex.h @@ -184,7 +184,7 @@ class DllExport XXBASE : public CSORT, public BLOCK { virtual bool IsRandom(void) {return true;} virtual bool IsDynamic(void) {return Dynamic;} virtual void SetDynamic(bool dyn) {Dynamic = dyn;} - virtual bool HaveSame(void) {return false;} +//virtual bool HaveSame(void) {return false;} virtual int GetCurPos(void) {return Cur_K;} virtual void SetNval(int n) {assert(n == 1);} virtual void SetOp(OPVAL op) {Op = op;} @@ -256,7 +256,7 @@ class DllExport XINDEX : public XXBASE { // Implementation virtual IDT GetType(void) {return TYPE_IDX_INDX;} virtual bool IsMul(void) {return (Nval < Nk) ? true : Mul;} - virtual bool HaveSame(void) {return Op == OP_SAME;} +//virtual bool HaveSame(void) {return Op == OP_SAME;} virtual int GetCurPos(void) {return (Pex) ? Pex[Cur_K] : Cur_K;} virtual void SetNval(int n) {Nval = n;} int GetMaxSame(void) {return MaxSame;} diff --git a/storage/connect/xobject.h b/storage/connect/xobject.h index d78cd09f9a4..8f6c23c4aeb 100644 --- a/storage/connect/xobject.h +++ b/storage/connect/xobject.h @@ -127,7 +127,8 @@ class DllExport STRING : public BLOCK { // Implementation inline int GetLength(void) {return (int)Length;} - inline PSZ GetStr(void) {return Strp;} + inline void SetLength(uint n) {Length = n;} + inline PSZ GetStr(void) {return Strp;} inline uint32 GetSize(void) {return Size;} // Methods diff --git a/storage/connect/xtable.h b/storage/connect/xtable.h index e18a08a54b8..4aeea05946a 100644 --- a/storage/connect/xtable.h +++ b/storage/connect/xtable.h @@ -1,7 +1,7 @@ /**************** Table H Declares Source Code File (.H) ***************/ -/* Name: TABLE.H Version 2.3 */ +/* Name: TABLE.H Version 2.4 */ /* */ -/* (C) Copyright to the author Olivier BERTRAND 1999-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 1999-2017 */ /* */ /* This file contains the TBX, OPJOIN and TDB class definitions. */ /***********************************************************************/ @@ -17,6 +17,7 @@ #include "block.h" #include "colblk.h" #include "m_ctype.h" +#include "reldef.h" typedef class CMD *PCMD; typedef struct st_key_range key_range; @@ -32,24 +33,30 @@ class CMD : public BLOCK { char *Cmd; }; // end of class CMD +#if 0 // Condition filter structure class CONDFIL : public BLOCK { public: // Constructor CONDFIL(const Item *cond, uint idx, AMT type) { - Cond = cond; Idx = idx; Type = type; Body = NULL; Op = OP_XX; Cmds = NULL; + Cond = cond; Idx = idx; Type = type; Op = OP_XX; + Cmds = NULL; All = true; Body = NULL, Having = NULL; } // Members const Item *Cond; AMT Type; uint Idx; - char *Body; OPVAL Op; PCMD Cmds; + bool All; + char *Body; + char *Having; }; // end of class CONDFIL +#endif // 0 +typedef class EXTCOL *PEXTCOL; typedef class CONDFIL *PCFIL; typedef class TDBCAT *PTDBCAT; typedef class CATCOL *PCATCOL; @@ -64,47 +71,61 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block. TDB(PTDB tdbp); // Implementation - static void SetTnum(int n) {Tnum = n;} - inline PTDB GetOrig(void) {return To_Orig;} - inline TUSE GetUse(void) {return Use;} - inline PCFIL GetCondFil(void) {return To_CondFil;} - inline LPCSTR GetName(void) {return Name;} - inline PTABLE GetTable(void) {return To_Table;} - inline PCOL GetColumns(void) {return Columns;} - inline int GetDegree(void) {return Degree;} - inline MODE GetMode(void) {return Mode;} - inline PFIL GetFilter(void) {return To_Filter;} - inline void SetFilter(PFIL fp) {To_Filter = fp;} - inline void SetOrig(PTDB txp) {To_Orig = txp;} - inline void SetUse(TUSE n) {Use = n;} - inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;} - inline void SetNext(PTDB tdbp) {Next = tdbp;} - inline void SetName(LPCSTR name) {Name = name;} - inline void SetTable(PTABLE tablep) {To_Table = tablep;} - inline void SetColumns(PCOL colp) {Columns = colp;} - inline void SetDegree(int degree) {Degree = degree;} - inline void SetMode(MODE mode) {Mode = mode;} + static void SetTnum(int n) {Tnum = n;} + inline PTABDEF GetDef(void) {return To_Def;} + inline PTDB GetOrig(void) {return To_Orig;} + inline TUSE GetUse(void) {return Use;} + inline PCFIL GetCondFil(void) {return To_CondFil;} + inline LPCSTR GetName(void) {return Name;} + inline PTABLE GetTable(void) {return To_Table;} + inline PCOL GetColumns(void) {return Columns;} + inline int GetDegree(void) {return Degree;} + inline MODE GetMode(void) {return Mode;} + inline PFIL GetFilter(void) {return To_Filter;} + inline PCOL GetSetCols(void) {return To_SetCols;} + inline void SetSetCols(PCOL colp) {To_SetCols = colp;} + inline void SetFilter(PFIL fp) {To_Filter = fp;} + inline void SetOrig(PTDB txp) {To_Orig = txp;} + inline void SetUse(TUSE n) {Use = n;} + inline void SetCondFil(PCFIL cfp) {To_CondFil = cfp;} + inline void SetNext(PTDB tdbp) {Next = tdbp;} + inline void SetName(LPCSTR name) {Name = name;} + inline void SetTable(PTABLE tablep) {To_Table = tablep;} + inline void SetColumns(PCOL colp) {Columns = colp;} + inline void SetDegree(int degree) {Degree = degree;} + inline void SetMode(MODE mode) {Mode = mode;} // Properties - virtual AMT GetAmType(void) {return TYPE_AM_ERROR;} - virtual int GetTdb_No(void) {return Tdb_No;} - virtual PTDB GetNext(void) {return Next;} - virtual PCATLG GetCat(void) {return NULL;} - virtual void SetAbort(bool) {;} + virtual AMT GetAmType(void) {return TYPE_AM_ERROR;} + virtual bool IsRemote(void) {return false;} + virtual bool IsIndexed(void) {return false;} + virtual int GetTdb_No(void) {return Tdb_No;} + virtual PTDB GetNext(void) {return Next;} + virtual PCATLG GetCat(void) {return NULL;} + virtual void SetAbort(bool) {;} + virtual PKXBASE GetKindex(void) {return NULL;} // Methods virtual bool IsSame(PTDB tp) {return tp == this;} - virtual bool IsSpecial(PSZ name) = 0; - virtual bool GetBlockValues(PGLOBAL) {return false;} + virtual bool IsSpecial(PSZ name); + virtual bool IsReadOnly(void) {return Read_Only;} + virtual bool IsView(void) {return FALSE;} + virtual PSZ GetPath(void); + virtual RECFM GetFtype(void) {return RECFM_NAF;} + virtual bool GetBlockValues(PGLOBAL) { return false; } virtual int Cardinality(PGLOBAL) {return 0;} - virtual int GetMaxSize(PGLOBAL) = 0; + virtual int GetRecpos(void) = 0; + virtual bool SetRecpos(PGLOBAL g, int recpos); + virtual int GetMaxSize(PGLOBAL) = 0; virtual int GetProgMax(PGLOBAL) = 0; - virtual int GetProgCur(void) = 0; - virtual int RowNumber(PGLOBAL g, bool b = false); - virtual bool IsReadOnly(void) {return true;} - virtual const CHARSET_INFO *data_charset() {return NULL;} + virtual int GetProgCur(void) {return GetRecpos();} + virtual PSZ GetFile(PGLOBAL) {return "Not a file";} + virtual void SetFile(PGLOBAL, PSZ) {} + virtual void ResetDB(void) {} + virtual void ResetSize(void) {MaxSize = -1;} + virtual int RowNumber(PGLOBAL g, bool b = false); virtual PTDB Duplicate(PGLOBAL) {return NULL;} - virtual PTDB CopyOne(PTABS) {return this;} + virtual PTDB Clone(PTABS) {return this;} virtual PTDB Copy(PTABS t); virtual void PrintAM(FILE *f, char *m) {fprintf(f, "%s AM(%d)\n", m, GetAmType());} @@ -112,10 +133,15 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block. virtual void Print(PGLOBAL g, char *ps, uint z); virtual PSZ GetServer(void) = 0; virtual int GetBadLines(void) {return 0;} + virtual CHARSET_INFO *data_charset(void); - // Database pure virtual routines - virtual PCOL ColDB(PGLOBAL g, PSZ name, int num) = 0; - virtual void MarkDB(PGLOBAL, PTDB) = 0; + // Database routines + virtual PCOL ColDB(PGLOBAL g, PSZ name, int num); + virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int) + {assert(false); return NULL;} + virtual PCOL InsertSpecialColumn(PCOL colp); + virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp); + virtual void MarkDB(PGLOBAL g, PTDB tdb2); virtual bool OpenDB(PGLOBAL) = 0; virtual int ReadDB(PGLOBAL) = 0; virtual int WriteDB(PGLOBAL) = 0; @@ -126,20 +152,26 @@ class DllExport TDB: public BLOCK { // Table Descriptor Block. protected: // Members - PTDB To_Orig; // Pointer to original if it is a copy - TUSE Use; - PFIL To_Filter; - PCFIL To_CondFil; // To condition filter structure - static int Tnum; // Used to generate Tdb_no's - const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN - PTDB Next; // Next in linearized queries - PTABLE To_Table; // Points to the XTAB object - LPCSTR Name; // Table name - PCOL Columns; // Points to the first column of the table - MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete - int Degree; // Number of columns - int Cardinal; // Table number of rows - }; // end of class TDB + PTDB To_Orig; // Pointer to original if it is a copy + PTABDEF To_Def; // Points to catalog description block + TUSE Use; + PFIL To_Filter; + PCFIL To_CondFil; // To condition filter structure + static int Tnum; // Used to generate Tdb_no's + const int Tdb_No; // GetTdb_No() is always 0 for OPJOIN + PTDB Next; // Next in linearized queries + PTABLE To_Table; // Points to the XTAB object + LPCSTR Name; // Table name + PCOL Columns; // Points to the first column of the table + PCOL To_SetCols; // Points to updated columns + MODE Mode; // 10 Read, 30 Update, 40 Insert, 50 Delete + int Degree; // Number of columns + int Cardinal; // Table number of rows + int MaxSize; // Max size in number of lines + bool Read_Only; // True for read only tables + const CHARSET_INFO *m_data_charset; + const char *csname; // Table charset name +}; // end of class TDB /***********************************************************************/ /* This is the base class for all query tables (except decode). */ @@ -155,50 +187,50 @@ class DllExport TDBASE : public TDB { // Implementation inline int GetKnum(void) {return Knum;} - inline PTABDEF GetDef(void) {return To_Def;} - inline PKXBASE GetKindex(void) {return To_Kindex;} - inline PCOL GetSetCols(void) {return To_SetCols;} - inline void SetSetCols(PCOL colp) {To_SetCols = colp;} +//inline PTABDEF GetDef(void) {return To_Def;} +//inline PCOL GetSetCols(void) {return To_SetCols;} +//inline void SetSetCols(PCOL colp) {To_SetCols = colp;} inline void SetKey_Col(PCOL *cpp) {To_Key_Col = cpp;} inline void SetXdp(PIXDEF xdp) {To_Xdp = xdp;} inline void SetKindex(PKXBASE kxp) {To_Kindex = kxp;} // Properties - void ResetKindex(PGLOBAL g, PKXBASE kxp); + virtual PKXBASE GetKindex(void) {return To_Kindex;} + void ResetKindex(PGLOBAL g, PKXBASE kxp); PCOL Key(int i) {return (To_Key_Col) ? To_Key_Col[i] : NULL;} // Methods virtual bool IsUsingTemp(PGLOBAL) {return false;} - virtual bool IsIndexed(void) {return false;} - virtual bool IsSpecial(PSZ name); +//virtual bool IsIndexed(void) {return false;} +//virtual bool IsSpecial(PSZ name); virtual PCATLG GetCat(void); - virtual PSZ GetPath(void); +//virtual PSZ GetPath(void); virtual void PrintAM(FILE *f, char *m); - virtual RECFM GetFtype(void) {return RECFM_NAF;} +//virtual RECFM GetFtype(void) {return RECFM_NAF;} //virtual int GetAffectedRows(void) {return -1;} - virtual int GetRecpos(void) = 0; - virtual bool SetRecpos(PGLOBAL g, int recpos); - virtual bool IsReadOnly(void) {return Read_Only;} - virtual bool IsView(void) {return FALSE;} - virtual CHARSET_INFO *data_charset(void); +//virtual int GetRecpos(void) = 0; +//virtual bool SetRecpos(PGLOBAL g, int recpos); +//virtual bool IsReadOnly(void) {return Read_Only;} +//virtual bool IsView(void) {return FALSE;} +//virtual CHARSET_INFO *data_charset(void); virtual int GetProgMax(PGLOBAL g) {return GetMaxSize(g);} - virtual int GetProgCur(void) {return GetRecpos();} - virtual PSZ GetFile(PGLOBAL) {return "Not a file";} - virtual int GetRemote(void) {return 0;} - virtual void SetFile(PGLOBAL, PSZ) {} - virtual void ResetDB(void) {} - virtual void ResetSize(void) {MaxSize = -1;} +//virtual int GetProgCur(void) {return GetRecpos();} +//virtual PSZ GetFile(PGLOBAL) {return "Not a file";} +//virtual int GetRemote(void) {return 0;} +//virtual void SetFile(PGLOBAL, PSZ) {} +//virtual void ResetDB(void) {} +//virtual void ResetSize(void) {MaxSize = -1;} virtual void RestoreNrec(void) {} virtual int ResetTableOpt(PGLOBAL g, bool dop, bool dox); virtual PSZ GetServer(void) {return "Current";} // Database routines - virtual PCOL ColDB(PGLOBAL g, PSZ name, int num); - virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int) - {assert(false); return NULL;} - virtual PCOL InsertSpecialColumn(PCOL colp); - virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp); - virtual void MarkDB(PGLOBAL g, PTDB tdb2); +//virtual PCOL ColDB(PGLOBAL g, PSZ name, int num); +//virtual PCOL MakeCol(PGLOBAL, PCOLDEF, PCOL, int) +// {assert(false); return NULL;} +//virtual PCOL InsertSpecialColumn(PCOL colp); +//virtual PCOL InsertSpcBlk(PGLOBAL g, PCOLDEF cdp); +//virtual void MarkDB(PGLOBAL g, PTDB tdb2); virtual int MakeIndex(PGLOBAL g, PIXDEF, bool) {strcpy(g->Message, "Remote index"); return RC_INFO;} virtual bool ReadKey(PGLOBAL, OPVAL, const key_range *) @@ -209,19 +241,19 @@ class DllExport TDBASE : public TDB { "This function should not be called for this table"); return true;} // Members - PTABDEF To_Def; // Points to catalog description block +//PTABDEF To_Def; // Points to catalog description block PXOB *To_Link; // Points to column of previous relations PCOL *To_Key_Col; // Points to key columns in current file PKXBASE To_Kindex; // Points to table key index PIXDEF To_Xdp; // To the index definition block - PCOL To_SetCols; // Points to updated columns +//PCOL To_SetCols; // Points to updated columns RECFM Ftype; // File type: 0-var 1-fixed 2-binary (VCT) - int MaxSize; // Max size in number of lines +//int MaxSize; // Max size in number of lines int Knum; // Size of key arrays - bool Read_Only; // True for read only tables - const CHARSET_INFO *m_data_charset; - const char *csname; // Table charset name - }; // end of class TDBASE +//bool Read_Only; // True for read only tables +//const CHARSET_INFO *m_data_charset; +//const char *csname; // Table charset name +}; // end of class TDBASE /***********************************************************************/ /* The abstract base class declaration for the catalog tables. */ @@ -243,7 +275,8 @@ class DllExport TDBCAT : public TDBASE { // Database routines virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); - virtual int GetMaxSize(PGLOBAL g); + virtual int Cardinality(PGLOBAL) {return 10;} // To avoid assert + virtual int GetMaxSize(PGLOBAL g); virtual bool OpenDB(PGLOBAL g); virtual int ReadDB(PGLOBAL g); virtual int WriteDB(PGLOBAL g); @@ -275,7 +308,7 @@ class DllExport CATCOL : public COLBLK { virtual int GetAmType(void) {return TYPE_AM_ODBC;} // Methods - virtual void ReadColumn(PGLOBAL g); + virtual void ReadColumn(PGLOBAL g); protected: CATCOL(void) {} // Default constructor not to be used diff --git a/storage/connect/zip.c b/storage/connect/zip.c index ea54853e858..4bbe31ab7dd 100644 --- a/storage/connect/zip.c +++ b/storage/connect/zip.c @@ -637,7 +637,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib return relativeOffset; } -int LoadCentralDirectoryRecord(zip64_internal* pziinit) +static int LoadCentralDirectoryRecord(zip64_internal* pziinit) { int err=ZIP_OK; ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ @@ -846,7 +846,7 @@ int LoadCentralDirectoryRecord(zip64_internal* pziinit) /************************************************************/ -extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +static zipFile zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { zip64_internal ziinit; zip64_internal* zi; @@ -955,7 +955,7 @@ extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) return zipOpen3(pathname,append,NULL,NULL); } -int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +static int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) { /* write the local header */ int err; @@ -1752,7 +1752,7 @@ extern int ZEXPORT zipCloseFileInZip (zipFile file) return zipCloseFileInZipRaw (file,0,0); } -int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +static int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) { int err = ZIP_OK; ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; @@ -1774,7 +1774,7 @@ int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eo return err; } -int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +static int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; @@ -1813,7 +1813,7 @@ int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centra } return err; } -int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +static int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { int err = ZIP_OK; @@ -1861,7 +1861,7 @@ int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, return err; } -int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +static int Write_GlobalComment(zip64_internal* zi, const char* global_comment) { int err = ZIP_OK; uInt size_global_comment = 0; |