00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <malloc.h>
00018
00019
00020 #include <lStr.h>
00021 #include <lExceptions.h>
00022
00023
00024 #include <cProtoBase.h>
00025
00026
00027 #include <cObject.h>
00028 #include <cPersistentObject.h>
00029 #include <cRefBase.h>
00030 #include <cResultBase.h>
00031 #include <cCursor.h>
00032 #include <cClassRegister.h>
00033 #include <cComplexQuery.h>
00034
00035 ProtoBase *ProtoBase::_root = NULL;
00036 ProtoBase *ProtoBase::_first = NULL;
00037
00038 typedef unsigned char Object::*MemberPtr;
00039
00040 typedef struct {
00041 bool key;
00042 bool rw;
00043 MemberPtr member;
00044 char *atrname;
00045 char *colname;
00046 char *varname;
00047 void* bufaddr;
00048 char buftype;
00049 int buflen;
00050 short indic;
00051 } sqlVar;
00052
00053 void ProtoBase::Register(ProtoBase *_p, const char *_n)
00054 {
00055
00056
00057 ProtoBase **t = &_root;
00058 int c;
00059 while (*t) {
00060 c = StrCmp((*t)->ClassName(),_n);
00061 if (c > 0)
00062 t = &((*t)->_left);
00063 else if (c < 0)
00064 t = &((*t)->_right);
00065 else
00066 break;
00067 };
00068 if (!(*t))
00069 *t = _p;
00070
00071 _p->_next = _first;
00072 _first = _p;
00073 };
00074
00075 bool ProtoBase::_ExportAttributes(const class Object &o)
00076 {
00077 _Initialise();
00078 void *source;
00079 char **addrptr;
00080 for(int i=0;i<_fullParentPrototypeCount;i++)
00081 {
00082 int j=0;
00083 if (i>0)
00084 j=_fullParentPrototype[i]->_sqlVars.KeyCount;
00085 for( ; j<_fullParentPrototype[i]->_sqlVars.Count; j++)
00086 {
00087 sqlVar &var = ((sqlVar*)(_fullParentPrototype[i]->_sqlVars.Arr))[j];
00088 source = (void *)&(o.*var.member);
00089
00090 var.indic=0;
00091 switch (var.buftype)
00092 {
00093 case TYPE_PTR:
00094 *(long int *)(var.bufaddr)=*(long int *)source;
00095 if ((*(long int *)(var.bufaddr))>0)
00096 var.indic=0;
00097 else
00098 var.indic=-1;
00099 break;
00100 case TYPE_INT:
00101 if (var.buflen == sizeof(long int))
00102 *(long int *)(var.bufaddr)=*(long int *)source;
00103 else if (var.buflen == sizeof(int))
00104 *(int *)(var.bufaddr)=*(int *)source;
00105 else if (var.buflen == sizeof(short int))
00106 *(short int *)(var.bufaddr)=*(short int *)source;
00107 else if (var.buflen == sizeof(signed char))
00108 *(signed char *)(var.bufaddr)=*(signed char *)source;
00109 break;
00110 case TYPE_UNSIGNED:
00111 if (var.buflen == sizeof(unsigned long int))
00112 *(unsigned long int *)(var.bufaddr)=*(unsigned long int *)source;
00113 else if (var.buflen == sizeof(unsigned int))
00114 *(unsigned int *)(var.bufaddr)=*(unsigned int *)source;
00115 else if (var.buflen == sizeof(unsigned short int))
00116 *(unsigned short int *)(var.bufaddr)=*(unsigned short int *)source;
00117 else if (var.buflen == sizeof(unsigned char))
00118 *(unsigned char *)(var.bufaddr)=*(unsigned char *)source;
00119 break;
00120 case TYPE_FLOAT:
00121 if (var.buflen == sizeof(double))
00122 *(double *)(var.bufaddr)=*(double *)source;
00123 else if (var.buflen == sizeof(float))
00124 *(double *)(var.bufaddr)=*(double *)source;
00125 break;
00126 case TYPE_CHAR:
00127 *(char *)(var.bufaddr)=*(char *)source;
00128 break;
00129 case TYPE_STRING:
00130 addrptr = (char **)&(var.bufaddr);
00131
00132
00133 if (*(const char **)source)
00134
00135 StrExp(*addrptr,*(const char **)source,var.buflen);
00136 else
00137 *addrptr[0] = '\0';
00138 break;
00139 };
00140 };
00141 for(j=_fullParentPrototype[i]->_sqlVars.Count ; j<_fullParentPrototype[i]->_sqlVars.SpecCount; j++)
00142 {
00143
00144
00145
00146 sqlVar &var = ((sqlVar*)(_fullParentPrototype[i]->_sqlVars.Arr))[j];
00147 addrptr = (char **)&(var.bufaddr);
00148
00149
00150 StrExp(*addrptr,_fullParentPrototype[_fullParentPrototypeCount-1]->ClassName(),var.buflen);
00151 var.indic=0;
00152 };
00153 };
00154 return true;
00155 };
00156
00157 bool ProtoBase::_ExportKeyAttributes(const class Object &o)
00158 {
00159 _Initialise();
00160 void *source;
00161 char **addrptr;
00162 for(int j=0 ; j<_rootPrototype->_sqlVars.KeyCount; j++)
00163 {
00164 sqlVar &var = ((sqlVar*)(_rootPrototype->_sqlVars.Arr))[j];
00165 source = (void *)&(o.*var.member);
00166
00167 var.indic=0;
00168 switch (var.buftype)
00169 {
00170 case TYPE_INT:
00171 if (var.buflen == sizeof(long int))
00172 *(long int *)(var.bufaddr)=*(long int *)source;
00173 else if (var.buflen == sizeof(int))
00174 *(int *)(var.bufaddr)=*(int *)source;
00175 else if (var.buflen == sizeof(short int))
00176 *(short int *)(var.bufaddr)=*(short int *)source;
00177 else if (var.buflen == sizeof(signed char))
00178 *(signed char *)(var.bufaddr)=*(signed char *)source;
00179 break;
00180 case TYPE_UNSIGNED:
00181 if (var.buflen == sizeof(unsigned long int))
00182 *(unsigned long int *)(var.bufaddr)=*(unsigned long int *)source;
00183 else if (var.buflen == sizeof(unsigned int))
00184 *(unsigned int *)(var.bufaddr)=*(unsigned int *)source;
00185 else if (var.buflen == sizeof(unsigned short int))
00186 *(unsigned short int *)(var.bufaddr)=*(unsigned short int *)source;
00187 else if (var.buflen == sizeof(unsigned char))
00188 *(unsigned char *)(var.bufaddr)=*(unsigned char *)source;
00189 break;
00190 case TYPE_FLOAT:
00191 if (var.buflen == sizeof(double))
00192 *(double *)(var.bufaddr)=*(double *)source;
00193 else if (var.buflen == sizeof(float))
00194 *(double *)(var.bufaddr)=*(double *)source;
00195 break;
00196 case TYPE_CHAR:
00197 *(char *)(var.bufaddr)=*(char *)source;
00198 break;
00199 case TYPE_STRING:
00200 addrptr = (char **)&(var.bufaddr);
00201
00202
00203 if (*(const char **)source)
00204
00205 StrExp(*addrptr,*(const char **)source,var.buflen);
00206 else
00207 *addrptr[0] = '\0';
00208 break;
00209 };
00210 };
00211 return true;
00212 };
00213
00214 bool ProtoBase::_ExportKeyAttributes(const class RefBase &x)
00215 {
00216 _Initialise();
00217
00218
00219 char * keyvals = StrCpy(x._ObjectIdentification._SelectKeyValues);
00220 char * keyval1 = NULL;
00221 char * decoded = NULL;
00222 int v = 0;
00223 while(StrSplit(keyvals,',',keyval1))
00224 {
00225
00226 StrDecode(decoded,keyval1);
00227 sqlVar &var = ((sqlVar*)(_rootPrototype->_sqlVars.Arr))[v];
00228 var.indic=0;
00229 switch (var.buftype)
00230 {
00231 case TYPE_STRING:
00232 StrExp((char *)var.bufaddr,decoded,var.buflen);
00233 break;
00234 case TYPE_CHAR:
00235 if (decoded)
00236 ((char *)var.bufaddr)[1] = *decoded;
00237 break;
00238 case TYPE_FLOAT:
00239 if (var.buflen == sizeof(double))
00240 sscanf(decoded,"%lf",(double *)var.bufaddr);
00241 else if (var.buflen == sizeof(float))
00242 sscanf(decoded,"%f",(float *)var.bufaddr);
00243 break;
00244 case TYPE_INT:
00245 if (var.buflen == sizeof(long))
00246 sscanf(decoded,"%ld",(long *)var.bufaddr);
00247 else if (var.buflen == sizeof(int))
00248 sscanf(decoded,"%d",(int *)var.bufaddr);
00249 else if (var.buflen == sizeof(short))
00250 sscanf(decoded,"%hd",(short *)var.bufaddr);
00251 break;
00252 case TYPE_UNSIGNED:
00253 if (var.buflen == sizeof(unsigned long))
00254 sscanf(decoded,"%lu",(unsigned long *)var.bufaddr);
00255 else if (var.buflen == sizeof(unsigned int))
00256 sscanf(decoded,"%u",(unsigned int *)var.bufaddr);
00257 else if (var.buflen == sizeof(unsigned short))
00258 sscanf(decoded,"%hu",(unsigned short *)var.bufaddr);
00259 break;
00260 };
00261 v++;
00262 };
00263 StrFree(keyvals);
00264 StrFree(keyval1);
00265 StrFree(decoded);
00266 return true;
00267 };
00268
00269 bool ProtoBase::_ImportAttributes(class Object &o)
00270 {
00271 _Initialise();
00272 void *source;
00273 for(int i=0;i<_fullParentPrototypeCount;i++)
00274 {
00275 int j=0;
00276 if (i>0)
00277 j=_fullParentPrototype[i]->_sqlVars.KeyCount;
00278 for( ; j<_fullParentPrototype[i]->_sqlVars.Count; j++)
00279 {
00280 sqlVar &var = ((sqlVar*)(_fullParentPrototype[i]->_sqlVars.Arr))[j];
00281 source = &(o.*var.member);
00282 switch (var.buftype)
00283 {
00284 case TYPE_PTR:
00285 if (var.indic<0)
00286 *(long int *)source=0;
00287 else
00288 *(long int *)source=*(long int *)(var.bufaddr);
00289 break;
00290 case TYPE_INT:
00291 if (var.buflen == sizeof(long int))
00292 *(long int *)source=*(long int *)(var.bufaddr);
00293 else if (var.buflen == sizeof(int))
00294 *(int *)source=*(int *)(var.bufaddr);
00295 else if (var.buflen == sizeof(short int))
00296 *(short int *)source=*(short int *)(var.bufaddr);
00297 else if (var.buflen == sizeof(signed char))
00298 *(signed char *)source=*(signed char *)(var.bufaddr);
00299 break;
00300 case TYPE_UNSIGNED:
00301 if (var.buflen == sizeof(unsigned long int))
00302 *(unsigned long int *)source=*(unsigned long int *)(var.bufaddr);
00303 else if (var.buflen == sizeof(unsigned int))
00304 *(unsigned int *)source=*(unsigned int *)(var.bufaddr);
00305 else if (var.buflen == sizeof(unsigned short int))
00306 *(unsigned short int *)source=*(unsigned short int *)(var.bufaddr);
00307 else if (var.buflen == sizeof(unsigned char))
00308 *(unsigned char *)source=*(unsigned char *)(var.bufaddr);
00309 break;
00310 case TYPE_FLOAT:
00311 if (var.buflen == sizeof(double))
00312 *(double *)source=*(double *)(var.bufaddr);
00313 else if (var.buflen == sizeof(float))
00314 *(float *)source=*(float *)(var.bufaddr);
00315 break;
00316 case TYPE_CHAR:
00317 *(char *)source=*(char *)(var.bufaddr);
00318 break;
00319 case TYPE_STRING:
00320 StrCpy(*(char **)source,(char *)(var.bufaddr));
00321 break;
00322 };
00323 };
00324 };
00325 return true;
00326 };
00327
00328 bool ProtoBase::_KeyValues(char *&s)
00329
00330 {
00331 _Initialise();
00332 char * decoded = NULL;
00333 char * encoded = NULL;
00334 const char * delim = NULL;
00335 StrFree(s);
00336 for(int j=0 ; j<_rootPrototype->_sqlVars.KeyCount; j++)
00337 {
00338 StrFree(decoded);
00339 sqlVar &var = ((sqlVar*)(_rootPrototype->_sqlVars.Arr))[j];
00340 switch (var.buftype)
00341 {
00342 case TYPE_INT:
00343 if (var.buflen == sizeof(long int))
00344 decoded = LongToStr(*(long int *)(var.bufaddr));
00345 else if (var.buflen == sizeof(int))
00346 decoded = LongToStr(*(int *)(var.bufaddr));
00347 else if (var.buflen == sizeof(short int))
00348 decoded = LongToStr(*(short int *)(var.bufaddr));
00349 break;
00350 case TYPE_UNSIGNED:
00351 if (var.buflen == sizeof(long int))
00352 decoded = ULongToStr(*(unsigned long int *)(var.bufaddr));
00353 else if (var.buflen == sizeof(int))
00354 decoded = ULongToStr(*(unsigned int *)(var.bufaddr));
00355 else if (var.buflen == sizeof(short int))
00356 decoded = ULongToStr(*(unsigned short int *)(var.bufaddr));
00357 break;
00358 case TYPE_FLOAT:
00359 if (var.buflen == sizeof(double))
00360 decoded = FloatToStr(*(float *)(var.bufaddr));
00361 else if (var.buflen == sizeof(float))
00362 decoded = FloatToStr(*(double *)(var.bufaddr));
00363 break;
00364 case TYPE_CHAR:
00365 decoded=(char *)malloc(2);
00366 *decoded=*(char *)(var.bufaddr);
00367 *(decoded+1)='\'';
00368 break;
00369 case TYPE_STRING:
00370 decoded = StrCpy((char *)var.bufaddr);
00371 break;
00372 };
00373 StrEncode(encoded,decoded);
00374 StrCat(s,2,
00375 delim,
00376 encoded
00377 );
00378 delim=",";
00379 };
00380 StrFree(encoded);
00381 StrFree(decoded);
00382 return true;
00383 };
00384
00385 char * ProtoBase::_KeyValues(const class Object &o)
00386 {
00387 _ExportKeyAttributes(o);
00388 char *keyvals = NULL;
00389 _KeyValues(keyvals);
00390 return keyvals;
00391 };
00392
00393 bool ProtoBase::_ImportKeyAttributes(class RefBase &x)
00394 {
00395 _Initialise();
00396 return _KeyValues(x._ObjectIdentification._SelectKeyValues);
00397 };
00398
00399 void ProtoBase::_ResetProcessed(ProtoBase * const _p)
00400 {
00401 if (_p)
00402 {
00403 _p->_processed=false;
00404 _ResetProcessed(_p->_left);
00405 _ResetProcessed(_p->_right);
00406 };
00407 };
00408
00410
00411
00412 class ResultBase *ProtoBase::ExecuteQuery(
00413 const QueRefProto &Q,
00414 class Connection *DbCon,
00415 const int i,
00416 class ResultBase * QR
00417 )
00418 {
00419 #ifdef C_OBJECT_TRACE
00420 logmsg("ResultBase *ProtoBase::ExecuteQuery(...) invoked");
00421 #endif
00422
00423 QR->_Strategies = DbCon->_Strategies;
00424 QR->_query = new ComplexQuery(Q);
00425
00426 QR->_queryPrototype = this;
00427 _TranslateToSql(*(QR->_query));
00428
00429 QR->_sql_select = _StmtSelectPtr(*(QR->_query),i);
00430 QR->_queryConnection = DbCon;
00431 QR->_cursor = DbCon->_GetNewCursor();
00432
00433 QR->_SetSqlCommand(NULL);
00434
00435
00436 QR->Open();
00437
00438 #ifdef C_OBJECT_TRACE
00439 logmsg("ResultBase *Object::ExecuteQuery(QueRefProto *Q, Connection *DbCon, const int i, const int j)finished");
00440 #endif
00441
00442 return(QR);
00443 };
00444
00445 void ProtoBase::_Initialise()
00446 {
00447
00448 if (_initialised)
00449 return;
00450 _initialised=true;
00451 if (!StrCmp(BaseClassName(),"Object"))
00452 _isObject=true;
00453 else if (!StrCmp(BaseClassName(),"ImmutableObject"))
00454 _isImmutableObject=true;
00455 else if (!StrCmp(BaseClassName(),"DatabaseObject"))
00456 _isDatabaseObject=true;
00457 else if (!StrCmp(BaseClassName(),"PersistentObject"))
00458 _isPersistentObject=true;
00459 if (!StrCmp(ClassName(),"Object"))
00460 _isRootClass=true;
00461 else if (!StrCmp(ClassName(),"ImmutableObject"))
00462 _isRootClass=true;
00463 else if (!StrCmp(ClassName(),"DatabaseObject"))
00464 _isRootClass=true;
00465 else if (!StrCmp(ClassName(),"PersistentObject"))
00466 _isRootClass=true;
00467
00468
00469 _InitialiseParentPrototype();
00470
00471 _ResetProcessed(_root);
00472
00473 _InitialiseFullParentPrototype(this);
00474
00475 for (int i=0; i<_parentPrototypeCount; i++)
00476 _parentPrototype[i]->_Initialise();
00477
00478 _InitialiseSqlVar();
00479
00480
00481
00482 _InitialiseSelect();
00483 _InitialiseFullSelect();
00484 _InitialiseKeySelect();
00485 _InitialiseInto();
00486
00487
00488 _InitialiseFullFrom();
00489 _InitialiseWhere();
00490 _InitialiseFullWhere();
00491 _InitialiseKeyWhere();
00492 _InitialiseGroupBy();
00493 _InitialiseHaving();
00494 _InitialiseStmtSelect();
00495 _InitialiseStmtInsert();
00496 _InitialiseStmtDelete();
00497 _InitialiseStmtUpdate();
00498 };
00499
00500 void ProtoBase::_InitialiseParentPrototype()
00501 {
00502 char *_parents = NULL;
00503 char *_1parent = NULL;
00504 StrCpy(_parents,ParentClassNames());
00505 while(StrSplit(_parents,',',_1parent))
00506 {
00507 _parentPrototypeCount++;
00508 _parentPrototype=(class ProtoBase **)realloc(
00509 _parentPrototype,_parentPrototypeCount*sizeof(class ProtoBase *)
00510 );
00511 if (_parentPrototype)
00512 _parentPrototype[_parentPrototypeCount-1]=Find(_1parent);
00513 };
00514 StrFree(_parents);
00515 StrFree(_1parent);
00516 };
00517
00518 void ProtoBase::_InitialiseFullParentPrototype(class ProtoBase *_p)
00519 {
00520 if (_processed)
00521 return;
00522 char *_parents = NULL;
00523 char *_1parent = NULL;
00524 class ProtoBase *_x;
00525 StrCpy(_parents,ParentClassNames());
00526 while(StrSplit(_parents,',',_1parent))
00527 {
00528 _x = Find(_1parent);
00529 if (_x)
00530 _x->_InitialiseFullParentPrototype(_p);
00531 };
00532 StrFree(_parents);
00533 StrFree(_1parent);
00534 _p->_fullParentPrototypeCount++;
00535 _p->_fullParentPrototype=(class ProtoBase **)realloc(
00536 _p->_fullParentPrototype,_p->_fullParentPrototypeCount*sizeof(class ProtoBase *)
00537 );
00538 if (_p->_fullParentPrototype)
00539 _p->_fullParentPrototype[_p->_fullParentPrototypeCount-1]=this;
00540 _processed=true;
00541 };
00542
00543 void ProtoBase::_InitialiseSqlVar()
00544 {
00545 _sqlVars.KeyCount = 0;
00546 _sqlVars.Count = 0;
00547 _sqlVars.SpecCount = 0;
00548 int i = 0;
00549 int v = 0;
00550 int b;
00551 const char *atr;
00552 MemberPtr mem;
00553 const char *col;
00554 char *trimcol = NULL;
00555 char ctype;
00556 unsigned int clen;
00557 bool crw;
00558 char *thistable = NULL;
00559 StrCat(thistable,2,From(),".");
00560 _MapKey(i,atr,mem,col,ctype,clen,crw);
00561 while (ctype!=TYPE_UNKNOWN)
00562 {
00563 _sqlVars.KeyCount++;
00564 _sqlVars.Count++;
00565 _sqlVars.SpecCount++;
00566 _sqlVars.Arr=realloc(_sqlVars.Arr,_sqlVars.Count*sizeof(sqlVar));
00567 sqlVar &var=((sqlVar *)_sqlVars.Arr)[v];
00568
00569
00570 StrCpy(trimcol,col);
00571 StrPrefixCut(trimcol,'.');
00572 var.key = true;
00573 var.rw = crw;
00574 var.member = mem;
00575 var.indic = 0;
00576 StrCpy(var.atrname = NULL, atr);
00577
00578 StrCpy(var.colname = NULL, From());
00579 StrCat(var.colname,2,".",trimcol);
00580 StrFree(trimcol);
00581 var.varname = NULL;
00582 StrCat(
00583 var.varname,4,
00584 ":",
00585 From(),
00586 "_",
00587 atr
00588 );
00589 var.buftype = ctype;
00590 var.buflen=clen;
00591 switch (ctype)
00592 {
00593 case TYPE_INT:
00594 case TYPE_UNSIGNED:
00595 case TYPE_FLOAT:
00596 case TYPE_CHAR:
00597 case TYPE_PTR:
00598 var.bufaddr=malloc(var.buflen);
00599 for(b=0; (var.bufaddr && (b<var.buflen)); *(((unsigned char *)var.bufaddr)+b)='\0', b++);
00600 break;
00601 case TYPE_STRING:
00602 var.bufaddr=new char[var.buflen+1];
00603 *((unsigned char *)var.bufaddr)='\0';
00604 break;
00605 };
00606 v++;
00607 i++;
00608 _MapKey(i,atr,mem,col,ctype,clen,crw);
00609 };
00610 i = 0;
00611 _Map(i,atr,mem,col,ctype,clen,crw);
00612 while (ctype!=TYPE_UNKNOWN)
00613 {
00614 _sqlVars.Count++;
00615 _sqlVars.SpecCount++;
00616 _sqlVars.Arr = realloc(_sqlVars.Arr,_sqlVars.Count*sizeof(sqlVar));
00617 sqlVar &var=((sqlVar *)_sqlVars.Arr)[v];
00618 var.key = false;
00619 var.rw = crw;
00620 var.member = mem;
00621 var.indic = 0;
00622 StrCpy(var.atrname = NULL, atr);
00623 StrCpy(var.colname = NULL, col);
00624
00625
00626 StrReplaceAll(var.colname,THIS_TABLE ".",thistable);
00627 var.varname = NULL;
00628 StrCat(
00629 var.varname,4,
00630 ":",
00631 From(),
00632 "_",
00633 atr
00634 );
00635 var.buftype = ctype;
00636 var.buflen=clen;
00637 switch (ctype)
00638 {
00639 case TYPE_INT:
00640 case TYPE_UNSIGNED:
00641 case TYPE_FLOAT:
00642 case TYPE_CHAR:
00643 case TYPE_PTR:
00644 var.bufaddr=malloc(var.buflen);
00645 for(b=0; (var.bufaddr && (b<var.buflen)); *(((unsigned char *)var.bufaddr)+b)='\0', b++);
00646 break;
00647 case TYPE_STRING:
00648 var.bufaddr=new char[var.buflen+1];
00649 *((unsigned char *)var.bufaddr)='\0';
00650 break;
00651 };
00652 v++;
00653 i++;
00654 _Map(i,atr,mem,col,ctype,clen,crw);
00655 };
00656
00657
00658 if (_isPersistentObject && _isRootClass)
00659 {
00660 _sqlVars.SpecCount++;
00661 _sqlVars.Arr=realloc(_sqlVars.Arr,_sqlVars.SpecCount*sizeof(sqlVar));
00662 sqlVar &var=((sqlVar *)_sqlVars.Arr)[v];
00663 var.key = false;
00664 var.rw = true;
00665 var.member = NULL;
00666 StrCpy(var.atrname = NULL, "ClassName");
00667 StrCpy(var.colname = NULL, From());
00668 StrCat(var.colname,".CLASS_NAME");
00669 StrFree(trimcol);
00670 var.varname = NULL;
00671 StrCat(
00672 var.varname,3,
00673 ":",
00674 From(),
00675 "_ClassName"
00676 );
00677 var.buftype = TYPE_STRING;
00678 var.buflen=MAX_CLASS_NAME_LEN;
00679 var.bufaddr=malloc(MAX_CLASS_NAME_LEN+1);
00680 };
00681
00682 StrFree(thistable);
00683 };
00684
00685 void ProtoBase::_InitialiseSelect()
00686 {
00687 const char *_delim = NULL;
00688 int v;
00689 for (v=0; v < _sqlVars.Count; v++)
00690 {
00691 (void)StrCat(_select,2,_delim,((sqlVar*)_sqlVars.Arr)[v].colname);
00692 _delim=", ";
00693 };
00694 };
00695
00696 void ProtoBase::_InitialiseFullSelect()
00697 {
00698 const char *_delim = NULL;
00699 class ProtoBase **_p = _fullParentPrototype;
00700 for(int i=0; i<_fullParentPrototypeCount; i++, _p++)
00701
00702 for(int v=(*_p)->_sqlVars.KeyCount; v<(*_p)->_sqlVars.Count; v++)
00703 {
00704 (void)StrCat(_fullSelect,2,_delim,((sqlVar*)((*_p)->_sqlVars.Arr))[v].colname);
00705 _delim=", ";
00706 };
00707 };
00708
00709 void ProtoBase::_InitialiseKeySelect()
00710 {
00711 const char *_delim = NULL;
00712 for (int v=0; v < _rootPrototype->_sqlVars.KeyCount; v++)
00713 {
00714 (void)StrCat(_keySelect,2,_delim,((sqlVar*)_rootPrototype->_sqlVars.Arr)[v].colname);
00715 _delim=", ";
00716 };
00717 };
00718
00719 void ProtoBase::_InitialisePtrSelect()
00720 {
00721 const char *_delim = NULL;
00722 int v;
00723 for (v=0; v < _rootPrototype->_sqlVars.KeyCount; v++)
00724 {
00725 (void)StrCat(_keySelect,2,_delim,((sqlVar*)_rootPrototype->_sqlVars.Arr)[v].colname);
00726 _delim=", ";
00727 };
00728 for (v=_rootPrototype->_sqlVars.Count; v < _rootPrototype->_sqlVars.SpecCount; v++)
00729 {
00730 (void)StrCat(_keySelect,2,_delim,((sqlVar*)_rootPrototype->_sqlVars.Arr)[v].colname);
00731 _delim=", ";
00732 };
00733 };
00734
00735 void ProtoBase::_InitialiseInto()
00736 {
00737 const char *_delim = NULL;
00738 int v;
00739 for (v=0; v < _sqlVars.Count; v++)
00740 {
00741 (void)StrCat(_into,2,_delim,((sqlVar*)_sqlVars.Arr)[v].varname);
00742 _delim=", ";
00743 };
00744 };
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 void ProtoBase::_InitialiseFullFrom()
00774 {
00775 char *_delim = NULL;
00776 for(int i=0;i<_fullParentPrototypeCount;i++)
00777 {
00778 (void)StrCat(_fullFrom,2,_delim,_fullParentPrototype[i]->From());
00779 (void)StrCpy(_delim,", ");
00780 };
00781 StrFree(_delim);
00782 };
00783
00784 void ProtoBase::_InitialiseWhere()
00785 {
00786 if (_isPersistentObject)
00787
00788 return;
00789 char *thistable = NULL;
00790 StrCat(thistable,2,From(),".");
00791
00792
00793 StrCpy(_where,_ProtoTWhere());
00794 StrReplaceAll(_where,THIS_TABLE ".", thistable);
00795 StrFree(thistable);
00796 };
00797
00798 void ProtoBase::_InitialiseFullWhere()
00799 {
00800 const char *_delim = NULL;
00801 class ProtoBase **_x = _fullParentPrototype;
00802 class ProtoBase **_p = _fullParentPrototype;
00803 for(int i=0; i<_fullParentPrototypeCount; i++, _p++)
00804 {
00805 for(int v=0; (i>0) && (v<_sqlVars.KeyCount) && (v<(*_p)->_sqlVars.KeyCount); v++)
00806 {
00807 (void)StrCat(_fullWhere,6,
00808 _delim,
00809 "(",
00810 ((sqlVar*)((*_x)->_sqlVars.Arr))[v].colname,
00811 "=",
00812 ((sqlVar*)((*_p)->_sqlVars.Arr))[v].colname,
00813 ")"
00814 );
00815 _delim = " AND ";
00816 };
00817 if ((*_p)->Where() && StrCmp((*_p)->Where(),""))
00818 {
00819 (void)StrCat(_fullWhere,4,_delim,"(",(*_p)->Where(),")");
00820 _delim = " AND ";
00821 };
00822 };
00823 };
00824
00825 void ProtoBase::_InitialiseKeyWhere()
00826 {
00827 const char *_delim = NULL;
00828 for (int v=0; v < _sqlVars.KeyCount; v++)
00829 {
00830 (void)StrCat(_keyWhere,4,
00831 _delim,
00832 ((sqlVar*)_sqlVars.Arr)[v].colname,
00833 " = ",
00834 ((sqlVar*)_sqlVars.Arr)[v].varname
00835 );
00836 _delim=" AND ";
00837 };
00838 };
00839
00840 void ProtoBase::_InitialiseGroupBy()
00841 {
00842 if (_isDatabaseObject || _isPersistentObject)
00843
00844 return;
00845 char *thistable = NULL;
00846 StrCat(thistable,2,From(),".");
00847
00848
00849 StrCpy(_groupBy,_ProtoTGroupBy());
00850 StrReplaceAll(_groupBy,THIS_TABLE ".", thistable);
00851 StrFree(thistable);
00852 };
00853
00854 void ProtoBase::_InitialiseHaving()
00855 {
00856 if (_isDatabaseObject || _isPersistentObject)
00857
00858 return;
00859 char *thistable = NULL;
00860 StrCat(thistable,2,From(),".");
00861
00862
00863 StrCpy(_having,_ProtoTHaving());
00864 StrReplaceAll(_having,THIS_TABLE ".", thistable);
00865 StrFree(thistable);
00866 };
00867
00868 void ProtoBase::_InitialiseStmtSelect()
00869 {
00870 if (_isObject)
00871
00872 return;
00873 char * where = NULL;
00874 StrCpy(where,_rootPrototype->_keyWhere);
00875 StrAnd(where,_fullWhere);
00876 StrClause(where,"WHERE");
00877 char * groupBy = NULL;
00878 StrCpy(groupBy,_groupBy);
00879 StrClause(groupBy,"GROUP BY");
00880 char * having = NULL;
00881 StrCpy(having,_having);
00882 StrClause(having,"HAVING");
00883 StrCat(_stmtSelect,9,
00884 "SELECT ", _fullSelect,
00885
00886 " FROM ", _fullFrom,
00887 " ", where,
00888 " ", groupBy,
00889 " ", having
00890 );
00891 StrFree(where);
00892 StrFree(groupBy);
00893 StrFree(having);
00894 };
00895
00896 void ProtoBase::_InitialiseStmtInsert()
00897 {
00898 if (_isObject || _isImmutableObject)
00899
00900 return;
00901 char * inscols = NULL;
00902 char * insvars = NULL;
00903 const char * delim = NULL;
00904 for (int v=0; v < _sqlVars.SpecCount; v++)
00905 {
00906 sqlVar &var = ((sqlVar *)_sqlVars.Arr)[v];
00907 if (var.rw)
00908 {
00909 char * colwithoutprefix = StrCpy(var.colname);
00910 StrPrefixCut(colwithoutprefix,'.');
00911 StrCat(inscols,2,
00912 delim, colwithoutprefix
00913 );
00914 StrCat(insvars,2,
00915 delim, var.varname
00916 );
00917 delim=", ";
00918 StrFree(colwithoutprefix);
00919 };
00920 };
00921 StrCat(_stmtInsert,7,
00922 "INSERT INTO ", From(), " (", inscols,
00923 ") VALUES (", insvars, ")"
00924 );
00925 StrFree(inscols);
00926 StrFree(insvars);
00927 };
00928
00929 void ProtoBase::_InitialiseStmtUpdate()
00930 {
00931 if (_isObject || _isImmutableObject)
00932
00933 return;
00934 StrCat(_stmtUpdate,3,
00935 "UPDATE ", From(), " SET "
00936 );
00937 const char *delim = NULL;
00938 for (int v=_sqlVars.KeyCount; v < _sqlVars.Count; v++)
00939 {
00940 sqlVar &var = ((sqlVar *)_sqlVars.Arr)[v];
00941 if (var.rw)
00942 {
00943 StrCat(_stmtUpdate,4,
00944 delim, var.colname, " = ", var.varname
00945 );
00946 delim=", ";
00947 };
00948 };
00949 char * where = NULL;
00950 StrCpy(where,_keyWhere);
00951 StrAnd(where,_where);
00952 StrClause(where," WHERE");
00953 StrCat(_stmtUpdate,where);
00954 StrFree(where);
00955 };
00956
00957 void ProtoBase::_InitialiseStmtDelete()
00958 {
00959 StrCat(_stmtDelete,4,
00960 "DELETE FROM ", From(),
00961 " WHERE ", _keyWhere
00962 );
00963 };
00964
00965 char *ProtoBase::_StmtSelectPtr(
00966
00967
00968
00969
00970
00971
00972
00973
00974 const QueRefProto &Q,
00975 const int i
00976 )
00977 {
00978 _Initialise();
00979
00980 char * NWhere = Q._Where();
00981 char * NOrderBy = Q._OrderBy();
00982 char * NSelect = Q._Select();
00983 char * NFrom = Q._From();
00984
00985 _RealiasT(NWhere,i);
00986 _RealiasT(NOrderBy,i);
00987
00988
00989 char *res = _StmtSelectPtr(
00990 NWhere,
00991 NOrderBy,
00992 NSelect,
00993 NFrom,
00994 i
00995 );
00996 StrFree(NWhere);
00997 StrFree(NOrderBy);
00998 StrFree(NSelect);
00999 StrFree(NFrom);
01000 return res;
01001 };
01002
01003 char *ProtoBase::_StmtSelectPtr(
01004
01005
01006
01007
01008
01009
01010
01011
01012 const char *const _where_clause,
01013 const char *const _order_by_clause,
01014 const char *const _select_clause,
01015 const char *const _from_clause,
01016 const int i
01017 )
01018 {
01019 _Initialise();
01020 char * qselect = NULL;
01021 char * qfrom = NULL;
01022 char * qwhere = NULL;
01023 const char * qsdelim = "";
01024 const char * qfdelim = "";
01025 const char * qwdelim = "";
01026 char * rootalias = AliasT(i,0);
01027 char * alias = NULL;
01028 for (int p=0; p<_fullParentPrototypeCount; p++)
01029 {
01030
01031
01032
01033
01034
01035 alias = AliasT(i,p);
01036 if (p==0)
01037 {
01038 char * trimcol = NULL;
01039 int v;
01040 if (_isObject)
01041 {
01042 for (v=0; v<_fullParentPrototype[p]->_sqlVars.Count; v++)
01043 {
01044 sqlVar &var = ((sqlVar*)(_fullParentPrototype[p]->_sqlVars.Arr))[v];
01045 StrCat(qselect,2,qsdelim,var.colname);
01046 qsdelim=", ";
01047 };
01048 }
01049 else
01050 {
01051 for (v=0; v<_fullParentPrototype[p]->_sqlVars.KeyCount; v++)
01052 {
01053 sqlVar &var = ((sqlVar*)(_fullParentPrototype[p]->_sqlVars.Arr))[v];
01054 StrCpy(trimcol,var.colname);
01055 StrPrefixCut(trimcol,'.');
01056 StrCat(qselect,4,qsdelim,alias,".",trimcol);
01057 qsdelim=", ";
01058 StrFree(trimcol);
01059 };
01060 for (v=_fullParentPrototype[p]->_sqlVars.Count; v<_fullParentPrototype[p]->_sqlVars.SpecCount; v++)
01061 {
01062 sqlVar &var = ((sqlVar*)(_fullParentPrototype[p]->_sqlVars.Arr))[v];
01063 StrCpy(trimcol,var.colname);
01064 StrPrefixCut(trimcol,'.');
01065 StrCat(qselect,4,qsdelim,alias,".",trimcol);
01066 qsdelim=", ";
01067 StrFree(trimcol);
01068 };
01069 };
01070 };
01071
01072 if (_isObject)
01073 StrCat(qfrom,2,qfdelim,_fullParentPrototype[p]->From());
01074 else
01075 StrCat(qfrom,4,qfdelim,_fullParentPrototype[p]->From()," ",alias);
01076 qfdelim=", ";
01077
01078 if (_where && *_where)
01079 {
01080 char * cwhere = NULL;
01081 StrCpy(cwhere,_where);
01082 _RealiasT(cwhere,i);
01083 StrCat(qwhere,4,qwdelim,"(",cwhere,")");
01084 qwdelim=" AND ";
01085 StrFree(cwhere);
01086 };
01087
01088 if (p>0)
01089 {
01090
01091 char * trimcol = NULL;
01092 int v;
01093 for (v=0; v<_fullParentPrototype[p]->_sqlVars.KeyCount; v++)
01094 {
01095 sqlVar &rootvar = ((sqlVar*)(_rootPrototype->_sqlVars.Arr))[v];
01096 sqlVar &thisvar = ((sqlVar*)(_fullParentPrototype[p]->_sqlVars.Arr))[v];
01097 StrCpy(trimcol,thisvar.colname);
01098 StrPrefixCut(trimcol,'.');
01099 StrCat(qwhere,5,qwdelim,"(",alias,".",trimcol);
01100 StrFree(trimcol);
01101 StrCpy(trimcol,rootvar.colname);
01102 StrPrefixCut(trimcol,'.');
01103 StrCat(qwhere,5,"=",rootalias,".",trimcol,")");
01104 StrFree(trimcol);
01105 qwdelim=" AND ";
01106 };
01107 };
01108 StrFree(alias);
01109 };
01110 StrFree(rootalias);
01111
01112 if (_from_clause && *_from_clause)
01113 {
01114
01115
01116 StrCat(qfrom,2,qfdelim,_from_clause);
01117
01118 };
01119 if (_where_clause && *_where_clause)
01120 {
01121
01122
01123 StrCat(qwhere,4,qwdelim,"(",_where_clause,")");
01124
01125 };
01126 if (_select_clause && *_select_clause)
01127 {
01128
01129
01130
01131
01132 };
01133
01134 char * statement = NULL;
01135 char * qgroupBy = NULL;
01136 char * qhaving = NULL;
01137 char * qorderby = NULL;
01138 StrCpy(qgroupBy,_groupBy);
01139 _RealiasT(qgroupBy,i);
01140 StrCpy(qhaving,_having);
01141 _RealiasT(qhaving,i);
01142 StrCpy(qorderby,_order_by_clause);
01143 StrClause(qwhere,"WHERE");
01144 StrClause(qgroupBy,"GROUP BY");
01145 StrClause(qhaving,"HAVING");
01146 StrClause(qorderby,"ORDER BY");
01147 StrCat(statement,12,
01148 "SELECT ", qselect,
01149 " FROM ", qfrom,
01150 " ", qwhere,
01151 " ", qgroupBy,
01152 " ", qhaving,
01153 " ", qorderby
01154 );
01155 StrFree(qselect);
01156 StrFree(qfrom);
01157 StrFree(qwhere);
01158 StrFree(qgroupBy);
01159 StrFree(qhaving);
01160 StrFree(qorderby);
01161 return statement;
01162 };
01163
01164 bool ProtoBase::_BindPtr(
01165
01166 class Cursor *C
01167 )
01168 {
01169 int v;
01170 int i=0;
01171 if (_isObject)
01172 {
01173
01174 for (v=0; v<_rootPrototype->_sqlVars.Count; v++)
01175 {
01176 i++;
01177 sqlVar &var=((sqlVar *)(_rootPrototype->_sqlVars.Arr))[v];
01178 C->_PreFetchBind(i,var.bufaddr,var.buflen,var.buftype);
01179 };
01180 }
01181 else
01182 {
01183
01184
01185 for (v=0; v<_rootPrototype->_sqlVars.KeyCount; v++)
01186 {
01187 i++;
01188 sqlVar &var=((sqlVar *)(_rootPrototype->_sqlVars.Arr))[v];
01189 C->_PreFetchBind(i,var.bufaddr,var.buflen,var.buftype);
01190 };
01191 for (v=_rootPrototype->_sqlVars.Count; v<_rootPrototype->_sqlVars.SpecCount; v++)
01192 {
01193 i++;
01194 sqlVar &var=((sqlVar *)(_rootPrototype->_sqlVars.Arr))[v];
01195 C->_PreFetchBind(i,var.bufaddr,var.buflen,var.buftype);
01196 };
01197 };
01198 return true;
01199 };
01200
01201 ProtoBase *ProtoBase::_PtrPrototype()
01202
01203 {
01204 _Initialise();
01205 #ifndef NO_DATABASE_PRESENT
01206 if (_isPersistentObject)
01207 return Class[(char *)(((sqlVar *)(_rootPrototype->_sqlVars.Arr))[_rootPrototype->_sqlVars.Count].bufaddr)];
01208 else
01209 #endif
01210 return this;
01211 };
01212
01213 ProtoBase * ProtoBase::Find(const char *_n)
01214 {
01215 ProtoBase *p = _root;
01216 int c;
01217 while (p) {
01218 c = StrCmp(p->ClassName(),_n);
01219 if (c > 0)
01220 p = p->_left;
01221 else if (c < 0)
01222 p = p->_right;
01223 else
01224 break;
01225 };
01226 return p;
01227 };
01228
01229 bool ProtoBase::operator<(class ProtoBase &_p)
01230 {
01231 _Initialise();
01232 int i = 0;
01233 while((i<_fullParentPrototypeCount-1) && (_fullParentPrototype[i]!=&_p))
01234 i++;
01235 return ((i<_fullParentPrototypeCount-1) && (_fullParentPrototype[i]==&_p));
01236 };
01237
01238 ProtoBase::~ProtoBase()
01239 {
01240 StrFree(_condition);
01241 if (_sqlVars.Arr)
01242 {
01243 for (int i=0; i<_sqlVars.Count; i++)
01244 {
01245 StrFree(((sqlVar*)_sqlVars.Arr)[i].atrname);
01246 if (((sqlVar*)_sqlVars.Arr)[i].bufaddr) free(((sqlVar*)_sqlVars.Arr)[i].bufaddr);
01247 };
01248 free(_sqlVars.Arr);
01249 };
01250 free(_parentPrototype);
01251 free(_fullParentPrototype);
01252 StrFree(_select);
01253 StrFree(_fullSelect);
01254 StrFree(_keySelect);
01255 StrFree(_ptrSelect);
01256 StrFree(_into);
01257
01258
01259 StrFree(_fullFrom);
01260 StrFree(_where);
01261 StrFree(_fullWhere);
01262 StrFree(_keyWhere);
01263 StrFree(_stmtSelect);
01264 StrFree(_stmtInsert);
01265 StrFree(_stmtDelete);
01266 StrFree(_stmtUpdate);
01267 };
01268
01269 class ProtoBase * ProtoBase::ParentPrototype(const int i)
01270 {
01271 _Initialise();
01272 if ((i<0)||(i>=_parentPrototypeCount))
01273 return NULL;
01274 return _parentPrototype[i];
01275 };
01276
01277 class ProtoBase * ProtoBase::FullParentPrototype(const int i)
01278 {
01279 _Initialise();
01280 if ((i<0)||(i>=_fullParentPrototypeCount))
01281 return NULL;
01282 return _fullParentPrototype[i];
01283 };
01284
01285 const char* ProtoBase::ColumnTable(const char* const col)
01286
01287 {
01288 _Initialise();
01289 for(int i=0;i<_fullParentPrototypeCount;i++)
01290 for(int j=1; j<=_fullParentPrototype[i]->_sqlVars.Count; j++)
01291 if (!StrCmpUp(col,(((sqlVar*)(_fullParentPrototype[i]->_sqlVars.Arr))[j-1]).colname))
01292 return _fullParentPrototype[i]->From();
01293 return NULL;
01294 };
01295
01296 bool ProtoBase::_InsertAll(class Object *target)
01297
01298 {
01299 _Initialise();
01300 bool retval;
01301
01302 #ifdef C_PROTOBASE_TRACE
01303 logmsg("bool ProtoBase::_InsertAll() invoked");
01304 #endif
01305
01306 retval = _ExportAttributes(*target);
01307 for(int i=0; i<_fullParentPrototypeCount; i++)
01308 retval = retval && _fullParentPrototype[i]->_Insert(target->_Connection);
01309
01310 #ifdef C_PROTOBASE_TRACE
01311 logmsg("bool ProtoBase::_InsertAll() finished");
01312 #endif
01313
01314 return retval;
01315 };
01316
01317 bool ProtoBase::_Insert(class Connection *aDbConn)
01318
01319 {
01320 bool retval = true;
01321
01322 #ifdef C_PROTOBASE_TRACE
01323 logmsg("bool ProtoBase::_Insert() invoked");
01324 #endif
01325
01326 retval = retval && aDbConn->_Open();
01327 retval = retval && aDbConn->_Prepare(_stmtInsert);
01328
01329 int v;
01330 for (v=0 ; v<_fullParentPrototype[0]->_sqlVars.KeyCount; v++)
01331 {
01332 sqlVar &rootvar = ((sqlVar *)_fullParentPrototype[0]->_sqlVars.Arr)[v];
01333 sqlVar &thisvar = ((sqlVar *)_sqlVars.Arr)[v];
01334 retval = retval && aDbConn->_PreExecBind(
01335 thisvar.varname,
01336 rootvar.bufaddr,
01337 rootvar.buflen,
01338 rootvar.buftype,
01339 &rootvar.indic
01340 );
01341 };
01342 for (v=_sqlVars.KeyCount ; v<_sqlVars.SpecCount; v++)
01343 {
01344 sqlVar &var = ((sqlVar *)_sqlVars.Arr)[v];
01345 if (var.rw)
01346 {
01347 retval = retval && aDbConn->_PreExecBind(
01348 var.varname,
01349 var.bufaddr,
01350 var.buflen,
01351 var.buftype,
01352 &var.indic
01353 );
01354 };
01355 };
01356 retval = retval && aDbConn->_Execute();
01357 retval = retval && aDbConn->_Close();
01358
01359 #ifdef C_PROTOBASE_TRACE
01360 logmsg("bool ProtoBase::_Insert() finished");
01361 #endif
01362
01363 return retval;
01364 };
01365
01367
01368 bool ProtoBase::_UpdateAll(class Object *target)
01369
01370 {
01371 _Initialise();
01372 bool retval;
01373
01374 #ifdef C_PROTOBASE_TRACE
01375 logmsg("bool ProtoBase::_UpdateAll() invoked");
01376 #endif
01377
01378 retval = _ExportAttributes(*target);
01379 for(int i=0; i<_fullParentPrototypeCount; i++)
01380 retval = retval && _fullParentPrototype[i]->_Update(target->_Connection);
01381 target->_MarkAsClean();
01382
01383 #ifdef C_PROTOBASE_TRACE
01384 logmsg("bool ProtoBase::_Insert() finished");
01385 #endif
01386
01387 return retval;
01388 };
01389
01390 bool ProtoBase::_Update(class Connection *aDbConn)
01391
01392 {
01393 bool retval;
01394
01395 #ifdef C_PROTOBASE_TRACE
01396 logmsg("bool ProtoBase::_Update() invoked");
01397 #endif
01398
01399 if (_sqlVars.Count == _sqlVars.KeyCount)
01400
01401 return true;
01402
01403 retval = aDbConn->_Open();
01404 retval = retval && aDbConn->_Prepare(_stmtUpdate);
01405
01406 int v;
01407 for (v=_sqlVars.KeyCount; v<_sqlVars.Count; v++)
01408 {
01409 sqlVar &var = ((sqlVar *)_sqlVars.Arr)[v];
01410 if (var.rw)
01411 {
01412 retval = retval && aDbConn->_PreExecBind(
01413 var.varname,
01414 var.bufaddr,
01415 var.buflen,
01416 var.buftype,
01417 &var.indic
01418 );
01419 };
01420 };
01421 for (v=0; v<_fullParentPrototype[0]->_sqlVars.KeyCount; v++)
01422 {
01423 sqlVar &rootvar = ((sqlVar *)_fullParentPrototype[0]->_sqlVars.Arr)[v];
01424 sqlVar &thisvar = ((sqlVar *)_sqlVars.Arr)[v];
01425 retval = retval && aDbConn->_PreExecBind(
01426 thisvar.varname,
01427 rootvar.bufaddr,
01428 rootvar.buflen,
01429 rootvar.buftype,
01430 &rootvar.indic
01431 );
01432 };
01433 retval = retval && aDbConn->_Execute();
01434 retval = retval && aDbConn->_Close();
01435
01436 #ifdef C_PROTOBASE_TRACE
01437 logmsg("bool ProtoBase::_Update() finished");
01438 #endif
01439 return retval;
01440 };
01441
01442 bool ProtoBase::_DeleteAll(class RefBase *target)
01443 {
01444 _Initialise();
01445 bool retval;
01446
01447 #ifdef C_PROTOBASE_TRACE
01448 logmsg("bool ProtoBase::_DeleteAll(RefBase *) invoked");
01449 #endif
01450
01451 #ifdef NO_DATABASE_CASCADE_DELETE
01452 for(int i=_fullParentPrototypeCount-1; i>0; i--)
01453 retval = retval && _fullParentPrototype[i]->_Delete(target->_Connection);
01454 #else
01455 retval = _fullParentPrototype[0]->_Delete(target->_Connection);
01456 #endif
01457
01458 #ifdef C_PROTOBASE_TRACE
01459 logmsg("bool ProtoBase::_DeleteAll(RefBase *) finished");
01460 #endif
01461
01462 return retval;
01463 };
01464
01465 bool ProtoBase::_DeleteAll(class Object *target)
01466 {
01467 _Initialise();
01468 bool retval;
01469
01470 #ifdef C_PROTOBASE_TRACE
01471 logmsg("bool ProtoBase::_DeleteAll(Object *) invoked");
01472 #endif
01473
01474 #ifdef NO_DATABASE_CASCADE_DELETE
01475 for(int i=_fullParentPrototypeCount-1; i>0; i--)
01476 retval = retval && _fullParentPrototype[i]->_Delete(target->_Connection);
01477 #else
01478 retval = _fullParentPrototype[0]->_Delete(target->_Connection);
01479 #endif
01480
01481 #ifdef C_PROTOBASE_TRACE
01482 logmsg("bool ProtoBase::_DeleteAll(Object *) finished");
01483 #endif
01484
01485 return retval;
01486 };
01487
01488 bool ProtoBase::_Delete(class Connection * aDbConn)
01489 {
01490 bool retval;
01491
01492 #ifdef C_PROTOBASE_TRACE
01493 logmsg("bool ProtoBase::_Delete() invoked");
01494 #endif
01495
01496 retval = aDbConn->_Open();
01497 retval = retval && aDbConn->_Prepare(_stmtDelete);
01498
01499 for (int v=0; v < _rootPrototype->_sqlVars.KeyCount; v++)
01500 {
01501 sqlVar &rootvar = ((sqlVar *)_rootPrototype->_sqlVars.Arr)[v];
01502 sqlVar &thisvar = ((sqlVar *)_sqlVars.Arr)[v];
01503 retval = retval && aDbConn->_PreExecBind(
01504 thisvar.varname,
01505 rootvar.bufaddr,
01506 rootvar.buflen,
01507 rootvar.buftype
01508 );
01509 };
01510
01511 retval = retval && aDbConn->_Execute();
01512 retval = retval && aDbConn->_Close();
01513
01514 #ifdef C_PROTOBASE_TRACE
01515 logmsg("bool ProtoBase::_Delete() finished");
01516 #endif
01517
01518 return retval;
01519 };
01520
01522
01523
01524 bool ProtoBase::_Load(
01525 class Object &o
01526 )
01527 {
01528 bool retval = true;
01529 #ifdef C_PROTOBASE_TRACE
01530 logmsg("ProtoBase::_Load(Object) invoked");
01531 #endif
01532
01533 if (o.IsPersistent())
01534 {
01535 _Initialise();
01536 char * statement = NULL;
01537 StrCpy(statement,_stmtSelect);
01538 if (o.CurrentLockingStrategy() == LS_Exclusive)
01539 {
01540 StrCat(statement," FOR UPDATE");
01541 if (o.CurrentWaitingStrategy() == WS_Nowait)
01542 StrCat(statement," NOWAIT");
01543 else
01544 ;
01545 };
01546 retval = retval && o._Connection->_Open();
01547 retval = retval && o._Connection->_Prepare(statement);
01548
01549 for (int v=0; v < _rootPrototype->_sqlVars.KeyCount; v++)
01550 {
01551 sqlVar &var = ((sqlVar *)_rootPrototype->_sqlVars.Arr)[v];
01552 retval = retval && o._Connection->_PreExecBind(
01553 var.varname,
01554 var.bufaddr,
01555 var.buflen,
01556 var.buftype
01557 );
01558 };
01559 retval = retval && o._Connection->_Execute();
01560
01561 int col = 0;
01562 for (int i=0; i<_fullParentPrototypeCount; i++)
01563 for (int v=_fullParentPrototype[i]->_sqlVars.KeyCount; v<_fullParentPrototype[i]->_sqlVars.Count; v++)
01564 {
01565 sqlVar &var = ((sqlVar *)_fullParentPrototype[i]->_sqlVars.Arr)[v];
01566 retval = retval && o._Connection->_PreFetchBind(
01567 ++col,
01568 var.bufaddr,
01569 var.buflen,
01570 var.buftype,
01571 &var.indic
01572 );
01573 };
01574 retval = retval && o._Connection->_FetchNext();
01575 retval = retval && o._Connection->_Close();
01576 retval = retval && _ImportAttributes(o) && o.PostLoad();
01577 if (o.CurrentLockingStrategy() == LS_Exclusive)
01578 {
01579 o._ForUpdate = true;
01580 }
01581 o._MarkAsClean();
01582 };
01583 #ifdef C_PROTOBASE_TRACE
01584 logmsg("char * ProtoBase::_Load() finished");
01585 #endif
01586 return(retval);
01587 };
01588
01590
01591
01592 bool ProtoBase::LockTable(
01593 class Connection *aDbCon,
01594 enum LockingStrategy aLockingStrategy,
01595 enum WaitingStrategy aWaitingStrategy
01596 )
01597 {
01598 bool _retval;
01599 if (aDbCon && (aLockingStrategy != LS_None))
01600 {
01601 if (aLockingStrategy == LS_Default)
01602 aLockingStrategy = DEFAULT_LOCKING_STRATEGY;
01603 if (aWaitingStrategy == WS_Default)
01604 aWaitingStrategy = DEFAULT_WAITING_STRATEGY;
01605 if (IsDatabaseObject() || IsPersistentObject())
01606 {
01607 char *lock = NULL;
01608 StrCat(lock,3,"LOCK TABLE ",From()," IN");
01609 switch (aLockingStrategy)
01610 {
01611 case LS_Shared:
01612 StrCat(lock," SHARED MODE");
01613 break;
01614 case LS_Exclusive:
01615 StrCat(lock," EXCLUSIVE MODE");
01616 break;
01617 };
01618 switch (aWaitingStrategy)
01619 {
01620 case WS_Wait:
01621 break;
01622 case WS_Nowait:
01623 StrCat(lock," NOWAIT");
01624 break;
01625 };
01626 _retval = aDbCon->Sql(lock);
01627 StrFree(lock);
01628 }
01629 else
01630 _retval = false;
01631 }
01632 else
01633 _retval = false;
01634 return _retval;
01635 };
01636
01637
01638 char * ProtoBase::_RealiasT(
01639 char * &fragment,
01640 const char *table,
01641 const int i,
01642 const int j
01643 )
01644 {
01645 _Initialise();
01646 char *_Alias = StrCpy(_Alias=NULL ,AliasT(i,j));
01647 char *_TableName = StrCpy(_TableName=NULL,table);
01648 StrCat(_Alias,".");
01649 StrCat(_TableName,".");
01650 StrReplaceAll(fragment,_TableName,_Alias,true);
01651 StrFree(_Alias);
01652 StrFree(_TableName);
01653 return fragment;
01654 };
01655
01656 char * ProtoBase::_RealiasT(
01657 char * &fragment,
01658 const int i
01659 )
01660 {
01661 _Initialise();
01662 for (int j=0; j < _fullParentPrototypeCount; j++)
01663 _RealiasT(fragment,_fullParentPrototype[j]->From(),i,j);
01664 return fragment;
01665 };
01666
01667 bool ProtoBase::WriteDDL(ofstream &S, class Database &Db)
01668
01669 {
01670 if (!S.rdbuf()->is_open())
01671 return false;
01672 _Initialise();
01673 if (!From() || !*From())
01674 return true;
01675 if (!_isPersistentObject)
01676 return true;
01677 S << "-- Table " << From() << " associated with class " << ClassName() << endl;
01678
01679 S << "CREATE TABLE " << From() << "(";
01680 char *col = NULL;
01681 char *typ = NULL;
01682 const char *delimcols = "";
01683 const char *delimkeys = "";
01684 int i;
01685
01686 for(i=0; i<_sqlVars.SpecCount; i++)
01687 {
01688 sqlVar &var = ((sqlVar *)(_sqlVars.Arr))[i];
01689 col = StrCpy(var.colname);
01690 StrPrefixCut(col,'.');
01691 typ = Db.ColumnTypeDDL(var.buftype,var.buflen);
01692 S << delimcols << endl << col << " " << typ;
01693 StrFree(col);
01694 StrFree(typ);
01695 delimcols = ",";
01696 };
01697
01698 S << delimcols << endl << "CONSTRAINT " << From() << "_PK PRIMARY KEY(";
01699 for(i=0; i<_sqlVars.KeyCount; i++)
01700 {
01701 sqlVar &var = ((sqlVar *)(_sqlVars.Arr))[i];
01702 col = StrCpy(var.colname);
01703 StrPrefixCut(col,'.');
01704 S << delimkeys << col;
01705 StrFree(col);
01706 delimkeys = ",";
01707 };
01708 S << ")";
01709 delimcols = ",";
01710
01711 for(int p=0; p<_parentPrototypeCount; p++)
01712 {
01713 S << delimcols << endl << "CONSTRAINT " << From() << "_FK_" << _parentPrototype[p]->From();
01714 S << " FOREIGN KEY(";
01715 delimkeys = "";
01716 for(i=0; i<_sqlVars.KeyCount; i++)
01717 {
01718 sqlVar &var = ((sqlVar *)(_sqlVars.Arr))[i];
01719 col = StrCpy(var.colname);
01720 StrPrefixCut(col,'.');
01721 S << delimkeys << col;
01722 StrFree(col);
01723 delimkeys = ",";
01724 };
01725 S << ") REFERENCES " << _parentPrototype[p]->From() << "(";
01726 delimkeys = "";
01727 for(i=0; i<_parentPrototype[p]->_sqlVars.KeyCount; i++)
01728 {
01729 sqlVar &var = ((sqlVar *)(_parentPrototype[p]->_sqlVars.Arr))[i];
01730 col = StrCpy(var.colname);
01731 StrPrefixCut(col,'.');
01732 S << delimkeys << col;
01733 StrFree(col);
01734 delimkeys = ",";
01735 };
01736 S << ") ON DELETE CASCADE";
01737 delimcols = ",";
01738 };
01739
01740 S << endl << ");" << endl << endl;
01741 S.flush();
01742 return true;
01743 };
01744
01745 char* ProtoBase::FullFrom(int k)
01746 {
01747 _Initialise();
01748 char *result = NULL;
01749 char *alias = NULL;
01750 const char *delim = "";
01751 for (int i=0; i<_fullParentPrototypeCount; i++)
01752 {
01753 alias = AliasT(k,i);
01754 StrCat(result,4,delim,_fullParentPrototype[i]->From()," ",alias);
01755 delim = ",";
01756 StrFree(alias);
01757 };
01758 return result;
01759 };
01760
01761 char* ProtoBase::FullWhere(int k)
01762 {
01763 _Initialise();
01764 char *result = NULL;
01765 char *rootalias = AliasT(k,0);
01766 char *alias = NULL;
01767 const char *delim = "";
01768 for (int p=1; p<_fullParentPrototypeCount; p++)
01769 {
01770 alias = AliasT(k,p);
01771 char * trimcol = NULL;
01772 int v;
01773 for (v=0; v<_fullParentPrototype[p]->_sqlVars.KeyCount; v++)
01774 {
01775 sqlVar &rootvar = ((sqlVar*)(_rootPrototype->_sqlVars.Arr))[v];
01776 sqlVar &thisvar = ((sqlVar*)(_fullParentPrototype[p]->_sqlVars.Arr))[v];
01777 StrCpy(trimcol,thisvar.colname);
01778 StrPrefixCut(trimcol,'.');
01779 StrCat(result,5,delim,"(",alias,".",trimcol);
01780 StrFree(trimcol);
01781 StrCpy(trimcol,rootvar.colname);
01782 StrPrefixCut(trimcol,'.');
01783 StrCat(result,5,"=",rootalias,".",trimcol,")");
01784 StrFree(trimcol);
01785 delim=" AND ";
01786 };
01787 StrFree(alias);
01788 };
01789 StrFree(rootalias);
01790 return result;
01791 };
01792
01793 char *ProtoBase::ColumnTypeDDL(int i, class Database &Db)
01794
01795 {
01796 _Initialise();
01797 if ((i<0) || (i>=_sqlVars.SpecCount))
01798 return StrCpy("UNKNOWN");
01799 else
01800 {
01801 sqlVar &var = ((sqlVar *)(_sqlVars.Arr))[i];
01802 return Db.ColumnTypeDDL(var.buftype,var.buflen);
01803 };
01804 };
01805
01806 char *ProtoBase::_TranslateToSql(char * (&dst), const char * const src)
01807
01808 {
01809 _Initialise();
01810 StrCpy(dst,src);
01811 StrReplaceAll(dst,"==","=");
01812 StrReplaceAll(dst,"!=","<>");
01813 StrReplaceAll(dst,"&&"," AND ");
01814 StrReplaceAll(dst,"||"," OR ");
01815 StrReplaceAll(dst,"!"," NOT ");
01816 char *cpp = NULL;
01817 char *sql = NULL;
01818
01819
01820 ProtoBase *ClassProto;
01821 ProtoBase *AttrProto;
01822 for(int c=0; c<_fullParentPrototypeCount; c++)
01823 {
01824 ClassProto = _fullParentPrototype[c];
01825 for (int a=(ClassProto->_fullParentPrototypeCount)-1; a>=0; a--)
01826 {
01827 AttrProto = ClassProto->_fullParentPrototype[a];
01828 for(int v=0; v<AttrProto->_sqlVars.SpecCount; v++)
01829 {
01830 sqlVar &var = ((sqlVar*)(AttrProto->_sqlVars.Arr))[v];
01831 StrCat(cpp,3,ClassProto->ClassName(),"::",var.atrname);
01832 StrCat(sql,3,"(",var.colname,")");
01833 StrReplaceAll(dst,cpp,sql,true,true);
01834 StrFree(cpp);
01835 StrFree(sql);
01836 };
01837 };
01838 };
01839
01840 return dst;
01841 };
01842
01843 char *ProtoBase::_TranslateToSql(char * (&src))
01844
01845 {
01846 char *dst = NULL;
01847 _TranslateToSql(dst,src);
01848 StrFree(src);
01849 src=dst;
01850 return src;
01851 };
01852
01853 class Query &ProtoBase::_TranslateToSql(class Query &Q)
01854
01855 {
01856 _TranslateToSql(Q._where);
01857 _TranslateToSql(Q._order_by);
01858 return Q;
01859 };