00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <lTrace.h>
00017 #include <lDefs.h>
00018
00019
00020
00021 #include <cOneToManyRelationBase.h>
00022
00023
00024 #include <cChainedRelationBase.h>
00025 #include <cClassRegister.h>
00026 #include <cRefBase.h>
00027 #include <cRefBase.h>
00028 #include <cConnection.h>
00029 #include <cComplexQuery.h>
00030
00031 OneToManyRelationBase::OneToManyRelationBase(
00032 const char *a_left_class_name,
00033 const char *a_right_class_name,
00034 const char *a_table_name,
00035 class Connection *a_database_connection,
00036 const char *a_left_column_name,
00037 const char *a_right_column_name
00038 ) :
00039 Relation(
00040 a_left_class_name,
00041 a_right_class_name,
00042 a_table_name,
00043 a_database_connection
00044 )
00045 {
00046 ProtoBase *_left_prototype=Class[_leftClassName];
00047 ProtoBase *_right_prototype=Class[_rightClassName];
00048 char *_str = NULL;
00049 char *_separator = NULL;
00050 char *_column = NULL;
00051
00052 if (!a_left_column_name || !*a_left_column_name)
00053 {
00054 StrCpy(_str,_left_prototype->KeySelect());
00055 while (StrSplit(_str,',',_column))
00056 {
00057 StrPrefixCut(_column,'.');
00058 StrCat(_leftColumnName,4,_separator,_tableName,"_",_column);
00059 _separator = ", ";
00060 };
00061 }
00062 else
00063 StrCpy(_leftColumnName=NULL,a_left_column_name);
00064
00065 if (!a_right_column_name || !*a_right_column_name)
00066 StrCpy(_rightColumnName, _right_prototype->KeySelect());
00067 else
00068 StrCpy(_rightColumnName=NULL,a_right_column_name);
00069
00070 StrFree(_str);
00071 };
00072
00073 bool OneToManyRelationBase::InsertCouple(RefBase &left, RefBase &right)
00074
00075 {
00076 if (left.IsTransient() || right.IsTransient())
00077 return false;
00078 ProtoBase *_left_prototype=Class[_leftClassName];
00079 ProtoBase *_right_prototype=Class[_rightClassName];
00080
00081
00082
00083 bool _retval;
00084 char *_update = StrCpy(_update = NULL, _right_prototype->From());
00085 StrClause(_update,"UPDATE");
00086 char *_columns = StrCpy(_columns = NULL, _leftColumnName);
00087 char *_1column = NULL;
00088 char *_values = left._KeyValues();
00089 char *_1value = NULL;
00090 char *_set = NULL;
00091 char *_separator = NULL;
00092 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00093 StrCat(_set,4,_separator,_1column," = ",_1value);
00094 _separator = ", ";
00095 };
00096 StrClause(_set,"SET");
00097 StrCpy(_columns,_right_prototype->KeySelect());
00098 StrFree(_1column);
00099 StrFree(_values);
00100 _values = right._KeyValues();
00101 StrFree(_1value);
00102 char *_where = NULL;
00103 _separator = "(";
00104 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00105 StrPrefixCut(_1column,'.');
00106 StrCat(_where,4,_separator,_1column," = ",_1value);
00107 _separator = ") AND (";
00108 };
00109 StrCat(_where,")");
00110 StrClause(_where,"WHERE");
00111 StrFree(_columns);
00112 StrFree(_1column);
00113 StrFree(_values);
00114 StrFree(_1value);
00115 StrCat(_update,2,_set,_where);
00116 StrFree(_set);
00117 StrFree(_where);
00118 if (_databaseConnection == NULL)
00119 throw ObjLibException_ConnectionError();
00120 _retval = _databaseConnection -> _Sql(_update);
00121 StrFree(_update);
00122 return _retval;
00123 };
00124
00125 bool OneToManyRelationBase::DeleteCouple(RefBase &left, RefBase &right)
00126 {
00127 if (left.IsTransient() || right.IsTransient())
00128 return false;
00129 ProtoBase *_right_prototype=Class[_rightClassName];
00130
00131
00132
00133 bool _retval;
00134 char *_update = StrCpy(_update = NULL, _right_prototype->From());
00135 StrClause(_update,"UPDATE");
00136 char *_columns = StrCpy(_columns = NULL, _leftColumnName);
00137 char *_1column = NULL;
00138 char *_values = left._KeyValues();
00139 char *_1value = NULL;
00140 char *_set = NULL;
00141 char *_separator = NULL;
00142 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00143 StrCat(_set,3,_separator,_1column," = NULL");
00144 _separator = ", ";
00145 };
00146 StrClause(_set,"SET");
00147 StrCpy(_columns,_leftColumnName);
00148 StrCat(_columns,2,", ",_right_prototype->KeySelect());
00149 StrFree(_1column);
00150 StrFree(_values);
00151 _values = left._KeyValues();
00152 StrFree(_1value);
00153 StrCat(_values,2,", ",_1value = right._KeyValues());
00154 StrFree(_1value);
00155 char *_where = NULL;
00156 _separator = "(";
00157 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00158 StrPrefixCut(_1column,'.');
00159 StrCat(_where,4,_separator,_1column," = ",_1value);
00160 _separator = ") AND (";
00161 };
00162 StrCat(_where,")");
00163 StrClause(_where,"WHERE");
00164 StrFree(_columns);
00165 StrFree(_1column);
00166 StrFree(_values);
00167 StrFree(_1value);
00168 StrCat(_update,2,_set,_where);
00169 StrFree(_set);
00170 StrFree(_where);
00171 if (_databaseConnection == NULL)
00172 throw ObjLibException_ConnectionError();
00173 _retval = _databaseConnection -> _Sql(_update);
00174 StrFree(_update);
00175 return _retval;
00176 };
00177
00178 bool OneToManyRelationBase::LDeleteAll(class RefBase &right)
00179
00180 {
00181 if (right.IsTransient())
00182 return false;
00183 ProtoBase *_right_prototype=Class[_rightClassName];
00184
00185
00186
00187 bool _retval;
00188 char *_update = StrCpy(_update = NULL, _right_prototype -> From());
00189 StrClause(_update,"UPDATE");
00190 char *_columns = StrCpy(_columns = NULL, _leftColumnName);
00191 char *_1column = NULL;
00192 char *_values = NULL;
00193 char *_1value = NULL;
00194 char *_set = NULL;
00195 char *_separator = NULL;
00196 while (StrSplit(_columns,',',_1column)) {
00197 StrCat(_set,3,_separator,_1column," = NULL");
00198 _separator = ", ";
00199 };
00200 StrClause(_set,"SET");
00201 StrCpy(_columns,_right_prototype->KeySelect());
00202 StrFree(_1column);
00203 StrFree(_values);
00204 _values = right._KeyValues();
00205 StrFree(_1value);
00206 char *_where = NULL;
00207 _separator = "(";
00208 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00209 StrPrefixCut(_1column,'.');
00210 StrCat(_where,4,_separator,_1column," = ",_1value);
00211 _separator = ") AND (";
00212 };
00213 StrCat(_where,")");
00214 StrClause(_where,"WHERE");
00215 StrFree(_columns);
00216 StrFree(_1column);
00217 StrFree(_values);
00218 StrFree(_1value);
00219 StrCat(_update,2,_set,_where);
00220 StrFree(_set);
00221 StrFree(_where);
00222 if (_databaseConnection == NULL)
00223 throw ObjLibException_ConnectionError();
00224 _retval = _databaseConnection -> _Sql(_update);
00225 StrFree(_update);
00226 return _retval;
00227 };
00228
00229 bool OneToManyRelationBase::RDeleteAll(class RefBase &left)
00230
00231 {
00232 if (left.IsTransient())
00233 return false;
00234 ProtoBase *_right_prototype=Class[_rightClassName];
00235
00236
00237
00238 bool _retval;
00239 char *_update = StrCpy(_update = NULL, _right_prototype -> From());
00240 StrClause(_update,"UPDATE");
00241 char *_columns = StrCpy(_columns = NULL, _leftColumnName);
00242 char *_1column = NULL;
00243 char *_values = NULL;
00244 char *_1value = NULL;
00245 char *_set = NULL;
00246 char *_separator = NULL;
00247 while (StrSplit(_columns,',',_1column)) {
00248 StrCat(_set,3,_separator,_1column," = NULL");
00249 _separator = ", ";
00250 };
00251 StrClause(_set,"SET");
00252 StrCpy(_columns,_leftColumnName);
00253 StrFree(_1column);
00254 StrFree(_values);
00255 _values = left._KeyValues();
00256 StrFree(_1value);
00257 char *_where = NULL;
00258 _separator = "(";
00259 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00260 StrPrefixCut(_1column,'.');
00261 StrCat(_where,4,_separator,_1column," = ",_1value);
00262 _separator = ") AND (";
00263 };
00264 StrCat(_where,")");
00265 StrClause(_where,"WHERE");
00266 StrFree(_columns);
00267 StrFree(_1column);
00268 StrFree(_values);
00269 StrFree(_1value);
00270 StrCat(_update,2,_set,_where);
00271 StrFree(_set);
00272 StrFree(_where);
00273 if (_databaseConnection == NULL)
00274 throw ObjLibException_ConnectionError();
00275 _retval = _databaseConnection -> _Sql(_update);
00276 StrFree(_update);
00277 return _retval;
00278 };
00279
00280 ResultBase *OneToManyRelationBase::_LGetAll(
00281 ResultBase *rb,
00282 const class RefBase &right,
00283 const class QueRefProto &query
00284 )
00285
00286 {
00287 #ifdef GC_REL1N_TRACE
00288 logmsg("OneToManyRelationBase::LGetAll(...) invoked");
00289 #endif
00290
00291 if (right.IsTransient())
00292 return NULL;
00293 ProtoBase *_left_prototype=Class[_leftClassName];
00294 ProtoBase *_right_prototype=Class[_rightClassName];
00295 RefBase r = right;
00296
00297
00298
00299 char *_Select = StrCpy(_Select=NULL,_leftColumnName);
00300 char *_Columns = StrCpy(
00301 _Columns=NULL,
00302 _left_prototype->KeySelect()
00303 );
00304 char *_Values = r._KeyValues();
00305 char *_1Select = NULL;
00306 char *_1Column = NULL;
00307 char *_1Value = NULL;
00308 char *_JoinCondition = NULL;
00309 char *_KeyCondition = NULL;
00310 char *_Separator = "(";
00311 char *_Alias = NULL;
00312
00313 while (
00314 StrSplit(_Select,',',_1Select)
00315 && StrSplit(_Columns,',',_1Column)
00316 ) {
00317 StrCat(_JoinCondition,6,_Separator,_tableName,".",_1Select," = ",_1Column);
00318 _Separator = ") AND (";
00319 };
00320 StrCat(_JoinCondition,")");
00321 StrFree(_Select);
00322 StrFree(_Columns);
00323 StrFree(_1Select);
00324 StrFree(_1Column);
00325
00326 _Select = StrCpy(_Select,_right_prototype->KeySelect());
00327 _Separator = "(";
00328
00329 while (
00330 StrSplit(_Select,',',_1Select)
00331 && StrSplit(_Values,',',_1Value)
00332 ) {
00333 StrPrefixCut(_1Select,'.');
00334 StrCat(_KeyCondition,6,_Separator,_tableName,".",_1Select," = ",_1Value);
00335 _Separator = ") AND (";
00336 };
00337 StrCat(_KeyCondition,")");
00338 StrFree(_Select);
00339 StrFree(_Values);
00340 StrFree(_1Select);
00341 StrFree(_1Value);
00342
00343 StrAnd(_JoinCondition,_KeyCondition);
00344 StrFree(_KeyCondition);
00345
00346 ComplexQuery CQ(
00347 _JoinCondition,
00348 NULL,
00349 _leftColumnName,
00350 StrCat(_Alias,3,_right_prototype->From()," ",_tableName)
00351 );
00352 CQ.And(query);
00353 CQ._order_by = query._OrderBy();
00354
00355 rb = _left_prototype->ExecuteQuery(CQ,_databaseConnection,1,rb);
00356
00357 #ifdef GC_REL1N_TRACE
00358 logmsg("OneToManyRelationBase::LGetAll() finished");
00359 #endif
00360
00361 return rb;
00362 };
00363
00364 ResultBase *OneToManyRelationBase::_RGetAll(
00365 ResultBase *rb,
00366 const class RefBase &left,
00367 const class QueRefProto &query
00368 )
00369
00370 {
00371 #ifdef GC_REL1N_TRACE
00372 logmsg("OneToManyRelationBase::RGetAll(...) invoked");
00373 #endif
00374
00375 if (left.IsTransient())
00376 return NULL;
00377 ProtoBase *_right_prototype=Class[_rightClassName];
00378 RefBase l = left;
00379
00380
00381
00382 char *_Columns = StrCpy(
00383 _Columns=NULL,
00384 _leftColumnName
00385 );
00386 char *_Values = l._KeyValues();
00387 char *_1Column = NULL;
00388 char *_1Value = NULL;
00389 char *_KeyCondition = NULL;
00390 char *_Separator = "(";
00391
00392 while (
00393 StrSplit(_Columns,',',_1Column)
00394 && StrSplit(_Values,',',_1Value)
00395 ) {
00396 StrCat(_KeyCondition,4,_Separator,_1Column," = ",_1Value);
00397 _Separator = ") AND (";
00398 };
00399 StrCat(_KeyCondition,")");
00400 StrFree(_Columns);
00401 StrFree(_Values);
00402 StrFree(_1Column);
00403 StrFree(_1Value);
00404
00405 ComplexQuery CQ(
00406 _KeyCondition,
00407 NULL,
00408 NULL,
00409 NULL
00410 );
00411 CQ.And(query);
00412
00413 CQ._order_by = query._OrderBy();
00414
00415 rb = _right_prototype -> ExecuteQuery(CQ,_databaseConnection,1,rb);
00416
00417 #ifdef GC_REL1N_TRACE
00418 logmsg("OneToManyRelationBase::RGetAll() finished");
00419 #endif
00420
00421 return rb;
00422 };
00423
00424 bool OneToManyRelationBase::ExistsCouple(
00425 const class RefBase &left,
00426 const class RefBase &right
00427 )
00428
00429 {
00430
00431
00432
00433
00434 bool _retval = false;
00435 ProtoBase *_right_prototype=Class[_rightClassName];
00436 RefBase l = left;
00437 RefBase r = right;
00438 int _sql_result_buffer = 0;
00439
00440 if (left.IsTransient() || right.IsTransient())
00441 return false;
00442 char *_select = StrCpy(_select = NULL, "0");
00443 StrClause(_select,"SELECT");
00444 char *_from = StrCpy(_from = NULL, _right_prototype->From());
00445 StrClause(_from, "FROM");
00446 char *_1column = NULL;
00447 char *_columns = StrCpy(_columns = NULL, _right_prototype->KeySelect());
00448 StrCat(_columns,2,", ",_leftColumnName);
00449 char *_1value = NULL;
00450 char *_values = r._KeyValues();
00451 StrCat(_values,2,", ",_1value = l._KeyValues());
00452 StrFree(_1value);
00453 char *_where = NULL;
00454 char *_separator = "(";
00455 while (StrSplit(_columns,',',_1column) && StrSplit(_values,',',_1value)) {
00456 StrPrefixCut(_1column,'.');
00457 StrCat(_where,4,_separator,_1column," = ",_1value);
00458 _separator = ") AND (";
00459 };
00460 StrCat(_where,")");
00461 StrClause(_where,"WHERE");
00462 StrFree(_columns);
00463 StrFree(_1column);
00464 StrFree(_values);
00465 StrFree(_1value);
00466 StrCat(_select,2,_from,_where);
00467 StrFree(_from);
00468 StrFree(_where);
00469 if (_databaseConnection == NULL)
00470 throw ObjLibException_ConnectionError();
00471 if (_databaseConnection -> _Open())
00472 {
00473 if (_databaseConnection -> _Prepare(_select))
00474 {
00475 if (_databaseConnection -> _Execute())
00476 {
00477 if (_databaseConnection -> _PreFetchBind(
00478 1,
00479 &_sql_result_buffer,
00480 0,
00481 'i'
00482 )
00483 )
00484 {
00485 if (_databaseConnection -> _FetchNext())
00486 {
00487 _retval = true;
00488 };
00489 };
00490 };
00491 };
00492 _databaseConnection -> _Close();
00493 };
00494 StrFree(_select);
00495 return _retval;
00496 };
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 const char *OneToManyRelationBase::_TableName() const {
00524 return Class[_rightClassName]->From();
00525 };
00526
00527
00528
00529 bool OneToManyRelationBase::WriteDDL(ofstream &S, class Database &Db)
00530
00531 {
00532 if (!S.rdbuf()->is_open())
00533 return false;
00534 ProtoBase *_left_prototype=Class[_leftClassName];
00535 ProtoBase *_right_prototype=Class[_rightClassName];
00536 char *_pk = NULL;
00537 char *_pk1 = NULL;
00538 char *_pklt = NULL;
00539 char *_fk = NULL;
00540 char *_fk1 = NULL;
00541 char *_fklt = NULL;
00542 char *typ = NULL;
00543 int c;
00544 const char *delimcols = "";
00545 const char *delimkeys = "";
00546 S << "-- One to many relation " << _tableName << " between classes " << _leftClassName << " and " << _rightClassName << endl;
00547
00548
00549 S << "ALTER TABLE " << _right_prototype->From() << " ADD(";
00550
00551 c = 0;
00552 StrCpy(_pk,_left_prototype->KeySelect());
00553 StrCpy(_fk,_leftColumnName);
00554 delimkeys = "";
00555 while (StrSplit(_fk,',',_fk1) && StrSplit(_pk,',',_pk1))
00556 {
00557 StrPrefixCut(_pk1,'.');
00558 StrPrefixCut(_fk1,'.');
00559 StrCat(_pklt,2,delimkeys,_pk1);
00560 StrCat(_fklt,2,delimkeys,_fk1);
00561 delimkeys = ",";
00562 typ = _left_prototype->ColumnTypeDDL(c,Db);
00563 S << delimcols << endl << _fk1 << " " << typ;
00564 StrFree(typ);
00565 delimcols = ",";
00566 c++;
00567 };
00568 StrFree(_pk);
00569 StrFree(_pk1);
00570 StrFree(_fk);
00571 StrFree(_fk1);
00572
00573 S << delimcols << endl << "CONSTRAINT " << _tableName << "_FK_L FOREIGN KEY(" << _fklt << ") REFERENCES " << _left_prototype->From() << "(" << _pklt << ")";
00574 delimcols = ",";
00575
00576 S << endl << ");"<< endl << endl;
00577
00578 S << "CREATE INDEX " << _tableName << "_RK_L ON " << _right_prototype->From() << "(" << _fklt << ");" << endl << endl;
00579 S.flush();
00580 StrFree(_pklt);
00581 StrFree(_fklt);
00582 return true;
00583 };