00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <eyedbconfig.h>
00025
00026 #include "kern_p.h"
00027
00028 namespace eyedbsm {
00029
00030 Boolean
00031 isDspValid(DbHandle const *dbh, short dspid)
00032 {
00033 DbHeader _dbh(DBSADDR(dbh));
00034 return (dspid >= 0 && dspid < x2h_u32(_dbh.__ndsp()) &&
00035 *_dbh.dsp(dspid).name()) ?
00036 True : False;
00037 }
00038
00039 Status
00040 ESM_dspGet(DbHandle const *dbh, const char *dataspace, short *dspid)
00041 {
00042 if (is_number(dataspace))
00043 {
00044 *dspid = atoi(dataspace);
00045 if (!isDspValid(dbh, *dspid))
00046 return statusMake(INVALID_DATASPACE, "invalid dataspace #%d",
00047 *dspid);
00048 return Success;
00049 }
00050
00051 DbHeader _dbh(DBSADDR(dbh));
00052 for (int i = 0; i < MAX_DATASPACES; i++)
00053 if (!strcmp(_dbh.dsp(i).name(), dataspace)) {
00054 *dspid = i;
00055 return Success;
00056 }
00057
00058 return statusMake(INVALID_DATASPACE, "dataspace %s not found",
00059 dataspace);
00060 }
00061
00062 Status
00063 ESM_getDatafile(DbHandle const *dbh, short &dspid, short &datid)
00064 {
00065 Status s;
00066 if (dspid == DefaultDspid) {
00067 s = ESM_dspGetDefault(dbh, &dspid);
00068 if (s) return s;
00069 }
00070
00071 if (!isDspValid(dbh, dspid))
00072 return statusMake(INVALID_DATASPACE, "invalid dataspace #%d", dspid);
00073
00074 DataspaceDesc dsp = DbHeader(DBSADDR(dbh)).dsp(dspid);
00075 datid = x2h_16(dsp.__datid(x2h_32(dsp.__cur())));
00076
00077
00078
00079
00080
00081
00082 return Success;
00083 }
00084
00085 Boolean
00086 ESM_getNextDatafile(DbHandle const *dbh, short dspid, short &datid)
00087 {
00088 DataspaceDesc dsp = DbHeader(DBSADDR(dbh)).dsp(dspid);
00089 int cur = x2h_32(dsp.__cur());
00090
00091
00092
00093
00094 if (datid != x2h_16(dsp.__datid(cur))) {
00095 fprintf(stderr, "*WARNING*: ESM_getNextDataFile : "
00096 "datid != x2h_16(dsp->__datid[cur]): %d != %d\n", datid,
00097 x2h_16(dsp.__datid(cur)));
00098 }
00099
00100 int ndat = x2h_32(dsp.__ndat());
00101 if (cur == ndat - 1)
00102 return False;
00103
00104
00105
00106
00107 datid = x2h_16(dsp.__datid(++cur));
00108
00109 dsp.__cur() = h2x_32(cur);
00110 return True;
00111 }
00112
00113 Status
00114 ESM_dspSetDefault(DbHandle const *dbh, const char *dataspace,
00115 Boolean fromDbCreate)
00116 {
00117 if (!fromDbCreate) {
00118 CHECK_X(dbh, "setting a default dataspace");
00119 }
00120
00121 short dspid;
00122 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00123 if (s) return s;
00124 DbHeader(DBSADDR(dbh)).__def_dspid() = h2x_16(dspid);
00125 return Success;
00126 }
00127
00128 Status
00129 ESM_dspGetDefault(DbHandle const *dbh, short *dspid)
00130 {
00131 *dspid = x2h_16(DbHeader(DBSADDR(dbh)).__def_dspid());
00132 return Success;
00133 }
00134
00135 Status
00136 ESM_dspCreateRealize(DbHandle const *dbh, const char *op,
00137 short dspid, const char *dataspace,
00138 const char **datfiles, unsigned int datfile_cnt)
00139 {
00140 if (datfile_cnt >= MAX_DAT_PER_DSP)
00141 return statusMake(INVALID_DATAFILE_CNT_IN_DATASPACE,
00142 "%s too many datafiles in dataspace: `%d'", op,
00143 datfile_cnt);
00144
00145 short *datid = new short[datfile_cnt];
00146 DbHeader _dbh(DBSADDR(dbh));
00147 DatType dtype;
00148 for (int i = 0; i < datfile_cnt; i++) {
00149 short xdspid;
00150 Status s = ESM_datCheck(dbh, datfiles[i], &datid[i], &xdspid);
00151 if (s) {
00152 delete [] datid;
00153 return s;
00154 }
00155
00156 if (xdspid != DefaultDspid && xdspid != dspid) {
00157 delete [] datid;
00158 return statusMake(INVALID_DATASPACE, "datafile %s is already "
00159 "tied to the dataspace %s",
00160 datfiles[i], _dbh.dsp(xdspid).name());
00161 }
00162
00163 if (!i)
00164 dtype = getDatType(&_dbh, datid[i]);
00165 else if (dtype != getDatType(&_dbh, datid[i])) {
00166 delete [] datid;
00167 return statusMake(INVALID_DATASPACE, "cannot gather different "
00168 "oid type based datafiles into a dataspace");
00169 }
00170 }
00171
00172 DataspaceDesc dsp = _dbh.dsp(dspid);
00173 strcpy(dsp.name(), dataspace);
00174 dsp.__cur() = 0;
00175 dsp.__ndat() = h2x_u32(datfile_cnt);
00176
00177 for (int i = 0; i < datfile_cnt; i++) {
00178 dsp.__datid(i) = h2x_16(datid[i]);
00179
00180 setDataspace(&_dbh, datid[i], dspid);
00181 }
00182
00183 unsigned int ndsp = x2h_32(_dbh.__ndsp());
00184 if (dspid == ndsp) {
00185 ndsp++;
00186 _dbh.__ndsp() = h2x_32(ndsp);
00187 }
00188
00189 delete [] datid;
00190 return Success;
00191 }
00192
00193 Status
00194 ESM_dspSetCurDat(DbHandle const *dbh, const char *dataspace, const char *datfile)
00195 {
00196 CHECK_X(dbh, "setting current datafile to a dataspace");
00197
00198 short dspid;
00199 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00200 if (s) return s;
00201
00202 short datid, xdspid;
00203 s = ESM_datCheck(dbh, datfile, &datid, &xdspid);
00204 if (s) return s;
00205
00206 DataspaceDesc dsp = DbHeader(DBSADDR(dbh)).dsp(dspid);
00207
00208 unsigned int ndat = x2h_u32(dsp.__ndat());
00209 for (int i = 0; i < ndat; i++) {
00210 if (x2h_16(dsp.__datid(i)) == datid) {
00211 dsp.__cur() = h2x_32(i);
00212 return Success;
00213 }
00214 }
00215
00216 return statusMake(ERROR, "datafile %s is not tied to "
00217 "to dataspace #%d [%s]",
00218 datfile, dspid, dsp.name());
00219 }
00220
00221 Status
00222 ESM_dspGetCurDat(DbHandle const *dbh, const char *dataspace, short *datid)
00223 {
00224 short dspid;
00225 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00226 if (s) return s;
00227
00228 DataspaceDesc dsp = DbHeader(DBSADDR(dbh)).dsp(dspid);
00229
00230 *datid = x2h_16(dsp.__datid(x2h_32(dsp.__cur())));
00231 return Success;
00232 }
00233
00234 Status
00235 ESM_dspCheck(DbHandle const *dbh, const char *dataspace, short *dspid,
00236 short datid[], unsigned int *ndat)
00237 {
00238 Status s = ESM_dspGet(dbh, dataspace, dspid);
00239 if (s) return s;
00240
00241 if (ndat || datid) {
00242 DataspaceDesc dsp = DbHeader(DBSADDR(dbh)).dsp(*dspid);
00243 if (ndat) *ndat = x2h_u32(dsp.__ndat());
00244 if (datid) {
00245 unsigned int _ndat = x2h_u32(dsp.__ndat());
00246 for (int i = 0; i < _ndat; i++)
00247 datid[i] = x2h_16(dsp.__datid(i));
00248 }
00249 }
00250
00251 return Success;
00252 }
00253
00254 Status
00255 ESM_dspCreate(DbHandle const *dbh, const char *dataspace,
00256 const char **datfiles, unsigned int datfile_cnt,
00257 Boolean fromDbCreate)
00258 {
00259 if (!fromDbCreate) {
00260 CHECK_X(dbh, "creating a dataspace");
00261 }
00262
00263 short dspid;
00264 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00265 if (!s)
00266 return statusMake(INVALID_DATASPACE, "dataspace already exist %s",
00267 dataspace);
00268
00269 if (strlen(dataspace) >= L_NAME)
00270 return statusMake(INVALID_DATASPACE, "dataspace name %s is too "
00271 "large, maximum size is %d",
00272 dataspace, L_NAME);
00273
00274 for (dspid = 0; dspid < MAX_DATASPACES; dspid++)
00275 if (!isDspValid(dbh, dspid))
00276 break;
00277
00278 #undef PR
00279 #define PR "dspCreate: "
00280 if (dspid == MAX_DATASPACES)
00281 return statusMake(INVALID_DATAFILE_CNT,
00282 PR " dataspace number too large: `%d'",
00283 x2h_u32(DbHeader(DBSADDR(dbh)).__ndsp()));
00284
00285 return ESM_dspCreateRealize(dbh, PR, dspid, dataspace, datfiles, datfile_cnt);
00286 }
00287
00288 Status
00289 ESM_dspUpdate(DbHandle const *dbh, const char *dataspace,
00290 const char **datfiles, unsigned int datfile_cnt)
00291 {
00292 CHECK_X(dbh, "updating a dataspace");
00293
00294 short dspid;
00295 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00296 if (s) return s;
00297
00298 #undef PR
00299 #define PR "dspUpdate: "
00300 return ESM_dspCreateRealize(dbh, PR, dspid, DbHeader(DBSADDR(dbh)).dsp(dspid).name(),
00301 datfiles, datfile_cnt);
00302 }
00303
00304 Status
00305 ESM_dspDelete(DbHandle const *dbh, const char *dataspace)
00306 {
00307 CHECK_X(dbh, "deleting a dataspace");
00308
00309 short dspid;
00310 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00311 if (s) return s;
00312
00313 short dspid_def;
00314 s = ESM_dspGetDefault(dbh, &dspid_def);
00315 if (s) return s;
00316
00317 DataspaceDesc dsp = DbHeader(DBSADDR(dbh)).dsp(dspid);
00318
00319 if (dspid == dspid_def)
00320 return statusMake(ERROR, "cannot delete default dataspace #%d [%s]",
00321 dspid, dsp.name());
00322
00323 unsigned int ndat = x2h_u32(dsp.__ndat());
00324
00325
00326
00327
00328
00329
00330 DbHeader _dbh(DBSADDR(dbh));
00331 for (int i = 0; i < ndat; i++) {
00332 setDataspace(&_dbh, x2h_16(dsp.__datid(i)), DefaultDspid);
00333 }
00334
00335 dsp.__ndat() = 0;
00336 *dsp.name() = 0;
00337
00338 unsigned int ndsp = x2h_u32(_dbh.__ndsp());
00339 if (dspid == ndsp - 1) {
00340 ndsp--;
00341 DbHeader(DBSADDR(dbh)).__ndsp() = h2x_u32(ndsp);
00342 }
00343
00344 return Success;
00345 }
00346
00347 Status
00348 ESM_dspRename(DbHandle const *dbh, const char *dataspace,
00349 const char *dataspace_new)
00350 {
00351 CHECK_X(dbh, "renaming a dataspace");
00352
00353 short dspid;
00354 Status s = ESM_dspGet(dbh, dataspace, &dspid);
00355 if (s) return s;
00356
00357 if (strlen(dataspace_new) >= L_NAME)
00358 return statusMake(INVALID_DATASPACE, "dataspace name %s is too "
00359 "large, maximum size is %d",
00360 dataspace_new, L_NAME);
00361
00362 strcpy(DbHeader(DBSADDR(dbh)).dsp(dspid).name(), dataspace_new);
00363 return Success;
00364 }
00365
00366 }