| 1 | /************ TabOccur CPP Declares Source Code File (.CPP) ************/ |
| 2 | /* Name: TABOCCUR.CPP Version 1.2 */ |
| 3 | /* */ |
| 4 | /* (C) Copyright to the author Olivier BERTRAND 2013 - 2017 */ |
| 5 | /* */ |
| 6 | /* OCCUR: Table that provides a view of a source table where the */ |
| 7 | /* contain of several columns of the source table is placed in only */ |
| 8 | /* one column, the OCCUR column, this resulting into several rows. */ |
| 9 | /***********************************************************************/ |
| 10 | |
| 11 | /***********************************************************************/ |
| 12 | /* Include relevant section of system dependant header files. */ |
| 13 | /***********************************************************************/ |
| 14 | #include "my_global.h" |
| 15 | #include "table.h" // MySQL table definitions |
| 16 | #if defined(__WIN__) |
| 17 | #include <stdlib.h> |
| 18 | #include <stdio.h> |
| 19 | #if defined(__BORLANDC__) |
| 20 | #define __MFC_COMPAT__ // To define min/max as macro |
| 21 | #endif |
| 22 | //#include <windows.h> |
| 23 | #else |
| 24 | #if defined(UNIX) |
| 25 | #include <fnmatch.h> |
| 26 | #include <errno.h> |
| 27 | #include <stdlib.h> |
| 28 | #include <stdio.h> |
| 29 | #include <string.h> |
| 30 | #include "osutil.h" |
| 31 | #else |
| 32 | //#include <io.h> |
| 33 | #endif |
| 34 | //#include <fcntl.h> |
| 35 | #endif |
| 36 | |
| 37 | /***********************************************************************/ |
| 38 | /* Include application header files: */ |
| 39 | /***********************************************************************/ |
| 40 | #include "global.h" |
| 41 | #include "plgdbsem.h" |
| 42 | #include "xtable.h" |
| 43 | #include "tabext.h" |
| 44 | //#include "reldef.h" |
| 45 | #include "filamtxt.h" |
| 46 | #include "tabdos.h" |
| 47 | #include "tabcol.h" |
| 48 | #include "taboccur.h" |
| 49 | #include "tabmysql.h" |
| 50 | #include "ha_connect.h" |
| 51 | |
| 52 | /***********************************************************************/ |
| 53 | /* Prepare and count columns in the column list. */ |
| 54 | /***********************************************************************/ |
| 55 | static int PrepareColist(char *colist) |
| 56 | { |
| 57 | char *p, *pn; |
| 58 | int n = 0; |
| 59 | |
| 60 | // Count the number of columns and change separator into null char |
| 61 | for (pn = colist; ; pn += (strlen(pn) + 1)) |
| 62 | // Separator can be ; if colist was specified in the option_list |
| 63 | if ((p = strchr(pn, ',')) || (p = strchr(pn, ';'))) { |
| 64 | *p++ = '\0'; |
| 65 | n++; |
| 66 | } else { |
| 67 | if (*pn) |
| 68 | n++; |
| 69 | |
| 70 | break; |
| 71 | } // endif p |
| 72 | |
| 73 | return n; |
| 74 | } // end of PrepareColist |
| 75 | |
| 76 | /************************************************************************/ |
| 77 | /* OcrColumns: constructs the result blocks containing all the columns */ |
| 78 | /* of the object table that will be retrieved by GetData commands. */ |
| 79 | /************************************************************************/ |
| 80 | bool OcrColumns(PGLOBAL g, PQRYRES qrp, const char *col, |
| 81 | const char *ocr, const char *rank) |
| 82 | { |
| 83 | char *pn, *colist; |
| 84 | int i, k, m, n = 0, c = 0, j = qrp->Nblin; |
| 85 | bool rk, b = false; |
| 86 | PCOLRES crp; |
| 87 | |
| 88 | if (!col || !*col) { |
| 89 | strcpy(g->Message, "Missing colist" ); |
| 90 | return true; |
| 91 | } // endif col |
| 92 | |
| 93 | // Prepare the column list |
| 94 | colist = PlugDup(g, col); |
| 95 | m = PrepareColist(colist); |
| 96 | |
| 97 | if ((rk = (rank && *rank))) { |
| 98 | if (m == 1) { |
| 99 | strcpy(g->Message, "Cannot handle one column colist and rank" ); |
| 100 | return true; |
| 101 | } // endif m |
| 102 | |
| 103 | for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1)) |
| 104 | n = MY_MAX(n, (signed)strlen(pn)); |
| 105 | |
| 106 | } // endif k |
| 107 | |
| 108 | // Default occur column name is the 1st colist column name |
| 109 | if (!ocr || !*ocr) |
| 110 | ocr = colist; |
| 111 | |
| 112 | /**********************************************************************/ |
| 113 | /* Replace the columns of the colist by the rank and occur columns. */ |
| 114 | /**********************************************************************/ |
| 115 | for (i = 0; i < qrp->Nblin; i++) { |
| 116 | for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1)) |
| 117 | if (!stricmp(pn, qrp->Colresp->Kdata->GetCharValue(i))) |
| 118 | break; |
| 119 | |
| 120 | if (k < m) { |
| 121 | // This column belongs to colist |
| 122 | if (rk) { |
| 123 | // Place the rank column here |
| 124 | for (crp = qrp->Colresp; crp; crp = crp->Next) |
| 125 | switch (crp->Fld) { |
| 126 | case FLD_NAME: crp->Kdata->SetValue((char*)rank, i); break; |
| 127 | case FLD_TYPE: crp->Kdata->SetValue(TYPE_STRING, i); break; |
| 128 | case FLD_PREC: crp->Kdata->SetValue(n, i); break; |
| 129 | case FLD_SCALE: crp->Kdata->SetValue(0, i); break; |
| 130 | case FLD_NULL: crp->Kdata->SetValue(0, i); break; |
| 131 | case FLD_REM: crp->Kdata->Reset(i); break; |
| 132 | default: ; // Ignored by CONNECT |
| 133 | } // endswich Fld |
| 134 | |
| 135 | rk = false; |
| 136 | } else if (!b) { |
| 137 | // First remaining listed column, will be the occur column |
| 138 | for (crp = qrp->Colresp; crp; crp = crp->Next) |
| 139 | switch (crp->Fld) { |
| 140 | case FLD_NAME: crp->Kdata->SetValue((char*)ocr, i); break; |
| 141 | case FLD_REM: crp->Kdata->Reset(i); break; |
| 142 | default: ; // Nothing to do |
| 143 | } // endswich Fld |
| 144 | |
| 145 | b = true; |
| 146 | } else if (j == qrp->Nblin) |
| 147 | j = i; // Column to remove |
| 148 | |
| 149 | c++; |
| 150 | } else if (j < i) { |
| 151 | // Move this column in empty spot |
| 152 | for (crp = qrp->Colresp; crp; crp = crp->Next) |
| 153 | crp->Kdata->Move(i, j); |
| 154 | |
| 155 | j++; |
| 156 | } // endif k |
| 157 | |
| 158 | } // endfor i |
| 159 | |
| 160 | // Check whether all columns of the list where found |
| 161 | if (c < m) { |
| 162 | strcpy(g->Message, "Some colist columns are not in the source table" ); |
| 163 | return true; |
| 164 | } // endif crp |
| 165 | |
| 166 | /**********************************************************************/ |
| 167 | /* Set the number of columns of the table. */ |
| 168 | /**********************************************************************/ |
| 169 | qrp->Nblin = j; |
| 170 | return false; |
| 171 | } // end of OcrColumns |
| 172 | |
| 173 | /************************************************************************/ |
| 174 | /* OcrSrcCols: constructs the result blocks containing all the columns */ |
| 175 | /* of the object table that will be retrieved by GetData commands. */ |
| 176 | /************************************************************************/ |
| 177 | bool OcrSrcCols(PGLOBAL g, PQRYRES qrp, const char *col, |
| 178 | const char *ocr, const char *rank) |
| 179 | { |
| 180 | char *pn, *colist; |
| 181 | int i, k, m, n = 0, c = 0; |
| 182 | bool rk, b = false; |
| 183 | PCOLRES crp, rcrp, *pcrp; |
| 184 | |
| 185 | if (!col || !*col) { |
| 186 | strcpy(g->Message, "Missing colist" ); |
| 187 | return true; |
| 188 | } // endif col |
| 189 | |
| 190 | // Prepare the column list |
| 191 | colist = PlugDup(g, col); |
| 192 | m = PrepareColist(colist); |
| 193 | |
| 194 | if ((rk = (rank && *rank))) |
| 195 | for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1)) |
| 196 | n = MY_MAX(n, (signed)strlen(pn)); |
| 197 | |
| 198 | // Default occur column name is the 1st colist column name |
| 199 | if (!ocr || !*ocr) |
| 200 | ocr = colist; |
| 201 | |
| 202 | /**********************************************************************/ |
| 203 | /* Replace the columns of the colist by the rank and occur columns. */ |
| 204 | /**********************************************************************/ |
| 205 | for (i = 0, pcrp = &qrp->Colresp; crp = *pcrp; ) { |
| 206 | for (k = 0, pn = colist; k < m; k++, pn += (strlen(pn) + 1)) |
| 207 | if (!stricmp(pn, crp->Name)) |
| 208 | break; |
| 209 | |
| 210 | if (k < m) { |
| 211 | // This column belongs to colist |
| 212 | c++; |
| 213 | |
| 214 | if (!b) { |
| 215 | if (rk) { |
| 216 | // Add the rank column here |
| 217 | rcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); |
| 218 | memset(rcrp, 0, sizeof(COLRES)); |
| 219 | rcrp->Next = crp; |
| 220 | rcrp->Name = (char*)rank; |
| 221 | rcrp->Type = TYPE_STRING; |
| 222 | rcrp->Length = n; |
| 223 | rcrp->Ncol = ++i; |
| 224 | *pcrp = rcrp; |
| 225 | } // endif rk |
| 226 | |
| 227 | // First remaining listed column, will be the occur column |
| 228 | crp->Name = (char*)ocr; |
| 229 | b = true; |
| 230 | } else { |
| 231 | *pcrp = crp->Next; // Remove this column |
| 232 | continue; |
| 233 | } // endif b |
| 234 | |
| 235 | } // endif k |
| 236 | |
| 237 | crp->Ncol = ++i; |
| 238 | pcrp = &crp->Next; |
| 239 | } // endfor pcrp |
| 240 | |
| 241 | // Check whether all columns of the list where found |
| 242 | if (c < m) { |
| 243 | strcpy(g->Message, "Some colist columns are not in the source table" ); |
| 244 | return true; |
| 245 | } // endif crp |
| 246 | |
| 247 | /**********************************************************************/ |
| 248 | /* Set the number of columns of the table. */ |
| 249 | /**********************************************************************/ |
| 250 | qrp->Nblin = i; |
| 251 | return false; |
| 252 | } // end of OcrSrcCols |
| 253 | |
| 254 | /* -------------- Implementation of the OCCUR classes ---------------- */ |
| 255 | |
| 256 | /***********************************************************************/ |
| 257 | /* DefineAM: define specific AM block values from OCCUR table. */ |
| 258 | /***********************************************************************/ |
| 259 | bool OCCURDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) |
| 260 | { |
| 261 | Rcol = GetStringCatInfo(g, "RankCol" , "" ); |
| 262 | Colist = GetStringCatInfo(g, "Colist" , "" ); |
| 263 | Xcol = GetStringCatInfo(g, "OccurCol" , Colist); |
| 264 | return PRXDEF::DefineAM(g, am, poff); |
| 265 | } // end of DefineAM |
| 266 | |
| 267 | /***********************************************************************/ |
| 268 | /* GetTable: makes a new TDB of the proper type. */ |
| 269 | /***********************************************************************/ |
| 270 | PTDB OCCURDEF::GetTable(PGLOBAL g, MODE) |
| 271 | { |
| 272 | if (Catfunc != FNC_COL) |
| 273 | return new(g) TDBOCCUR(this); |
| 274 | else |
| 275 | return new(g) TDBTBC(this); |
| 276 | |
| 277 | } // end of GetTable |
| 278 | |
| 279 | /* ------------------------------------------------------------------- */ |
| 280 | |
| 281 | /***********************************************************************/ |
| 282 | /* Implementation of the TDBOCCUR class. */ |
| 283 | /***********************************************************************/ |
| 284 | TDBOCCUR::TDBOCCUR(POCCURDEF tdp) : TDBPRX(tdp) |
| 285 | { |
| 286 | //Tdbp = NULL; // Source table (in TDBPRX) |
| 287 | Tabname = tdp->Tablep->GetName(); // Name of source table |
| 288 | Colist = tdp->Colist; // List of source columns |
| 289 | Xcolumn = tdp->Xcol; // Occur column name |
| 290 | Rcolumn = tdp->Rcol; // Rank column name |
| 291 | Xcolp = NULL; // To the OCCURCOL column |
| 292 | Col = NULL; // To source column blocks array |
| 293 | Mult = PrepareColist(Colist); // Multiplication factor |
| 294 | N = 0; // The current table index |
| 295 | M = 0; // The occurence rank |
| 296 | RowFlag = 0; // 0: Ok, 1: Same, 2: Skip |
| 297 | } // end of TDBOCCUR constructor |
| 298 | |
| 299 | /***********************************************************************/ |
| 300 | /* Allocate OCCUR/SRC column description block. */ |
| 301 | /***********************************************************************/ |
| 302 | PCOL TDBOCCUR::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) |
| 303 | { |
| 304 | PCOL colp = NULL; |
| 305 | |
| 306 | if (!stricmp(cdp->GetName(), Rcolumn)) { |
| 307 | // Allocate a RANK column |
| 308 | colp = new(g) RANKCOL(cdp, this, n); |
| 309 | } else if (!stricmp(cdp->GetName(), Xcolumn)) { |
| 310 | // Allocate the OCCUR column |
| 311 | colp = Xcolp = new(g) OCCURCOL(cdp, this, n); |
| 312 | } else |
| 313 | return new(g) PRXCOL(cdp, this, cprec, n); |
| 314 | |
| 315 | if (cprec) { |
| 316 | colp->SetNext(cprec->GetNext()); |
| 317 | cprec->SetNext(colp); |
| 318 | } else { |
| 319 | colp->SetNext(Columns); |
| 320 | Columns = colp; |
| 321 | } // endif cprec |
| 322 | |
| 323 | return colp; |
| 324 | } // end of MakeCol |
| 325 | |
| 326 | /***********************************************************************/ |
| 327 | /* Initializes the table. */ |
| 328 | /***********************************************************************/ |
| 329 | bool TDBOCCUR::InitTable(PGLOBAL g) |
| 330 | { |
| 331 | if (!Tdbp) |
| 332 | // Get the table description block of this table |
| 333 | if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE))) |
| 334 | return TRUE; |
| 335 | |
| 336 | if (!Tdbp->IsView()) |
| 337 | if (MakeColumnList(g)) |
| 338 | return TRUE; |
| 339 | |
| 340 | return FALSE; |
| 341 | } // end of InitTable |
| 342 | |
| 343 | /***********************************************************************/ |
| 344 | /* Allocate OCCUR column description block. */ |
| 345 | /***********************************************************************/ |
| 346 | bool TDBOCCUR::MakeColumnList(PGLOBAL g) |
| 347 | { |
| 348 | char *pn; |
| 349 | int i; |
| 350 | PCOL colp; |
| 351 | |
| 352 | for (colp = Columns; colp; colp = colp->GetNext()) |
| 353 | if (colp->GetAmType() == TYPE_AM_PRX) |
| 354 | if (((PPRXCOL)colp)->Init(g, NULL)) |
| 355 | return true; |
| 356 | |
| 357 | Col = (PCOL*)PlugSubAlloc(g, NULL, Mult * sizeof(PCOL)); |
| 358 | |
| 359 | for (i = 0, pn = Colist; i < Mult; i++, pn += (strlen(pn) + 1)) { |
| 360 | if (!(Col[i] = Tdbp->ColDB(g, pn, 0))) { |
| 361 | // Column not found in table |
| 362 | sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname); |
| 363 | return true; |
| 364 | } // endif Col |
| 365 | |
| 366 | if (Col[i]->InitValue(g)) { |
| 367 | strcpy(g->Message, "OCCUR InitValue failed" ); |
| 368 | return true; |
| 369 | } // endif InitValue |
| 370 | |
| 371 | } // endfor i |
| 372 | |
| 373 | return false; |
| 374 | } // end of MakeColumnList |
| 375 | |
| 376 | /***********************************************************************/ |
| 377 | /* Allocate OCCUR column description block for a view. */ |
| 378 | /***********************************************************************/ |
| 379 | bool TDBOCCUR::ViewColumnList(PGLOBAL g) |
| 380 | { |
| 381 | char *pn; |
| 382 | int i; |
| 383 | PCOL colp, cp; |
| 384 | PTDBMY tdbp; |
| 385 | |
| 386 | if (!Tdbp->IsView()) |
| 387 | return false; |
| 388 | |
| 389 | if (Tdbp->GetAmType() != TYPE_AM_MYSQL) { |
| 390 | strcpy(g->Message, "View is not MySQL" ); |
| 391 | return true; |
| 392 | } else |
| 393 | tdbp = (PTDBMY)Tdbp; |
| 394 | |
| 395 | for (cp = Columns; cp; cp = cp->GetNext()) |
| 396 | if (cp->GetAmType() == TYPE_AM_PRX) { |
| 397 | if ((colp = tdbp->MakeFieldColumn(g, cp->GetName()))) { |
| 398 | ((PPRXCOL)cp)->Colp = colp; |
| 399 | ((PPRXCOL)cp)->To_Val = colp->GetValue(); |
| 400 | } else |
| 401 | return true; |
| 402 | |
| 403 | } // endif Type |
| 404 | |
| 405 | Col = (PCOL*)PlugSubAlloc(g, NULL, Mult * sizeof(PCOL)); |
| 406 | |
| 407 | for (i = 0, pn = Colist; i < Mult; i++, pn += (strlen(pn) + 1)) |
| 408 | if (!(Col[i] = tdbp->MakeFieldColumn(g, pn))) { |
| 409 | // Column not found in table |
| 410 | sprintf(g->Message, MSG(COL_ISNOT_TABLE), pn, Tabname); |
| 411 | return true; |
| 412 | } // endif Col |
| 413 | |
| 414 | return false; |
| 415 | } // end of ViewColumnList |
| 416 | |
| 417 | /***********************************************************************/ |
| 418 | /* OCCUR GetMaxSize: returns the maximum number of rows in the table. */ |
| 419 | /***********************************************************************/ |
| 420 | int TDBOCCUR::GetMaxSize(PGLOBAL g) |
| 421 | { |
| 422 | if (MaxSize < 0) { |
| 423 | if (!(Tdbp = GetSubTable(g, ((POCCURDEF)To_Def)->Tablep, TRUE))) |
| 424 | return 0; |
| 425 | |
| 426 | MaxSize = Mult * Tdbp->GetMaxSize(g); |
| 427 | } // endif MaxSize |
| 428 | |
| 429 | return MaxSize; |
| 430 | } // end of GetMaxSize |
| 431 | |
| 432 | /***********************************************************************/ |
| 433 | /* In this sample, ROWID will be the (virtual) row number, */ |
| 434 | /* while ROWNUM will be the occurence rank in the multiple column. */ |
| 435 | /***********************************************************************/ |
| 436 | int TDBOCCUR::RowNumber(PGLOBAL, bool b) |
| 437 | { |
| 438 | return (b) ? M : N; |
| 439 | } // end of RowNumber |
| 440 | |
| 441 | /***********************************************************************/ |
| 442 | /* OCCUR Access Method opening routine. */ |
| 443 | /***********************************************************************/ |
| 444 | bool TDBOCCUR::OpenDB(PGLOBAL g) |
| 445 | { |
| 446 | if (Use == USE_OPEN) { |
| 447 | /*******************************************************************/ |
| 448 | /* Table already open, just replace it at its beginning. */ |
| 449 | /*******************************************************************/ |
| 450 | N = M = 0; |
| 451 | RowFlag = 0; |
| 452 | |
| 453 | if (Xcolp) |
| 454 | Xcolp->Xreset(); |
| 455 | |
| 456 | return Tdbp->OpenDB(g); |
| 457 | } // endif use |
| 458 | |
| 459 | |
| 460 | if (Mode != MODE_READ) { |
| 461 | /*******************************************************************/ |
| 462 | /* Currently OCCUR tables cannot be modified. */ |
| 463 | /*******************************************************************/ |
| 464 | strcpy(g->Message, "OCCUR tables are read only" ); |
| 465 | return TRUE; |
| 466 | } // endif Mode |
| 467 | |
| 468 | /*********************************************************************/ |
| 469 | /* Do it here if not done yet. */ |
| 470 | /*********************************************************************/ |
| 471 | if (InitTable(g)) |
| 472 | return TRUE; |
| 473 | |
| 474 | if (Xcolp) |
| 475 | // Lock this column so it is evaluated by its table only |
| 476 | Xcolp->AddStatus(BUF_READ); |
| 477 | |
| 478 | if (To_Key_Col || To_Kindex) { |
| 479 | /*******************************************************************/ |
| 480 | /* Direct access of OCCUR tables is not implemented yet. */ |
| 481 | /*******************************************************************/ |
| 482 | strcpy(g->Message, "No direct access to OCCUR tables" ); |
| 483 | return TRUE; |
| 484 | } // endif To_Key_Col |
| 485 | |
| 486 | /*********************************************************************/ |
| 487 | /* Do open the source table. */ |
| 488 | /*********************************************************************/ |
| 489 | if (Tdbp->OpenDB(g)) |
| 490 | return TRUE; |
| 491 | |
| 492 | Use = USE_OPEN; |
| 493 | return ViewColumnList(g); |
| 494 | } // end of OpenDB |
| 495 | |
| 496 | /***********************************************************************/ |
| 497 | /* Data Base read routine for OCCUR access method. */ |
| 498 | /***********************************************************************/ |
| 499 | int TDBOCCUR::ReadDB(PGLOBAL g) |
| 500 | { |
| 501 | int rc = RC_OK; |
| 502 | |
| 503 | /*********************************************************************/ |
| 504 | /* Now start the multi reading process. */ |
| 505 | /*********************************************************************/ |
| 506 | do { |
| 507 | if (RowFlag != 1) |
| 508 | if ((rc = Tdbp->ReadDB(g)) != RC_OK) |
| 509 | break; |
| 510 | |
| 511 | if (Xcolp) { |
| 512 | RowFlag = 0; |
| 513 | Xcolp->ReadColumn(g); |
| 514 | M = Xcolp->GetI(); |
| 515 | } // endif Xcolp |
| 516 | |
| 517 | } while (RowFlag == 2); |
| 518 | |
| 519 | N++; |
| 520 | return rc; |
| 521 | } // end of ReadDB |
| 522 | |
| 523 | // ------------------------ OCCURCOL functions ---------------------------- |
| 524 | |
| 525 | /***********************************************************************/ |
| 526 | /* OCCURCOL public constructor. */ |
| 527 | /***********************************************************************/ |
| 528 | OCCURCOL::OCCURCOL(PCOLDEF cdp, PTDBOCCUR tdbp, int n) |
| 529 | : COLBLK(cdp, tdbp, n) |
| 530 | { |
| 531 | // Set additional OCCUR access method information for column. |
| 532 | I = 0; |
| 533 | } // end of OCCURCOL constructor |
| 534 | |
| 535 | /***********************************************************************/ |
| 536 | /* ReadColumn: what this routine does is to access the columns of */ |
| 537 | /* list, extract their value and convert it to buffer type. */ |
| 538 | /***********************************************************************/ |
| 539 | void OCCURCOL::ReadColumn(PGLOBAL g) |
| 540 | { |
| 541 | PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb; |
| 542 | PCOL *col = tdbp->Col; |
| 543 | |
| 544 | for (; I < tdbp->Mult; I++) { |
| 545 | col[I]->ReadColumn(g); |
| 546 | |
| 547 | if (Nullable || !col[I]->GetValue()->IsZero()) |
| 548 | break; |
| 549 | |
| 550 | } // endfor I |
| 551 | |
| 552 | if (I == tdbp->Mult) { |
| 553 | // No more values, go to next source row |
| 554 | tdbp->RowFlag = 2; |
| 555 | I = 0; |
| 556 | return; |
| 557 | } // endif I |
| 558 | |
| 559 | // Set the OCCUR column value from the Ith source column value |
| 560 | Value->SetValue_pval(col[I++]->GetValue()); |
| 561 | tdbp->RowFlag = 1; |
| 562 | } // end of ReadColumn |
| 563 | |
| 564 | |
| 565 | // ------------------------ RANKCOL functions --------------------------- |
| 566 | |
| 567 | /***********************************************************************/ |
| 568 | /* ReadColumn: what this routine does is to access the Mth columns of */ |
| 569 | /* list, extract its name and set to it the rank column value. */ |
| 570 | /***********************************************************************/ |
| 571 | void RANKCOL::ReadColumn(PGLOBAL) |
| 572 | { |
| 573 | PTDBOCCUR tdbp = (PTDBOCCUR)To_Tdb; |
| 574 | PCOL *col = tdbp->Col; |
| 575 | |
| 576 | // Set the RANK column value from the Mth source column name |
| 577 | if (tdbp->M) |
| 578 | Value->SetValue_psz(col[tdbp->M - 1]->GetName()); |
| 579 | else { |
| 580 | Value->Reset(); |
| 581 | |
| 582 | if (Nullable) |
| 583 | Value->SetNull(true); |
| 584 | |
| 585 | } // endelse |
| 586 | |
| 587 | } // end of ReadColumn |
| 588 | |