SAF_Db *
saf_open_database(const char *path, /* The name of the database. */
SAF_DbProps *properties /* This argument, if not null, provides database
* properties that will override the default properties provided by
* saf_createProps_database(). */
)
{
SAF_ENTER(saf_open_database, NULL);
SAF_Db *db=NULL;
SAF_DbProps *p=properties;
unsigned flags=0;
ss_prop_t *fprops=NULL;
size_t regno;
ss_scope_t regscope;
size_t naux, i;
ss_file_ref_t *filerefs=NULL;
SAF_REQUIRE(path != NULL, SAF_LOW_CHK_COST, NULL, _saf_errmsg("PATH must be non-null"));
/* Obtain properties. Either the user passed in a database properties handle or they passed null. In the latter
* case we create our own handle to default properties and release that at the end. */
if (!properties)
p = saf_createProps_database();
SAF_REQUIRE(p, SAF_HIGH_CHK_COST, NULL,
_saf_errmsg("PROPERTIES must be a valid handle if supplied"));
/* Build an SSlib property list and flags for opening the file */
if (NULL==(fprops = ss_prop_new(path)))
SAF_ERROR(NULL, _saf_errmsg("cannot create property list for ss_file_open"));
if (ss_prop_add(fprops, "comm", H5T_NATIVE_MPI_COMM, &(p->DbComm))<0)
SAF_ERROR(NULL, _saf_errmsg("cannot insert MPI communicator into property list for ss_file_open"));
flags |= p->ReadOnly ? H5F_ACC_RDONLY : H5F_ACC_RDWR | H5F_ACC_CREAT;
if (p->Clobber) flags |= H5F_ACC_TRUNC | H5F_ACC_CREAT | H5F_ACC_RDWR;
if (p->MemoryResident) flags |= H5F_ACC_TRANSIENT | H5F_ACC_CREAT | H5F_ACC_RDWR;
/* Open or create the file */
if (NULL==(db=ss_file_open(NULL, path, flags, fprops)))
SAF_ERROR(NULL, _saf_errmsg("ss_file_open failed"));
/* Open all auxiliary files using the same communicator */
if (NULL==(filerefs=ss_file_references(db, &naux, NULL, NULL)))
SAF_ERROR(NULL, _saf_errmsg("cannot obtain list of auxiliary files"));
if (ss_file_openall(naux, filerefs, flags, fprops)<0)
SAF_ERROR(NULL, _saf_errmsg("cannot open some auxiliary files"));
/* Attach registry scopes to the files unless we're opening a registry */
if (!p->NoRegistries) {
for (regno=0; regno<_SAF_GLOBALS.p.reg.nused; regno++) {
if (!_SAF_GLOBALS.p.reg.db[regno]) continue;
if (NULL==ss_file_topscope(_SAF_GLOBALS.p.reg.db[regno], ®scope))
SAF_ERROR(NULL, _saf_errmsg("cannot get top scope for registry"));
if (ss_file_registry(db, ®scope)<0)
SAF_ERROR(NULL, _saf_errmsg("cannot set registry for file"));
for (i=0; i<naux; i++) {
if (ss_file_registry(&(filerefs[i].file), ®scope)<0)
SAF_ERROR(NULL, _saf_errmsg("cannot set registry for auxiliary file"));
}
}
}
/* Free the property list */
ss_prop_dest(fprops);
for (i=0; i<naux; i++) SS_FREE(filerefs[i].newname);
SS_FREE(filerefs);
SAF_LEAVE(db);
}