Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / tt / lib / db / tt_client_isam_file.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 //%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                  
24 //%%  (c) Copyright 1993, 1994 International Business Machines Corp.    
25 //%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                   
26 //%%  (c) Copyright 1993, 1994 Novell, Inc.                             
27 //%%  $XConsortium: tt_client_isam_file.C /main/3 1995/10/23 09:59:12 rswiston $                                                        
28 /*
29  * tt_client_isam_file.cc - Defines the TT ISAM file class.  This class
30  *      simplifies opening, closing, reading and writing an ISAM file.
31  *
32  * Copyright (c) 1992 by Sun Microsystems, Inc.
33  */
34
35 #include "db/tt_client_isam.h"
36 #include "db/tt_client_isam_file.h"
37 #include "db/tt_old_db_consts.h"
38
39 _Tt_client_isam_file::_Tt_client_isam_file (const _Tt_string        &file,
40                               int                      mode,
41                               const _Tt_db_client_ptr &db_connection)
42 {
43   dbConnection = db_connection;
44
45   setTtISAMFileDefaults();
46   fileName = file;
47   fileMode = mode;
48
49   if ((fileDescriptor = dbConnection->isopen(file, mode)) != -1) {
50     getISAMFileInfo();
51   }
52   else {
53     getStatusInfo();
54   }
55 }
56
57 _Tt_client_isam_file
58 ::_Tt_client_isam_file (const _Tt_string            &file,
59                  int                          max_record_length,
60                  int                          min_record_length,
61                  _Tt_client_isam_key_descriptor_ptr  primary_key_descriptor,
62                  int                          mode,
63                  const _Tt_db_client_ptr     &db_connection)
64 {
65   dbConnection = db_connection;
66
67   setTtISAMFileDefaults();
68   fileName = file;
69   fileMode = mode;
70
71   // Because a old TT client may be talking with the old DB, make sure
72   // files are opened with a manual lock, not an exclusive lock.
73   if ((fileDescriptor =
74        dbConnection->isopen(file, mode&(~ISEXCLLOCK)|ISMANULOCK)) == -1) {
75     newFlag = TRUE;
76     dbConnection->isreclen = min_record_length;
77     fileDescriptor = dbConnection->isbuild(file,
78                                            (max_record_length > TT_OLD_MAX_RECORD_LENGTH ?
79                                             TT_OLD_MAX_RECORD_LENGTH : max_record_length),
80                                            primary_key_descriptor->getKeyDescriptor(),
81                                            mode);
82   }
83   
84   if (fileDescriptor != -1) {
85     getISAMFileInfo();
86   }
87   else {
88     errorStatus = dbConnection->iserrno;
89     currentRecordLength = -1;
90     currentRecordNumber = -1;
91   }
92 }
93
94 void _Tt_client_isam_file::setTtISAMFileDefaults ()
95 {
96   eraseFlag = FALSE;
97   fileName = (char *)NULL;
98   fileMode = 0;
99   keyDescriptorList = new _Tt_client_isam_key_descriptor_list;
100   newFlag = FALSE;
101
102   dbConnection->iserrno = 0;
103 }
104
105 _Tt_client_isam_file::~_Tt_client_isam_file ()
106 {
107   if (eraseFlag) {
108     (void)dbConnection->iserase(fileName);
109   }
110   else {
111     (void)dbConnection->isclose(fileDescriptor);
112   }
113 }
114
115 void _Tt_client_isam_file::setErase (bool_t flag)
116 {
117   eraseFlag = flag;
118 }
119
120 int _Tt_client_isam_file::addIndex (_Tt_client_isam_key_descriptor_ptr key_descriptor)
121 {
122   dbConnection->iserrno = 0;
123
124   int results = dbConnection->isaddindex(fileDescriptor, key_descriptor->getKeyDescriptor());
125
126   errorStatus = dbConnection->iserrno;
127   if (!results) {
128     getISAMFileInfo();
129   }
130
131   return errorStatus;
132 }
133
134 _Tt_client_isam_record_ptr _Tt_client_isam_file::getEmptyRecord ()
135 {
136   return (new _Tt_client_isam_record(keyDescriptorList,
137                               maxRecordLength,
138                               minRecordLength));
139 }
140
141 int _Tt_client_isam_file
142 ::findStartRecord (const _Tt_client_isam_key_descriptor_ptr &key_descriptor,
143                    int                                length,
144                    const _Tt_client_isam_record_ptr         &record,
145                    int                                mode)
146 {
147   dbConnection->iserrno = 0;
148
149   dbConnection->isreclen = record->getLength();
150   (void)dbConnection->isstart(fileDescriptor,
151                               key_descriptor->getKeyDescriptor(),
152                               length,
153                               (char *)record->getRecord(),
154                               mode);
155
156   getStatusInfo();
157   return errorStatus;
158 }
159
160 _Tt_client_isam_record_ptr _Tt_client_isam_file::readRecord (int mode)
161 {
162   dbConnection->iserrno = 0;
163
164   _Tt_client_isam_record_ptr record = (_Tt_client_isam_record *)NULL;
165   _Tt_string          record_buffer(maxRecordLength);
166   dbConnection->isreclen = maxRecordLength;
167   int                 results = dbConnection->isread(fileDescriptor,
168                                                      (char *)record_buffer,
169                                                      mode);
170
171   getStatusInfo();
172   if (!results) {
173     record = getFullRecord(record_buffer);
174   }
175
176   return record;
177 }
178
179 int _Tt_client_isam_file::readRecord (int                        mode,
180                                const _Tt_client_isam_record_ptr &record)
181 {
182   dbConnection->iserrno = 0;
183
184   dbConnection->isreclen = record->getLength();
185   int results = dbConnection->isread(fileDescriptor, (char *)record->getRecord(), mode);
186
187   getStatusInfo();
188   if (!results) {
189     record->setLength(currentRecordLength);
190   }
191
192   return errorStatus;
193 }
194
195 int
196 _Tt_client_isam_file::updateRecord (long recnum, const _Tt_client_isam_record_ptr &record)
197 {
198   dbConnection->iserrno = 0;
199
200   dbConnection->isreclen = record->getLength();
201   (void)dbConnection->isrewrec(fileDescriptor, recnum, (char *)record->getRecord());
202
203   getStatusInfo();
204   return errorStatus;
205 }
206
207 int _Tt_client_isam_file::writeRecord (const _Tt_client_isam_record_ptr &record)
208 {
209   dbConnection->iserrno = 0;
210
211   dbConnection->isreclen = record->getLength();
212   (void)dbConnection->iswrite(fileDescriptor, (char *)record->getRecord());
213
214   getStatusInfo();
215   return errorStatus;
216 }
217
218 int
219 _Tt_client_isam_file::deleteRecord (long                              recnum,
220                                     const _Tt_client_isam_record_ptr &record)
221 {
222   dbConnection->iserrno = 0;
223
224   dbConnection->isreclen = record->getLength();
225   (void)dbConnection->isdelrec(fileDescriptor,
226                                recnum,
227                                (char *)record->getRecord());
228
229   getStatusInfo();
230   return errorStatus;
231 }
232
233 int _Tt_client_isam_file::writeMagicString (const _Tt_string &magic_string)
234 {
235   dbConnection->iserrno = 0;
236
237   (void)dbConnection->iscntl(fileDescriptor,
238                              ISCNTL_APPLMAGIC_WRITE,
239                              (char *)magic_string);
240
241   errorStatus = dbConnection->iserrno;
242   return errorStatus;
243 }
244
245 _Tt_string _Tt_client_isam_file::readMagicString ()
246 {
247   dbConnection->iserrno = 0;
248
249   _Tt_string magic_string_bytes(ISAPPLMAGICLEN);
250   memset((char *)magic_string_bytes, '\0', ISAPPLMAGICLEN);
251   
252   (void)dbConnection->iscntl(fileDescriptor,
253                              ISCNTL_APPLMAGIC_READ,
254                              (char *)magic_string_bytes);
255
256   errorStatus = dbConnection->iserrno;
257
258   _Tt_string magic_string = (char *)magic_string_bytes;
259   return magic_string;
260 }
261
262 _Tt_client_isam_record_ptr
263 _Tt_client_isam_file::getFullRecord (const _Tt_string &record_buffer)
264 {
265   _Tt_client_isam_record_ptr record_ptr = new _Tt_client_isam_record(keyDescriptorList,
266                                                        maxRecordLength,
267                                                        minRecordLength);
268   record_ptr->setBytes(0, currentRecordLength, record_buffer);
269   record_ptr->setLength(currentRecordLength);
270
271   return record_ptr;
272 }
273
274 void _Tt_client_isam_file::getISAMFileInfo ()
275 {
276   keyDescriptorList->flush();
277
278   if (!strcmp(TT_OLD_DB_PROPERTY_TABLE_FILE,
279               (char *)fileName+
280                       fileName.len()-
281                       strlen(TT_OLD_DB_PROPERTY_TABLE_FILE))) {
282     maxRecordLength = TT_OLD_MAX_RECORD_LENGTH;
283     minRecordLength = TT_OLD_DB_KEY_LENGTH+TT_OLD_DB_MAX_PROPERTY_NAME_LENGTH;
284
285     _Tt_client_isam_key_descriptor_ptr key_descriptor =
286                                 new _Tt_client_isam_key_descriptor;
287
288     key_descriptor->addKeyPart(TT_OLD_DB_FIRST_KEY_OFFSET,
289                                TT_OLD_DB_KEY_LENGTH,
290                                BINTYPE);
291     key_descriptor->addKeyPart(TT_OLD_DB_PROPERTY_NAME_OFFSET,
292                                TT_OLD_DB_MAX_PROPERTY_NAME_LENGTH,
293                                CHARTYPE);
294     key_descriptor->setDuplicates(TRUE);
295     
296     keyDescriptorList->append(key_descriptor);
297   }
298   else if (!strcmp(TT_OLD_DB_ACCESS_TABLE_FILE,
299                    (char *)fileName+
300                            fileName.len()-
301                            strlen(TT_OLD_DB_ACCESS_TABLE_FILE))) {
302     maxRecordLength = minRecordLength = TT_OLD_DB_KEY_LENGTH+
303                                         3*TT_OLD_DB_SHORT_SIZE;
304
305     _Tt_client_isam_key_descriptor_ptr key_descriptor =
306                                 new _Tt_client_isam_key_descriptor;
307
308     key_descriptor->addKeyPart(TT_OLD_DB_FIRST_KEY_OFFSET,
309                                TT_OLD_DB_KEY_LENGTH,
310                                BINTYPE);
311
312     keyDescriptorList->append(key_descriptor);
313   }
314   else if (!strcmp(TT_OLD_DB_FILE_TABLE_FILE,
315                    (char *)fileName+
316                            fileName.len()-
317                            strlen(TT_OLD_DB_FILE_TABLE_FILE))) {
318     maxRecordLength = TT_OLD_DB_KEY_LENGTH+MAXPATHLEN;
319     minRecordLength = TT_OLD_DB_KEY_LENGTH+TT_OLD_DB_MAX_KEY_LENGTH;
320
321     _Tt_client_isam_key_descriptor_ptr key_descriptor =
322                                 new _Tt_client_isam_key_descriptor;
323     key_descriptor->addKeyPart(TT_OLD_DB_FIRST_KEY_OFFSET,
324                                TT_OLD_DB_KEY_LENGTH,
325                                BINTYPE);
326     keyDescriptorList->append(key_descriptor);
327
328     key_descriptor = new _Tt_client_isam_key_descriptor;
329     key_descriptor->addKeyPart(TT_OLD_DB_FILE_PATH_OFFSET,
330                                TT_OLD_DB_MAX_KEY_LENGTH,
331                                CHARTYPE);
332     keyDescriptorList->append(key_descriptor);
333   }
334   // TT_OLD_DB_FILE_OBJECT_MAP_FILE
335   else {
336     maxRecordLength = minRecordLength = 2*TT_OLD_DB_KEY_LENGTH;
337
338     _Tt_client_isam_key_descriptor_ptr key_descriptor =
339                                 new _Tt_client_isam_key_descriptor;
340     key_descriptor->addKeyPart(TT_OLD_DB_FIRST_KEY_OFFSET,
341                                TT_OLD_DB_KEY_LENGTH,
342                                BINTYPE);
343     keyDescriptorList->append(key_descriptor);
344
345     key_descriptor = new _Tt_client_isam_key_descriptor;
346     key_descriptor->addKeyPart(TT_OLD_DB_SECOND_KEY_OFFSET,
347                                TT_OLD_DB_KEY_LENGTH,
348                                CHARTYPE);
349     key_descriptor->setDuplicates(TRUE);
350     keyDescriptorList->append(key_descriptor);
351   }
352
353   errorStatus = dbConnection->iserrno = 0;
354 }