1 /************** CMGFAM C++ Program Source Code File (.CPP) *************/
2 /* PROGRAM NAME: cmgfam.cpp                                            */
3 /* -------------                                                       */
4 /*  Version 1.5                                                        */
5 /*                                                                     */
6 /* COPYRIGHT:                                                          */
7 /* ----------                                                          */
8 /*  (C) Copyright to the author Olivier BERTRAND          20017 - 2020 */
9 /*                                                                     */
10 /* WHAT THIS PROGRAM DOES:                                             */
11 /* -----------------------                                             */
12 /*  This program are the MongoDB access method classes.                */
13 /*                                                                     */
14 /***********************************************************************/
15 
16 /***********************************************************************/
17 /*  Include relevant sections of the System header files.              */
18 /***********************************************************************/
19 #include "my_global.h"
20 
21 /***********************************************************************/
22 /*  Include application header files:                                  */
23 /*  global.h    is header containing all global declarations.          */
24 /*  plgdbsem.h  is header containing the DB application declarations.  */
25 /*  filamtxt.h  is header containing the file AM classes declarations. */
26 /***********************************************************************/
27 #include "global.h"
28 #include "plgdbsem.h"
29 #include "reldef.h"
30 #include "filamtxt.h"
31 #include "tabdos.h"
32 #if defined(BSON_SUPPORT)
33 #include "tabbson.h"
34 #else
35 #include "tabjson.h"
36 #endif   // BSON_SUPPORT
37 #include "cmgfam.h"
38 
39 #if defined(UNIX) || defined(UNIV_LINUX)
40 #include "osutil.h"
41 #endif
42 
43 /* --------------------------- Class CMGFAM -------------------------- */
44 
45 /***********************************************************************/
46 /*  Constructors.                                                      */
47 /***********************************************************************/
48 CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
49 {
50 	Cmgp = NULL;
51 	Pcg.Tdbp = NULL;
52 
53 	if (tdp) {
54 		Pcg.Uristr = tdp->Uri;
55 		Pcg.Db_name = tdp->Schema;
56 		Pcg.Coll_name = tdp->Collname;
57 		Pcg.Options = tdp->Options;
58 		Pcg.Filter = tdp->Filter;
59 		Pcg.Line = NULL;
60 		Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
61 		Lrecl = tdp->Lrecl + tdp->Ending;
62 	} else {
63 		Pcg.Uristr = NULL;
64 		Pcg.Db_name = NULL;
65 		Pcg.Coll_name = NULL;
66 		Pcg.Options = NULL;
67 		Pcg.Filter = NULL;
68 		Pcg.Line = NULL;
69 		Pcg.Pipe = false;
70 		Lrecl = 0;
71 	} // endif tdp
72 
73 	To_Fbt = NULL;
74 	Mode = MODE_ANY;
75 	Done = false;
76 } // end of CMGFAM standard constructor
77 
78 #if defined(BSON_SUPPORT)
79 	/***********************************************************************/
80 /*  Constructors.                                                      */
81 /***********************************************************************/
82 CMGFAM::CMGFAM(PBDEF tdp) : DOSFAM((PDOSDEF)NULL)
83 {
84 	Cmgp = NULL;
85 	Pcg.Tdbp = NULL;
86 
87 	if (tdp) {
88 		Pcg.Uristr = tdp->Uri;
89 		Pcg.Db_name = tdp->Schema;
90 		Pcg.Coll_name = tdp->Collname;
91 		Pcg.Options = tdp->Options;
92 		Pcg.Filter = tdp->Filter;
93 		Pcg.Line = NULL;
94 		Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
95 		Lrecl = tdp->Lrecl + tdp->Ending;
96 	} else {
97 		Pcg.Uristr = NULL;
98 		Pcg.Db_name = NULL;
99 		Pcg.Coll_name = NULL;
100 		Pcg.Options = NULL;
101 		Pcg.Filter = NULL;
102 		Pcg.Line = NULL;
103 		Pcg.Pipe = false;
104 		Lrecl = 0;
105 	} // endif tdp
106 
107 	To_Fbt = NULL;
108 	Mode = MODE_ANY;
109 	Done = false;
110 } // end of CMGFAM standard constructor
111 #endif    // BSON_SUPPORT
112 
113 CMGFAM::CMGFAM(PCMGFAM tdfp) : DOSFAM(tdfp)
114 {
115 	Cmgp = tdfp->Cmgp;
116 	Pcg = tdfp->Pcg;
117 	To_Fbt = tdfp->To_Fbt;
118 	Mode = tdfp->Mode;
119 	Done = tdfp->Done;
120 } // end of CMGFAM copy constructor
121 
122 /***********************************************************************/
123 /*  Reset: reset position values at the beginning of file.             */
124 /***********************************************************************/
125 void CMGFAM::Reset(void)
126 {
127 	TXTFAM::Reset();
128 	Fpos = Tpos = Spos = 0;
129 } // end of Reset
130 
131 /***********************************************************************/
132 /*  MGO GetFileLength: returns file size in number of bytes.           */
133 /***********************************************************************/
134 int CMGFAM::GetFileLength(PGLOBAL g)
135 {
136 	return 0;
137 } // end of GetFileLength
138 
139 /***********************************************************************/
140 /*  Cardinality: returns the number of documents in the collection.    */
141 /*  This function can be called with a null argument to test the       */
142 /*  availability of Cardinality implementation (1 yes, 0 no).          */
143 /***********************************************************************/
144 int CMGFAM::Cardinality(PGLOBAL g)
145 {
146 	if (!g)
147 		return 1;
148 
149 	return (!Init(g)) ? Cmgp->CollSize(g) : 0;
150 } // end of Cardinality
151 
152 /***********************************************************************/
153 /*  Note: This function is not really implemented yet.                 */
154 /***********************************************************************/
155 int CMGFAM::MaxBlkSize(PGLOBAL, int s)
156 {
157 	return s;
158 } // end of MaxBlkSize
159 
160 /***********************************************************************/
161 /*  Init: initialize MongoDB processing.                               */
162 /***********************************************************************/
163 bool CMGFAM::Init(PGLOBAL g)
164 {
165 	if (Done)
166 		return false;
167 
168 	/*********************************************************************/
169 	/*  Open an C connection for this table.                             */
170 	/*********************************************************************/
171 	if (!Cmgp) {
172 		Pcg.Tdbp = Tdbp;
173 		Cmgp = new(g) CMgoConn(g, &Pcg);
174 	} else if (Cmgp->IsConnected())
175 		Cmgp->Close();
176 
177 	if (Cmgp->Connect(g))
178 		return true;
179 
180 	Done = true;
181 	return false;
182 } // end of Init
183 
184 /***********************************************************************/
185 /*  OpenTableFile: Open a MongoDB table.                               */
186 /***********************************************************************/
187 bool CMGFAM::OpenTableFile(PGLOBAL g)
188 {
189 	Mode = Tdbp->GetMode();
190 
191 	if (Pcg.Pipe && Mode != MODE_READ) {
192 		strcpy(g->Message, "Pipeline tables are read only");
193 		return true;
194 	}	// endif Pipe
195 
196 	if (Init(g))
197 		return true;
198 
199 	if (Mode == MODE_DELETE && !Tdbp->GetNext())
200 		// Delete all documents
201 		return Cmgp->DocDelete(g);
202 	else if (Mode == MODE_INSERT)
203 		Cmgp->MakeColumnGroups(g);
204 
205 	return false;
206 } // end of OpenTableFile
207 
208 /***********************************************************************/
209 /*  GetRowID: return the RowID of last read record.                    */
210 /***********************************************************************/
211 int CMGFAM::GetRowID(void)
212 {
213 	return Rows;
214 } // end of GetRowID
215 
216 /***********************************************************************/
217 /*  GetPos: return the position of last read record.                   */
218 /***********************************************************************/
219 int CMGFAM::GetPos(void)
220 {
221 	return Fpos;
222 } // end of GetPos
223 
224 /***********************************************************************/
225 /*  GetNextPos: return the position of next record.                    */
226 /***********************************************************************/
227 int CMGFAM::GetNextPos(void)
228 {
229 	return Fpos;						// TODO
230 } // end of GetNextPos
231 
232 /***********************************************************************/
233 /*  SetPos: Replace the table at the specified position.               */
234 /***********************************************************************/
235 bool CMGFAM::SetPos(PGLOBAL g, int pos)
236 {
237 	Fpos = pos;
238 	Placed = true;
239 	return false;
240 } // end of SetPos
241 
242 /***********************************************************************/
243 /*  Record file position in case of UPDATE or DELETE.                  */
244 /***********************************************************************/
245 bool CMGFAM::RecordPos(PGLOBAL g)
246 {
247 	strcpy(g->Message, "CMGFAM::RecordPos NIY");
248 	return true;
249 } // end of RecordPos
250 
251 /***********************************************************************/
252 /*  Initialize Fpos and the current position for indexed DELETE.       */
253 /***********************************************************************/
254 int CMGFAM::InitDelete(PGLOBAL g, int fpos, int spos)
255 {
256 	strcpy(g->Message, "CMGFAM::InitDelete NIY");
257 	return RC_FX;
258 } // end of InitDelete
259 
260 /***********************************************************************/
261 /*  Skip one record in file.                                           */
262 /***********************************************************************/
263 int CMGFAM::SkipRecord(PGLOBAL g, bool header)
264 {
265 	return RC_OK;                  // Dummy
266 } // end of SkipRecord
267 
268 /***********************************************************************/
269 /*  ReadBuffer: Get next document from a collection.                   */
270 /***********************************************************************/
271 int CMGFAM::ReadBuffer(PGLOBAL g)
272 {
273 	int rc = Cmgp->ReadNext(g);
274 
275 	if (rc != RC_OK)
276 		return rc;
277 
278 	strncpy(Tdbp->GetLine(), Cmgp->GetDocument(g), Lrecl);
279 	return RC_OK;
280 } // end of ReadBuffer
281 
282 /***********************************************************************/
283 /*  WriteBuffer: File write routine for MGO access method.             */
284 /***********************************************************************/
285 int CMGFAM::WriteBuffer(PGLOBAL g)
286 {
287 	Pcg.Line = Tdbp->GetLine();
288 	return Cmgp->Write(g);
289 } // end of WriteBuffer
290 
291 /***********************************************************************/
292 /*  Data Base delete line routine for MGO and BLK access methods.      */
293 /***********************************************************************/
294 int CMGFAM::DeleteRecords(PGLOBAL g, int irc)
295 {
296 	return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
297 } // end of DeleteRecords
298 
299 /***********************************************************************/
300 /*  Table file close routine for MGO access method.                    */
301 /***********************************************************************/
302 void CMGFAM::CloseTableFile(PGLOBAL g, bool)
303 {
304 	Cmgp->Close();
305 	Done = false;
306 } // end of CloseTableFile
307 
308 /***********************************************************************/
309 /*  Rewind routine for MGO access method.                              */
310 /***********************************************************************/
311 void CMGFAM::Rewind(void)
312 {
313 	Cmgp->Rewind();
314 } // end of Rewind
315 
316