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