1/************* RelDef CPP Program Source Code File (.CPP) **************/
2/* PROGRAM NAME: RELDEF */
3/* ------------- */
4/* Version 1.6 */
5/* */
6/* COPYRIGHT: */
7/* ---------- */
8/* (C) Copyright to the author Olivier BERTRAND 2004-2016 */
9/* */
10/* WHAT THIS PROGRAM DOES: */
11/* ----------------------- */
12/* This program are the DB definition related routines. */
13/* */
14/***********************************************************************/
15
16/***********************************************************************/
17/* Include relevant MariaDB header file. */
18/***********************************************************************/
19#include "my_global.h"
20#if defined(__WIN__)
21#include <sqlext.h>
22#else
23#include <dlfcn.h> // dlopen(), dlclose(), dlsym() ...
24#include "osutil.h"
25//#include "sqlext.h"
26#endif
27#include "handler.h"
28
29/***********************************************************************/
30/* Include application header files */
31/* */
32/* global.h is header containing all global declarations. */
33/* plgdbsem.h is header containing DB application declarations. */
34/* catalog.h is header containing DB description declarations. */
35/***********************************************************************/
36#include "global.h"
37#include "plgdbsem.h"
38#include "reldef.h"
39#include "colblk.h"
40#include "tabcol.h"
41#include "filamap.h"
42#include "filamfix.h"
43#if defined(VCT_SUPPORT)
44#include "filamvct.h"
45#endif // VCT_SUPPORT
46#if defined(GZ_SUPPORT)
47#include "filamgz.h"
48#endif // GZ_SUPPORT
49#include "tabdos.h"
50#include "valblk.h"
51#include "tabmul.h"
52#include "ha_connect.h"
53#include "mycat.h"
54
55#if !defined(__WIN__)
56extern handlerton *connect_hton;
57#endif // !__WIN__
58
59/***********************************************************************/
60/* External function. */
61/***********************************************************************/
62USETEMP UseTemp(void);
63char *GetPluginDir(void);
64
65/* --------------------------- Class RELDEF -------------------------- */
66
67/***********************************************************************/
68/* RELDEF Constructor. */
69/***********************************************************************/
70RELDEF::RELDEF(void)
71 {
72 Next = NULL;
73 To_Cols = NULL;
74 Name = NULL;
75 Database = NULL;
76 Cat = NULL;
77 Hc = NULL;
78 } // end of RELDEF constructor
79
80/***********************************************************************/
81/* This function return a pointer to the Table Option Struct. */
82/***********************************************************************/
83PTOS RELDEF::GetTopt(void)
84 {
85 return Hc->GetTableOptionStruct();
86 } // end of GetTopt
87
88/***********************************************************************/
89/* This function sets an integer table information. */
90/***********************************************************************/
91bool RELDEF::SetIntCatInfo(PCSZ what, int n)
92 {
93 return Hc->SetIntegerOption(what, n);
94 } // end of SetIntCatInfo
95
96/***********************************************************************/
97/* This function returns integer table information. */
98/***********************************************************************/
99int RELDEF::GetIntCatInfo(PCSZ what, int idef)
100 {
101 int n= Hc->GetIntegerOption(what);
102
103 return (n == NO_IVAL) ? idef : n;
104 } // end of GetIntCatInfo
105
106/***********************************************************************/
107/* This function returns Boolean table information. */
108/***********************************************************************/
109bool RELDEF::GetBoolCatInfo(PCSZ what, bool bdef)
110 {
111 bool b= Hc->GetBooleanOption(what, bdef);
112
113 return b;
114 } // end of GetBoolCatInfo
115
116/***********************************************************************/
117/* This function returns size catalog information. */
118/***********************************************************************/
119int RELDEF::GetSizeCatInfo(PCSZ what, PCSZ sdef)
120 {
121 char c;
122 PCSZ s;
123 int i, n= 0;
124
125 if (!(s= Hc->GetStringOption(what)))
126 s= sdef;
127
128 if ((i= sscanf(s, " %d %c ", &n, &c)) == 2)
129 switch (toupper(c)) {
130 case 'M':
131 n *= 1024;
132 // fall through
133 case 'K':
134 n *= 1024;
135 } // endswitch c
136
137 return n;
138} // end of GetSizeCatInfo
139
140/***********************************************************************/
141/* This function sets char table information in buf. */
142/***********************************************************************/
143int RELDEF::GetCharCatInfo(PCSZ what, PCSZ sdef, char *buf, int size)
144 {
145 PCSZ s= Hc->GetStringOption(what);
146
147 strncpy(buf, ((s) ? s : sdef), size);
148 return size;
149 } // end of GetCharCatInfo
150
151/***********************************************************************/
152/* To be used by any TDB's. */
153/***********************************************************************/
154bool RELDEF::Partitioned(void)
155 {
156 return Hc->IsPartitioned();
157 } // end of Partitioned
158
159/***********************************************************************/
160/* This function returns string table information. */
161/* Default parameter is "*" to get the handler default. */
162/***********************************************************************/
163char *RELDEF::GetStringCatInfo(PGLOBAL g, PCSZ what, PCSZ sdef)
164 {
165 char *sval = NULL;
166 PCSZ name, s= Hc->GetStringOption(what, sdef);
167
168 if (s) {
169 if (!Hc->IsPartitioned() ||
170 (stricmp(what, "filename") && stricmp(what, "tabname")
171 && stricmp(what, "connect")))
172 sval= PlugDup(g, s);
173 else
174 sval= (char*)s;
175
176 } else if (!stricmp(what, "filename")) {
177 // Return default file name
178 PCSZ ftype= Hc->GetStringOption("Type", "*");
179 int i, n;
180
181 if (IsFileType(GetTypeID(ftype))) {
182 name= Hc->GetPartName();
183 sval= (char*)PlugSubAlloc(g, NULL, strlen(name) + 12);
184 strcat(strcpy(sval, name), ".");
185 n= strlen(sval);
186
187 // Fold ftype to lower case
188 for (i= 0; i < 12; i++)
189 if (!ftype[i]) {
190 sval[n+i]= 0;
191 break;
192 } else
193 sval[n+i]= tolower(ftype[i]);
194
195 } // endif FileType
196
197 } // endif s
198
199 return sval;
200 } // end of GetStringCatInfo
201
202/* --------------------------- Class TABDEF -------------------------- */
203
204/***********************************************************************/
205/* TABDEF Constructor. */
206/***********************************************************************/
207TABDEF::TABDEF(void)
208 {
209 Schema = NULL;
210 Desc = NULL;
211 Catfunc = FNC_NO;
212 Card = 0;
213 Elemt = 0;
214 Sort = 0;
215 Multiple = 0;
216 Degree = 0;
217 Pseudo = 0;
218 Read_Only = false;
219 m_data_charset = NULL;
220 csname = NULL;
221 } // end of TABDEF constructor
222
223/***********************************************************************/
224/* Define: initialize the table definition block from XDB file. */
225/***********************************************************************/
226bool TABDEF::Define(PGLOBAL g, PCATLG cat,
227 LPCSTR name, LPCSTR schema, LPCSTR am)
228 {
229 int poff = 0;
230
231 Hc = ((MYCAT*)cat)->GetHandler();
232 Name = (PSZ)name;
233 Schema = (PSZ)Hc->GetDBName(schema);
234 Cat = cat;
235 Catfunc = GetFuncID(GetStringCatInfo(g, "Catfunc", NULL));
236 Elemt = GetIntCatInfo("Elements", 0);
237 Multiple = GetIntCatInfo("Multiple", 0);
238 Degree = GetIntCatInfo("Degree", 0);
239 Read_Only = GetBoolCatInfo("ReadOnly", false);
240 const char *data_charset_name= GetStringCatInfo(g, "Data_charset", NULL);
241 m_data_charset= data_charset_name ?
242 get_charset_by_csname(data_charset_name, MY_CS_PRIMARY, 0):
243 NULL;
244 csname = GetStringCatInfo(g, "Table_charset", NULL);
245
246 // Get The column definitions
247 if ((poff = GetColCatInfo(g)) < 0)
248 return true;
249
250 // Do the definition of AM specific fields
251 return DefineAM(g, am, poff);
252 } // end of Define
253
254/***********************************************************************/
255/* This function returns the database data path. */
256/***********************************************************************/
257PCSZ TABDEF::GetPath(void)
258 {
259 return (Database) ? Database : (Hc) ? Hc->GetDataPath() : NULL;
260 } // end of GetPath
261
262/***********************************************************************/
263/* This function returns column table information. */
264/***********************************************************************/
265int TABDEF::GetColCatInfo(PGLOBAL g)
266 {
267 char *type= GetStringCatInfo(g, "Type", "*");
268 char c, fty, eds;
269 int i, n, loff, poff, nof, nlg;
270 void *field= NULL;
271 TABTYPE tc;
272 PCOLDEF cdp, lcdp= NULL, tocols= NULL;
273 PCOLINFO pcf= (PCOLINFO)PlugSubAlloc(g, NULL, sizeof(COLINFO));
274
275 memset(pcf, 0, sizeof(COLINFO));
276
277 // Get a unique char identifier for type
278 tc= (Catfunc == FNC_NO) ? GetTypeID(type) : TAB_PRX;
279
280 // Take care of the column definitions
281 i= poff= nof= nlg= 0;
282
283#if defined(__WIN__)
284 // Offsets of HTML and DIR tables start from 0, DBF at 1
285 loff= (tc == TAB_DBF) ? 1 : (tc == TAB_XML || tc == TAB_DIR) ? -1 : 0;
286#else // !__WIN__
287 // Offsets of HTML tables start from 0, DIR and DBF at 1
288 loff = (tc == TAB_DBF || tc == TAB_DIR) ? 1 : (tc == TAB_XML) ? -1 : 0;
289#endif // !__WIN__
290
291 while (true) {
292 // Default Offset depends on table type
293 switch (tc) {
294 case TAB_DOS:
295 case TAB_FIX:
296 case TAB_BIN:
297 case TAB_VEC:
298 case TAB_DBF:
299 poff= loff + nof; // Default next offset
300 nlg= MY_MAX(nlg, poff); // Default lrecl
301 break;
302 case TAB_CSV:
303 case TAB_FMT:
304 nlg+= nof;
305 case TAB_DIR:
306 case TAB_XML:
307 poff= loff + (pcf->Flags & U_VIRTUAL ? 0 : 1);
308 break;
309 case TAB_INI:
310 case TAB_MAC:
311 case TAB_TBL:
312 case TAB_XCL:
313 case TAB_OCCUR:
314 case TAB_PRX:
315 case TAB_OEM:
316 poff = 0; // Offset represents an independant flag
317 break;
318 default: // VCT PLG ODBC JDBC MYSQL WMI...
319 poff = 0; // NA
320 break;
321 } // endswitch tc
322
323// do {
324 field= Hc->GetColumnOption(g, field, pcf);
325// } while (field && (*pcf->Name =='*' /*|| pcf->Flags & U_VIRTUAL*/));
326
327 if (tc == TAB_DBF && pcf->Type == TYPE_DATE && !pcf->Datefmt) {
328 // DBF date format defaults to 'YYYMMDD'
329 pcf->Datefmt= "YYYYMMDD";
330 pcf->Length= 8;
331 } // endif tc
332
333 if (!field)
334 break;
335
336 // Allocate the column description block
337 cdp= new(g) COLDEF;
338
339 if ((nof= cdp->Define(g, NULL, pcf, poff)) < 0)
340 return -1; // Error, probably unhandled type
341 else
342 loff= cdp->GetOffset();
343
344 switch (tc) {
345 case TAB_VEC:
346 cdp->SetOffset(0); // Not to have shift
347 case TAB_BIN:
348 // BIN/VEC are packed by default
349 if (nof) {
350 // Field width is the internal representation width
351 // that can also depend on the column format
352 fty = cdp->Decode ? 'C' : 'X';
353 eds = 0;
354 n = 0;
355
356 if (cdp->Fmt && !cdp->Decode) {
357 for (i = 0; cdp->Fmt[i]; i++) {
358 c = toupper(cdp->Fmt[i]);
359
360 if (isdigit(c))
361 n = (n * 10 + (c - '0'));
362 else if (c == 'L' || c == 'B' || c == 'H')
363 eds = c;
364 else
365 fty = c;
366
367 } // endfor i
368
369 } // endif Fmt
370
371 if (n)
372 nof = n;
373 else switch (fty) {
374 case 'X':
375 if (eds && IsTypeChar(cdp->Buf_Type))
376 nof = sizeof(longlong);
377 else
378 nof= cdp->Clen;
379
380 break;
381 case 'C': break;
382 case 'R':
383 case 'F': nof = sizeof(float); break;
384 case 'I': nof = sizeof(int); break;
385 case 'D': nof = sizeof(double); break;
386 case 'S': nof = sizeof(short); break;
387 case 'T': nof = sizeof(char); break;
388 case 'G': nof = sizeof(longlong); break;
389 default: /* Wrong format */
390 sprintf(g->Message, "Invalid format %c", fty);
391 return -1;
392 } // endswitch fty
393
394 } // endif nof
395
396 default:
397 break;
398 } // endswitch tc
399
400 if (lcdp)
401 lcdp->SetNext(cdp);
402 else
403 tocols= cdp;
404
405 lcdp= cdp;
406 i++;
407 } // endwhile
408
409 // Degree is the the number of defined columns (informational)
410 if (i != GetDegree())
411 SetDegree(i);
412
413 if (GetDefType() == TYPE_AM_DOS) {
414 int ending, recln= 0;
415
416 // Was commented because sometimes ending is 0 even when
417 // not specified (for instance if quoted is specified)
418// if ((ending= Hc->GetIntegerOption("Ending")) < 0) {
419 if ((ending= Hc->GetIntegerOption("Ending")) <= 0) {
420 ending= (tc == TAB_BIN || tc == TAB_VEC) ? 0 : CRLF;
421 Hc->SetIntegerOption("Ending", ending);
422 } // endif ending
423
424 // Calculate the default record size
425 switch (tc) {
426 case TAB_FIX:
427 case TAB_BIN:
428 recln= nlg + ending; // + length of line ending
429 break;
430 case TAB_VEC:
431 recln= nlg;
432
433// if ((k= (pak < 0) ? 8 : pak) > 1)
434 // See above for detailed comment
435 // Round up lrecl to multiple of 8 or pak
436// recln= ((recln + k - 1) / k) * k;
437
438 break;
439 case TAB_DOS:
440 case TAB_DBF:
441 recln= nlg;
442 break;
443 case TAB_CSV:
444 case TAB_FMT:
445 // The number of separators (assuming an extra one can exist)
446// recln= poff * ((qotd) ? 3 : 1); to be investigated
447 recln= nlg + poff * 3; // To be safe
448 default:
449 break;
450 } // endswitch tc
451
452 // lrecl must be at least recln to avoid buffer overflow
453 if (trace(1))
454 htrc("Lrecl: Calculated=%d defined=%d\n",
455 recln, Hc->GetIntegerOption("Lrecl"));
456
457 recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
458 Hc->SetIntegerOption("Lrecl", recln);
459 ((PDOSDEF)this)->SetLrecl(recln);
460 } // endif Lrecl
461
462 // Attach the column definition to the tabdef
463 SetCols(tocols);
464 return poff;
465 } // end of GetColCatInfo
466
467/***********************************************************************/
468/* SetIndexInfo: retrieve index description from the table structure. */
469/***********************************************************************/
470void TABDEF::SetIndexInfo(void)
471 {
472 // Attach new index(es)
473 SetIndx(Hc->GetIndexInfo());
474 } // end of SetIndexInfo
475
476/* --------------------------- Class OEMDEF -------------------------- */
477
478/***********************************************************************/
479/* GetXdef: get the external TABDEF from OEM module. */
480/***********************************************************************/
481PTABDEF OEMDEF::GetXdef(PGLOBAL g)
482 {
483 typedef PTABDEF (__stdcall *XGETDEF) (PGLOBAL, void *);
484 char c, soname[_MAX_PATH], getname[40] = "Get";
485 PTABDEF xdefp;
486 XGETDEF getdef = NULL;
487 PCATLG cat = Cat;
488
489 /*********************************************************************/
490 /* Ensure that the .dll doesn't have a path. */
491 /* This is done to ensure that only approved dll from the system */
492 /* directories are used (to make this even remotely secure). */
493 /*********************************************************************/
494 if (check_valid_path(Module, strlen(Module))) {
495 strcpy(g->Message, "Module cannot contain a path");
496 return NULL;
497 } else
498 PlugSetPath(soname, Module, GetPluginDir());
499
500#if defined(__WIN__)
501 // Is the DLL already loaded?
502 if (!Hdll && !(Hdll = GetModuleHandle(soname)))
503 // No, load the Dll implementing the function
504 if (!(Hdll = LoadLibrary(soname))) {
505 char buf[256];
506 DWORD rc = GetLastError();
507
508 sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
509 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
510 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
511 (LPTSTR)buf, sizeof(buf), NULL);
512 strcat(strcat(g->Message, ": "), buf);
513 return NULL;
514 } // endif hDll
515
516 // The exported name is always in uppercase
517 for (int i = 0; ; i++) {
518 c = Subtype[i];
519 getname[i + 3] = toupper(c);
520 if (!c) break;
521 } // endfor i
522
523 // Get the function returning an instance of the external DEF class
524 if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) {
525 sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
526 FreeLibrary((HMODULE)Hdll);
527 return NULL;
528 } // endif getdef
529#else // !__WIN__
530 const char *error = NULL;
531
532#if 0 // Don't know what all this stuff does
533 Dl_info dl_info;
534
535 // The OEM lib must retrieve exported CONNECT variables
536 if (dladdr(&connect_hton, &dl_info)) {
537 if (dlopen(dl_info.dli_fname, RTLD_NOLOAD | RTLD_NOW | RTLD_GLOBAL) == 0) {
538 error = dlerror();
539 sprintf(g->Message, "dlopen failed: %s, OEM not supported", SVP(error));
540 return NULL;
541 } // endif dlopen
542
543 } else {
544 error = dlerror();
545 sprintf(g->Message, "dladdr failed: %s, OEM not supported", SVP(error));
546 return NULL;
547 } // endif dladdr
548#endif // 0
549
550 // Load the desired shared library
551 if (!Hdll && !(Hdll = dlopen(soname, RTLD_LAZY))) {
552 error = dlerror();
553 sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
554 return NULL;
555 } // endif Hdll
556
557 // The exported name is always in uppercase
558 for (int i = 0; ; i++) {
559 c = Subtype[i];
560 getname[i + 3] = toupper(c);
561 if (!c) break;
562 } // endfor i
563
564 // Get the function returning an instance of the external DEF class
565 if (!(getdef = (XGETDEF)dlsym(Hdll, getname))) {
566 error = dlerror();
567 sprintf(g->Message, MSG(GET_FUNC_ERR), getname, SVP(error));
568 dlclose(Hdll);
569 return NULL;
570 } // endif getdef
571#endif // !__WIN__
572
573 // Just in case the external Get function does not set error messages
574 sprintf(g->Message, MSG(DEF_ALLOC_ERROR), Subtype);
575
576 // Get the table definition block
577 if (!(xdefp = getdef(g, NULL)))
578 return NULL;
579
580 // Have the external class do its complete definition
581 if (!cat->Cbuf) {
582 // Suballocate a temporary buffer for the entire column section
583 cat->Cblen = GetSizeCatInfo("Colsize", "8K");
584 cat->Cbuf = (char*)PlugSubAlloc(g, NULL, cat->Cblen);
585 } // endif Cbuf
586
587 // Here "OEM" should be replace by a more useful value
588 if (xdefp->Define(g, cat, Name, Schema, "OEM"))
589 return NULL;
590
591 // Ok, return external block
592 return xdefp;
593 } // end of GetXdef
594
595#if 0
596/***********************************************************************/
597/* DeleteTableFile: Delete an OEM table file if applicable. */
598/***********************************************************************/
599bool OEMDEF::DeleteTableFile(PGLOBAL g)
600 {
601 if (!Pxdef)
602 Pxdef = GetXdef(g);
603
604 return (Pxdef) ? Pxdef->DeleteTableFile(g) : true;
605 } // end of DeleteTableFile
606#endif // 0
607
608/***********************************************************************/
609/* Define: initialize the table definition block from XDB file. */
610/***********************************************************************/
611bool OEMDEF::DefineAM(PGLOBAL g, LPCSTR, int)
612 {
613 Module = GetStringCatInfo(g, "Module", "");
614 Subtype = GetStringCatInfo(g, "Subtype", Module);
615
616 if (!*Module)
617 Module = Subtype;
618
619 char *desc = (char*)PlugSubAlloc(g, NULL, strlen(Module)
620 + strlen(Subtype) + 3);
621 sprintf(desc, "%s(%s)", Module, Subtype);
622 Desc = desc;
623 return false;
624 } // end of DefineAM
625
626/***********************************************************************/
627/* GetTable: makes a new Table Description Block. */
628/***********************************************************************/
629PTDB OEMDEF::GetTable(PGLOBAL g, MODE mode)
630 {
631 RECFM rfm;
632 PTDB tdbp = NULL;
633
634 // If define block not here yet, get it now
635 if (!Pxdef && !(Pxdef = GetXdef(g)))
636 return NULL; // Error
637
638 /*********************************************************************/
639 /* Allocate a TDB of the proper type. */
640 /* Column blocks will be allocated only when needed. */
641 /*********************************************************************/
642 if (!(tdbp = Pxdef->GetTable(g, mode)))
643 return NULL;
644 else
645 rfm = tdbp->GetFtype();
646
647 if (rfm == RECFM_NAF)
648 return tdbp;
649 else if (rfm == RECFM_OEM) {
650 if (Multiple)
651 tdbp = new(g) TDBMUL(tdbp); // No block optimization yet
652
653 return tdbp;
654 } // endif OEM
655
656 /*********************************************************************/
657 /* The OEM table is based on a file type (currently DOS+ only) */
658 /*********************************************************************/
659 assert (rfm == RECFM_VAR || rfm == RECFM_FIX ||
660 rfm == RECFM_BIN || rfm == RECFM_VCT);
661
662 PTXF txfp = NULL;
663 PDOSDEF defp = (PDOSDEF)Pxdef;
664 bool map = defp->Mapped && mode != MODE_INSERT &&
665 !(UseTemp() == TMP_FORCE &&
666 (mode == MODE_UPDATE || mode == MODE_DELETE));
667 int cmpr = defp->Compressed;
668
669 /*********************************************************************/
670 /* Allocate table and file processing class of the proper type. */
671 /* Column blocks will be allocated only when needed. */
672 /*********************************************************************/
673 if (!((PTDBDOS)tdbp)->GetTxfp()) {
674 if (cmpr) {
675#if defined(GZ_SUPPORT)
676 if (cmpr == 1)
677 txfp = new(g) GZFAM(defp);
678 else
679 txfp = new(g) ZLBFAM(defp);
680#else // !GZ_SUPPORT
681 strcpy(g->Message, "Compress not supported");
682 return NULL;
683#endif // !GZ_SUPPORT
684 } else if (rfm == RECFM_VAR) {
685 if (map)
686 txfp = new(g) MAPFAM(defp);
687 else
688 txfp = new(g) DOSFAM(defp);
689
690 } else if (rfm == RECFM_FIX || rfm == RECFM_BIN) {
691 if (map)
692 txfp = new(g) MPXFAM(defp);
693 else
694 txfp = new(g) FIXFAM(defp);
695 } else if (rfm == RECFM_VCT) {
696#if defined(VCT_SUPPORT)
697 assert(Pxdef->GetDefType() == TYPE_AM_VCT);
698
699 if (map)
700 txfp = new(g) VCMFAM((PVCTDEF)defp);
701 else
702 txfp = new(g) VCTFAM((PVCTDEF)defp);
703#else // !VCT_SUPPORT
704 strcpy(g->Message, "VCT no more supported");
705 return NULL;
706#endif // !VCT_SUPPORT
707 } // endif's
708
709 ((PTDBDOS)tdbp)->SetTxfp(txfp);
710 } // endif Txfp
711
712 if (Multiple)
713 tdbp = new(g) TDBMUL(tdbp);
714
715 return tdbp;
716 } // end of GetTable
717
718/* --------------------------- Class COLCRT -------------------------- */
719
720/***********************************************************************/
721/* COLCRT Constructors. */
722/***********************************************************************/
723COLCRT::COLCRT(PSZ name)
724 {
725 Next = NULL;
726 Name = name;
727 Desc = NULL;
728 Decode = NULL;
729 Fmt = NULL;
730 Offset = -1;
731 Long = -1;
732 Precision = -1;
733 Freq = -1;
734 Key = -1;
735 Scale = -1;
736 Opt = -1;
737 DataType = '*';
738 } // end of COLCRT constructor for table creation
739
740COLCRT::COLCRT(void)
741 {
742 Next = NULL;
743 Name = NULL;
744 Desc = NULL;
745 Decode = NULL;
746 Fmt = NULL;
747 Offset = 0;
748 Long = 0;
749 Precision = 0;
750 Freq = 0;
751 Key = 0;
752 Scale = 0;
753 Opt = 0;
754 DataType = '*';
755 } // end of COLCRT constructor for table & view definition
756
757/* --------------------------- Class COLDEF -------------------------- */
758
759/***********************************************************************/
760/* COLDEF Constructor. */
761/***********************************************************************/
762COLDEF::COLDEF(void) : COLCRT()
763 {
764 To_Min = NULL;
765 To_Max = NULL;
766 To_Pos = NULL;
767 Xdb2 = FALSE;
768 To_Bmap = NULL;
769 To_Dval = NULL;
770 Ndv = 0;
771 Nbm = 0;
772 Buf_Type = TYPE_ERROR;
773 Clen = 0;
774 Poff = 0;
775 memset(&F, 0, sizeof(FORMAT));
776 Flags = 0;
777 } // end of COLDEF constructor
778
779/***********************************************************************/
780/* Define: initialize a column definition from a COLINFO structure. */
781/***********************************************************************/
782int COLDEF::Define(PGLOBAL g, void *, PCOLINFO cfp, int poff)
783 {
784 Name = (PSZ)PlugDup(g, cfp->Name);
785
786 if (!(cfp->Flags & U_SPECIAL)) {
787 Poff = poff;
788 Buf_Type = cfp->Type;
789
790 if ((Clen = GetTypeSize(Buf_Type, cfp->Length)) < 0) {
791 sprintf(g->Message, MSG(BAD_COL_TYPE), GetTypeName(Buf_Type), Name);
792 return -1;
793 } // endswitch
794
795 strcpy(F.Type, GetFormatType(Buf_Type));
796 F.Length = cfp->Length;
797 F.Prec = cfp->Scale;
798 Offset = (cfp->Offset < 0) ? poff : cfp->Offset;
799 Precision = cfp->Precision;
800 Scale = cfp->Scale;
801 Long = cfp->Length;
802 Opt = cfp->Opt;
803 Key = cfp->Key;
804 Freq = cfp->Freq;
805
806 if (cfp->Remark && *cfp->Remark)
807 Desc = (PSZ)PlugDup(g, cfp->Remark);
808
809 if (cfp->Datefmt)
810 Decode = (PSZ)PlugDup(g, cfp->Datefmt);
811
812 } else
813 Offset = poff;
814
815 if (cfp->Fieldfmt)
816 Fmt = (PSZ)PlugDup(g, cfp->Fieldfmt);
817
818 Flags = cfp->Flags;
819 return (Flags & (U_VIRTUAL|U_SPECIAL)) ? 0 : Long;
820 } // end of Define
821
822/* ------------------------- End of RelDef --------------------------- */
823