1 /************ JMONGO FAM C++ Program Source Code File (.CPP) ***********/
2 /* PROGRAM NAME: jmgfam.cpp */
3 /* ------------- */
4 /* Version 1.2 */
5 /* */
6 /* COPYRIGHT: */
7 /* ---------- */
8 /* (C) Copyright to the author Olivier BERTRAND 20017 - 2021 */
9 /* */
10 /* WHAT THIS PROGRAM DOES: */
11 /* ----------------------- */
12 /* This program are the Java MongoDB access method classes. */
13 /* */
14 /***********************************************************************/
15
16 /***********************************************************************/
17 /* Include relevant sections of the System header files. */
18 /***********************************************************************/
19 #include "my_global.h"
20 #if defined(_WIN32)
21 //#include <io.h>
22 //#include <fcntl.h>
23 //#include <errno.h>
24 #if defined(__BORLANDC__)
25 #define __MFC_COMPAT__ // To define min/max as macro
26 #endif // __BORLANDC__
27 //#include <windows.h>
28 #else // !_WIN32
29 #if defined(UNIX) || defined(UNIV_LINUX)
30 //#include <errno.h>
31 #include <unistd.h>
32 //#if !defined(sun) // Sun has the ftruncate fnc.
33 //#define USETEMP // Force copy mode for DELETE
34 //#endif // !sun
35 #else // !UNIX
36 //#include <io.h>
37 #endif // !UNIX
38 //#include <fcntl.h>
39 #endif // !_WIN32
40
41 /***********************************************************************/
42 /* Include application header files: */
43 /* global.h is header containing all global declarations. */
44 /* plgdbsem.h is header containing the DB application declarations. */
45 /* filamtxt.h is header containing the file AM classes declarations. */
46 /***********************************************************************/
47 #include "global.h"
48 #include "plgdbsem.h"
49 #include "reldef.h"
50 #include "filamtxt.h"
51 #include "tabdos.h"
52 #if defined(BSON_SUPPORT)
53 #include "tabbson.h"
54 #else
55 #include "tabjson.h"
56 #endif // BSON_SUPPORT
57 #include "jmgfam.h"
58
59 #if defined(UNIX) || defined(UNIV_LINUX)
60 #include "osutil.h"
61 //#define _fileno fileno
62 //#define _O_RDONLY O_RDONLY
63 #endif
64
65 /* --------------------------- Class JMGFAM -------------------------- */
66
67 /***********************************************************************/
68 /* Constructors. */
69 /***********************************************************************/
JMGFAM(PJDEF tdp)70 JMGFAM::JMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
71 {
72 Jcp = NULL;
73 //Client = NULL;
74 //Database = NULL;
75 //Collection = NULL;
76 //Cursor = NULL;
77 //Query = NULL;
78 //Opts = NULL;
79 Ops.Driver = tdp->Schema;
80 Ops.Url = tdp->Uri;
81 Ops.User = NULL;
82 Ops.Pwd = NULL;
83 Ops.Scrollable = false;
84 Ops.Fsize = 0;
85 Ops.Version = tdp->Version;
86 To_Fbt = NULL;
87 Mode = MODE_ANY;
88 Uristr = tdp->Uri;
89 Db_name = tdp->Schema;
90 Coll_name = tdp->Collname;
91 Options = tdp->Options;
92 Filter = tdp->Filter;
93 Wrapname = tdp->Wrapname;
94 Done = false;
95 Pipe = tdp->Pipe;
96 Version = tdp->Version;
97 Lrecl = tdp->Lrecl + tdp->Ending;
98 Curpos = 0;
99 } // end of JMGFAM Json standard constructor
100
101 #if defined(BSON_SUPPORT)
JMGFAM(PBDEF tdp)102 JMGFAM::JMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL)
103 {
104 Jcp = NULL;
105 Ops.Driver = tdp->Schema;
106 Ops.Url = tdp->Uri;
107 Ops.User = NULL;
108 Ops.Pwd = NULL;
109 Ops.Scrollable = false;
110 Ops.Fsize = 0;
111 Ops.Version = tdp->Version;
112 To_Fbt = NULL;
113 Mode = MODE_ANY;
114 Uristr = tdp->Uri;
115 Db_name = tdp->Schema;
116 Coll_name = tdp->Collname;
117 Options = tdp->Options;
118 Filter = tdp->Filter;
119 Wrapname = tdp->Wrapname;
120 Done = false;
121 Pipe = tdp->Pipe;
122 Version = tdp->Version;
123 Lrecl = tdp->Lrecl + tdp->Ending;
124 Curpos = 0;
125 } // end of JMGFAM Bson standard constructor
126 #endif // BSON_SUPPORT
127
JMGFAM(PJMGFAM tdfp)128 JMGFAM::JMGFAM(PJMGFAM tdfp) : DOSFAM(tdfp)
129 {
130 Jcp = tdfp->Jcp;
131 //Client = tdfp->Client;
132 //Database = NULL;
133 //Collection = tdfp->Collection;
134 //Cursor = tdfp->Cursor;
135 //Query = tdfp->Query;
136 //Opts = tdfp->Opts;
137 Ops = tdfp->Ops;
138 To_Fbt = tdfp->To_Fbt;
139 Mode = tdfp->Mode;
140 Uristr = tdfp->Uristr;
141 Db_name = tdfp->Db_name;
142 Coll_name = tdfp->Coll_name;
143 Options = tdfp->Options;
144 Filter = NULL;
145 Wrapname = tdfp->Wrapname;
146 Done = tdfp->Done;
147 Pipe = tdfp->Pipe;
148 Version = tdfp->Version;
149 Curpos = tdfp->Curpos;
150 } // end of JMGFAM copy constructor
151
152 /***********************************************************************/
153 /* Reset: reset position values at the beginning of file. */
154 /***********************************************************************/
Reset(void)155 void JMGFAM::Reset(void)
156 {
157 TXTFAM::Reset();
158 Fpos = Tpos = Spos = 0;
159 } // end of Reset
160
161 /***********************************************************************/
162 /* MGO GetFileLength: returns file size in number of bytes. */
163 /***********************************************************************/
GetFileLength(PGLOBAL g)164 int JMGFAM::GetFileLength(PGLOBAL g)
165 {
166 return 0;
167 } // end of GetFileLength
168
169 /***********************************************************************/
170 /* Cardinality: returns table cardinality in number of rows. */
171 /* This function can be called with a null argument to test the */
172 /* availability of Cardinality implementation (1 yes, 0 no). */
173 /***********************************************************************/
Cardinality(PGLOBAL g)174 int JMGFAM::Cardinality(PGLOBAL g)
175 {
176 if (!g)
177 return 1;
178
179 return (!Init(g)) ? Jcp->CollSize(g) : 0;
180 } // end of Cardinality
181
182 /***********************************************************************/
183 /* Note: This function is not really implemented yet. */
184 /***********************************************************************/
MaxBlkSize(PGLOBAL,int s)185 int JMGFAM::MaxBlkSize(PGLOBAL, int s)
186 {
187 return s;
188 } // end of MaxBlkSize
189
190 /***********************************************************************/
191 /* Init: initialize MongoDB processing. */
192 /***********************************************************************/
Init(PGLOBAL g)193 bool JMGFAM::Init(PGLOBAL g)
194 {
195 if (Done)
196 return false;
197
198 /*********************************************************************/
199 /* Open an JDBC connection for this table. */
200 /* Note: this may not be the proper way to do. Perhaps it is better */
201 /* to test whether a connection is already open for this datasource */
202 /* and if so to allocate just a new result set. But this only for */
203 /* drivers allowing concurency in getting results ??? */
204 /*********************************************************************/
205 if (!Jcp)
206 Jcp = new(g) JMgoConn(g, Coll_name, Wrapname);
207 else if (Jcp->IsOpen())
208 Jcp->Close();
209
210 if (Jcp->Connect(&Ops))
211 return true;
212
213 Done = true;
214 return false;
215 } // end of Init
216
217 /***********************************************************************/
218 /* OpenTableFile: Open a MongoDB table. */
219 /***********************************************************************/
OpenTableFile(PGLOBAL g)220 bool JMGFAM::OpenTableFile(PGLOBAL g)
221 {
222 Mode = Tdbp->GetMode();
223
224 if (Pipe && Mode != MODE_READ) {
225 strcpy(g->Message, "Pipeline tables are read only");
226 return true;
227 } // endif Pipe
228
229 if (Init(g))
230 return true;
231
232 if (Jcp->GetMethodId(g, Mode))
233 return true;
234
235 if (Mode == MODE_DELETE && !Tdbp->GetNext()) {
236 // Delete all documents
237 if (!Jcp->MakeCursor(g, Tdbp, "all", Filter, false))
238 if (Jcp->DocDelete(g, true) == RC_OK)
239 return false;
240
241 return true;
242 } // endif Mode
243
244 //if (Mode == MODE_INSERT)
245 // Jcp->MakeColumnGroups(g, Tdbp);
246
247 if (Mode != MODE_UPDATE)
248 return Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe);
249
250 return false;
251 } // end of OpenTableFile
252
253 /***********************************************************************/
254 /* GetRowID: return the RowID of last read record. */
255 /***********************************************************************/
GetRowID(void)256 int JMGFAM::GetRowID(void)
257 {
258 return Rows;
259 } // end of GetRowID
260
261 /***********************************************************************/
262 /* GetPos: return the position of last read record. */
263 /***********************************************************************/
GetPos(void)264 int JMGFAM::GetPos(void)
265 {
266 return Fpos;
267 } // end of GetPos
268
269 /***********************************************************************/
270 /* GetNextPos: return the position of next record. */
271 /***********************************************************************/
GetNextPos(void)272 int JMGFAM::GetNextPos(void)
273 {
274 return Fpos; // TODO
275 } // end of GetNextPos
276
277 /***********************************************************************/
278 /* SetPos: Replace the table at the specified position. */
279 /***********************************************************************/
SetPos(PGLOBAL g,int pos)280 bool JMGFAM::SetPos(PGLOBAL g, int pos)
281 {
282 Fpos = pos;
283 Placed = true;
284 return false;
285 } // end of SetPos
286
287 /***********************************************************************/
288 /* Record file position in case of UPDATE or DELETE. */
289 /***********************************************************************/
RecordPos(PGLOBAL g)290 bool JMGFAM::RecordPos(PGLOBAL g)
291 {
292 strcpy(g->Message, "JMGFAM::RecordPos NIY");
293 return true;
294 } // end of RecordPos
295
296 /***********************************************************************/
297 /* Initialize Fpos and the current position for indexed DELETE. */
298 /***********************************************************************/
InitDelete(PGLOBAL g,int fpos,int spos)299 int JMGFAM::InitDelete(PGLOBAL g, int fpos, int spos)
300 {
301 strcpy(g->Message, "JMGFAM::InitDelete NIY");
302 return RC_FX;
303 } // end of InitDelete
304
305 /***********************************************************************/
306 /* Skip one record in file. */
307 /***********************************************************************/
SkipRecord(PGLOBAL g,bool header)308 int JMGFAM::SkipRecord(PGLOBAL g, bool header)
309 {
310 return RC_OK; // Dummy
311 } // end of SkipRecord
312
313 /***********************************************************************/
314 /* ReadBuffer: Get next document from a collection. */
315 /***********************************************************************/
ReadBuffer(PGLOBAL g)316 int JMGFAM::ReadBuffer(PGLOBAL g)
317 {
318 int rc = RC_FX;
319
320 if (!Curpos && Mode == MODE_UPDATE)
321 if (Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe))
322 return RC_FX;
323
324 if (++CurNum >= Rbuf) {
325 Rbuf = Jcp->Fetch();
326 Curpos++;
327 CurNum = 0;
328 } // endif CurNum
329
330 if (Rbuf > 0) {
331 PSZ str = Jcp->GetDocument();
332
333 if (str) {
334 if (trace(1))
335 htrc("%s\n", str);
336
337 strncpy(Tdbp->GetLine(), str, Lrecl);
338 rc = RC_OK;
339 } else
340 strcpy(g->Message, "Null document");
341
342 } else if (!Rbuf)
343 rc = RC_EF;
344
345 return rc;
346 } // end of ReadBuffer
347
348 /***********************************************************************/
349 /* WriteBuffer: File write routine for JMG access method. */
350 /***********************************************************************/
WriteBuffer(PGLOBAL g)351 int JMGFAM::WriteBuffer(PGLOBAL g)
352 {
353 int rc = RC_OK;
354
355 if (Mode == MODE_INSERT) {
356 rc = Jcp->DocWrite(g, Tdbp->GetLine());
357 } else if (Mode == MODE_DELETE) {
358 rc = Jcp->DocDelete(g, false);
359 } else if (Mode == MODE_UPDATE) {
360 rc = Jcp->DocUpdate(g, Tdbp);
361 } // endif Mode
362
363 return rc;
364 } // end of WriteBuffer
365
366 /***********************************************************************/
367 /* Data Base delete line routine for MGO and BLK access methods. */
368 /***********************************************************************/
DeleteRecords(PGLOBAL g,int irc)369 int JMGFAM::DeleteRecords(PGLOBAL g, int irc)
370 {
371 return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
372 } // end of DeleteRecords
373
374 /***********************************************************************/
375 /* Table file close routine for MGO access method. */
376 /***********************************************************************/
CloseTableFile(PGLOBAL g,bool)377 void JMGFAM::CloseTableFile(PGLOBAL g, bool)
378 {
379 Jcp->Close();
380 Done = false;
381 } // end of CloseTableFile
382
383 /***********************************************************************/
384 /* Rewind routine for MGO access method. */
385 /***********************************************************************/
Rewind(void)386 void JMGFAM::Rewind(void)
387 {
388 Jcp->Rewind();
389 } // end of Rewind
390
391