1 /************* TabZip C++ Program Source Code File (.CPP) **************/
2 /* PROGRAM NAME: TABZIP     Version 1.0                                */
3 /*  (C) Copyright to the author Olivier BERTRAND          2016         */
4 /*  This program are the TABZIP class DB execution routines.           */
5 /***********************************************************************/
6 
7 /***********************************************************************/
8 /*  Include relevant sections of the MariaDB header file.              */
9 /***********************************************************************/
10 #include <my_global.h>
11 
12 /***********************************************************************/
13 /*  Include application header files:                                  */
14 /*  global.h    is header containing all global declarations.          */
15 /*  plgdbsem.h  is header containing the DB application declarations.  */
16 /*  (x)table.h  is header containing the TDBASE declarations.          */
17 /*  tabzip.h    is header containing the TABZIP classes declarations.  */
18 /***********************************************************************/
19 #include "global.h"
20 #include "plgdbsem.h"
21 #include "xtable.h"
22 #include "filamtxt.h"
23 #include "filamzip.h"
24 #include "resource.h"                        // for IDS_COLUMNS
25 #include "tabdos.h"
26 #include "tabmul.h"
27 #include "tabzip.h"
28 
29 /* -------------------------- Class ZIPDEF --------------------------- */
30 
31 /************************************************************************/
32 /*  DefineAM: define specific AM block values.                          */
33 /************************************************************************/
34 bool ZIPDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
35 {
36 //target = GetStringCatInfo(g, "Target", NULL);
37 	return DOSDEF::DefineAM(g, "ZIP", poff);
38 } // end of DefineAM
39 
40 /***********************************************************************/
41 /*  GetTable: makes a new Table Description Block.                     */
42 /***********************************************************************/
43 PTDB ZIPDEF::GetTable(PGLOBAL g, MODE m)
44 {
45 	PTDB tdbp = NULL;
46 
47 	tdbp = new(g) TDBZIP(this);
48 
49 	if (Multiple)
50 		tdbp = new(g) TDBMUL(tdbp);
51 
52 	return tdbp;
53 } // end of GetTable
54 
55 /* ------------------------------------------------------------------- */
56 
57 /***********************************************************************/
58 /*  Implementation of the TDBZIP class.                                */
59 /***********************************************************************/
60 TDBZIP::TDBZIP(PZIPDEF tdp) : TDBASE(tdp)
61 {
62 	zipfile = NULL;
63 	zfn = tdp->Fn;
64 //target = tdp->target;
65 	nexterr = UNZ_OK;
66 } // end of TDBZIP standard constructor
67 
68 /***********************************************************************/
69 /*  Allocate ZIP column description block.                             */
70 /***********************************************************************/
71 PCOL TDBZIP::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
72 {
73 	return new(g) ZIPCOL(cdp, this, cprec, n);
74 } // end of MakeCol
75 
76 /***********************************************************************/
77 /*  open a zip file.																									 */
78 /*  param: filename	path and the filename of the zip file to open.		 */
79 /*  return:	true if open, false otherwise.														 */
80 /***********************************************************************/
81 bool TDBZIP::open(PGLOBAL g, const char *fn)
82 {
83 	char filename[_MAX_PATH];
84 
85 	PlugSetPath(filename, fn, GetPath());
86 
87 	if (!zipfile && !(zipfile = unzOpen64(filename)))
88 		sprintf(g->Message, "Zipfile open error");
89 
90 	return (zipfile == NULL);
91 }	// end of open
92 
93 /***********************************************************************/
94 /*  Close the zip file.																								 */
95 /***********************************************************************/
96 void TDBZIP::close()
97 {
98 	if (zipfile) {
99 		unzClose(zipfile);
100 		zipfile = NULL;
101 	}	// endif zipfile
102 
103 }	// end of close
104 
105 /***********************************************************************/
106 /*  ZIP Cardinality: returns table size in number of rows.             */
107 /***********************************************************************/
108 int TDBZIP::Cardinality(PGLOBAL g)
109 {
110 	if (!g)
111 		return 1;
112 	else if (Cardinal < 0) {
113 		if (!open(g, zfn)) {
114 			unz_global_info64 ginfo;
115 			int err = unzGetGlobalInfo64(zipfile, &ginfo);
116 
117 			Cardinal = (err == UNZ_OK) ? (int)ginfo.number_entry : 0;
118 		} else
119 			Cardinal = 10;    // Dummy for multiple tables
120 
121 	} // endif Cardinal
122 
123 	return Cardinal;
124 } // end of Cardinality
125 
126 /***********************************************************************/
127 /*  ZIP GetMaxSize: returns file size estimate in number of lines.     */
128 /***********************************************************************/
129 int TDBZIP::GetMaxSize(PGLOBAL g)
130 {
131 	if (MaxSize < 0)
132 		MaxSize = Cardinality(g);
133 
134 	return MaxSize;
135 } // end of GetMaxSize
136 
137 /***********************************************************************/
138 /*  ZIP Access Method opening routine.                                 */
139 /***********************************************************************/
140 bool TDBZIP::OpenDB(PGLOBAL g)
141 {
142 	if (Use == USE_OPEN)
143 		// Table already open
144 		return false;
145 
146 	Use = USE_OPEN;       // To be clean
147   return open(g, zfn);
148 } // end of OpenDB
149 
150 /***********************************************************************/
151 /*  ReadDB: Data Base read routine for ZIP access method.              */
152 /***********************************************************************/
153 int TDBZIP::ReadDB(PGLOBAL g)
154 {
155 	if (nexterr == UNZ_END_OF_LIST_OF_FILE)
156 		return RC_EF;
157 	else if (nexterr != UNZ_OK) {
158 		sprintf(g->Message, "unzGoToNextFile error %d", nexterr);
159 		return RC_FX;
160 	}	// endif nexterr
161 
162 	int err = unzGetCurrentFileInfo64(zipfile, &finfo, fn,
163 		sizeof(fn), NULL, 0, NULL, 0);
164 
165 	if (err != UNZ_OK) {
166 		sprintf(g->Message, "unzGetCurrentFileInfo64 error %d", err);
167 		return RC_FX;
168 	}	// endif err
169 
170 	nexterr = unzGoToNextFile(zipfile);
171 	return RC_OK;
172 } // end of ReadDB
173 
174 /***********************************************************************/
175 /*  WriteDB: Data Base write routine for ZIP access method.            */
176 /***********************************************************************/
177 int TDBZIP::WriteDB(PGLOBAL g)
178 {
179 	strcpy(g->Message, "ZIP tables are read only");
180 	return RC_FX;
181 } // end of WriteDB
182 
183 /***********************************************************************/
184 /*  Data Base delete line routine for ZIP access method.               */
185 /***********************************************************************/
186 int TDBZIP::DeleteDB(PGLOBAL g, int irc)
187 {
188 	strcpy(g->Message, "Delete not enabled for ZIP tables");
189 	return RC_FX;
190 } // end of DeleteDB
191 
192 /***********************************************************************/
193 /*  Data Base close routine for ZIP access method.                     */
194 /***********************************************************************/
195 void TDBZIP::CloseDB(PGLOBAL g)
196 {
197 	close();
198 	nexterr = UNZ_OK;               // For multiple tables
199 	Use = USE_READY;                // Just to be clean
200 } // end of CloseDB
201 
202 /* ---------------------------- ZIPCOL ------------------------------- */
203 
204 /***********************************************************************/
205 /*  ZIPCOL public constructor.                                         */
206 /***********************************************************************/
207 ZIPCOL::ZIPCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
208 	    : COLBLK(cdp, tdbp, i)
209 {
210 	if (cprec) {
211 		Next = cprec->GetNext();
212 		cprec->SetNext(this);
213 	} else {
214 		Next = tdbp->GetColumns();
215 		tdbp->SetColumns(this);
216 	} // endif cprec
217 
218 	Tdbz = (TDBZIP*)tdbp;
219 	flag = cdp->GetOffset();
220 } // end of ZIPCOL constructor
221 
222 /***********************************************************************/
223 /*  ReadColumn:                                                        */
224 /***********************************************************************/
225 void ZIPCOL::ReadColumn(PGLOBAL g)
226 {
227 	switch (flag) {
228 	case 1:
229 		Value->SetValue(Tdbz->finfo.compressed_size);
230 		break;
231 	case 2:
232 		Value->SetValue(Tdbz->finfo.uncompressed_size);
233 		break;
234 	case 3:
235 		Value->SetValue((int)Tdbz->finfo.compression_method);
236 		break;
237 	case 4:
238 		Tdbz->finfo.tmu_date.tm_year -= 1900;
239 
240 		if (((DTVAL*)Value)->MakeTime((tm*)&Tdbz->finfo.tmu_date))
241 			Value->SetNull(true);
242 
243 		Tdbz->finfo.tmu_date.tm_year += 1900;
244 		break;
245 	default:
246 		Value->SetValue_psz((PSZ)Tdbz->fn);
247 	}	// endswitch flag
248 
249 } // end of ReadColumn
250 
251 /* -------------------------- End of tabzip -------------------------- */
252