Commit 84314bd3 authored by claes's avatar claes

Database mysql

parent 1729c14d
/*
* Proview $Id: wb_dbms.cpp,v 1.1 2007-10-18 09:11:01 claes Exp $
* Copyright (C) 2005 SSAB Oxelösund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#if defined PWRE_CONF_MYSQL
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include "pwr.h"
#include "pwr_class.h"
#include "co_dcli.h"
#include "wb_ldh.h"
#include "wb_ldh_msg.h"
#include "wb_destination.h"
#include "wb_dbms.h"
#include "wb_name.h"
#include "wb_export.h"
#include "wb_convert_volume.h"
#include <iostream>
wb_dbms::wb_dbms() :
m_vid(0), m_cid(0), m_env(0), m_con(0), m_txn(0)
{
initTables();
}
wb_dbms::wb_dbms(pwr_tVid vid) :
m_vid(0), m_cid(0), m_env(0), m_con(0), m_txn(0)
{
initTables();
}
int wb_dbms::close()
{
if (m_txn) {
m_txn->abort();
}
m_t_ohead->close();
m_t_rbody->close();
m_t_dbody->close();
m_t_class->close();
m_t_name->close();
m_t_info->close();
m_env->close();
return 0;
}
void wb_dbms::copy(wb_export &e, const char *fileName)
{
pwr_tStatus sts;
char l_fileName[512];
dcli_translate_filename(l_fileName, fileName);
if (!m_env) {
m_env = new wb_dbms_env(l_fileName);
m_env->open();
}
createDb();
importVolume(e);
close();
open();
try {
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
wb_dbms_info i(this);
i.get(m_txn);
m_vid = i.vid();
m_cid = i.cid();
strcpy(m_volumeName, i.name());
commit(&sts);
}
catch (wb_dbms_error &e) {
m_txn->abort();
printf("exeption: %s\n", e.what().c_str());
}
}
void wb_dbms::copy(wb_export &e, wb_dbms_env *env)
{
pwr_tStatus sts;
m_env = env;
m_env->open();
createDb();
importVolume(e);
close();
open();
try {
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
wb_dbms_info i(this);
i.get(m_txn);
m_vid = i.vid();
m_cid = i.cid();
strcpy(m_volumeName, i.name());
commit(&sts);
}
catch (wb_dbms_error &e) {
m_txn->abort();
printf("exeption: %s\n", e.what().c_str());
}
}
void wb_dbms::create(pwr_tVid vid, pwr_tCid cid, const char *volumeName, const char *fileName)
{
m_vid = vid;
m_cid = cid;
pwr_tStatus sts;
strcpy(m_volumeName, volumeName);
char l_fileName[512];
dcli_translate_filename(l_fileName, fileName);
size_t rbSize = 0;
pwr_tTime time;
pwr_tOid oid;
pwr_mClassDef flags;
flags.m = pwr_mClassDef_System | pwr_mClassDef_TopObject;
if (!m_env) {
m_env = new wb_dbms_env(l_fileName);
m_env->open();
}
if (m_env->exists())
createDb();
else
return;
switch (cid) {
case pwr_eClass_RootVolume:
rbSize = sizeof(pwr_sRootVolume);
break;
case pwr_eClass_SubVolume:
rbSize = sizeof(pwr_sSubVolume);
break;
case pwr_eClass_SystemVolume:
rbSize = sizeof(pwr_sSystemVolume);
break;
case pwr_eClass_ClassVolume:
rbSize = sizeof(pwr_sClassVolume);
break;
case pwr_eClass_WorkBenchVolume:
rbSize = sizeof(pwr_sWorkBenchVolume);
break;
case pwr_eClass_DirectoryVolume:
rbSize = sizeof(pwr_sDirectoryVolume);
break;
case pwr_eClass_SharedVolume:
rbSize = sizeof(pwr_sSharedVolume);
break;
case pwr_eClass_CreateVolume:
case pwr_eClass_MountVolume:
flags.m = pwr_mClassDef_System | pwr_mClassDef_NoAdopt;
break;
case pwr_eClass_MountObject:
flags.m = pwr_mClassDef_System | pwr_mClassDef_TopObject | pwr_mClassDef_NoAdopt;
break;
case pwr_eClass_VolatileVolume:
case pwr_eClass_ExternVolume:
flags.m = pwr_mClassDef_System | pwr_mClassDef_TopObject | pwr_mClassDef_DevOnly;
break;
case pwr_eClass_DynamicVolume:
break;
default: ;
}
oid.vid = vid;
oid.oix = pwr_cNOix;
wb_name n(volumeName);
try {
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
importHead(oid, cid, pwr_cNOid, pwr_cNOid, pwr_cNOid, pwr_cNOid, pwr_cNOid, n.name(), n.normName(), flags, time, time, time, rbSize, 0);
wb_dbms_info i(this);
i.get(m_txn);
m_vid = i.vid();
m_cid = i.cid();
strcpy(m_volumeName, i.name());
commit(&sts);
}
catch (wb_dbms_error &e) {
m_txn->abort();
printf("exeption: %s\n", e.what().c_str());
}
}
void wb_dbms::open(const char *fileName)
{
char l_fileName[512];
dcli_translate_filename(l_fileName, fileName);
if (!m_env) {
m_env = new wb_dbms_env(l_fileName);
m_env->open();
}
open();
}
void wb_dbms::open(wb_dbms_env *env)
{
m_env = env;
open();
}
int wb_dbms::open()
{
m_con = m_env->openDb();
try {
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
wb_dbms_info i(this);
i.get(m_txn);
m_vid = i.vid();
m_cid = i.cid();
strcpy(m_volumeName, i.name());
return 0;
}
catch (wb_dbms_error &e) {
m_txn->abort();
printf("exeption: %s\n", e.what().c_str());
return 1;
}
}
int wb_dbms::createDb()
{
int rc;
m_con = m_env->createDb();
rc = m_t_ohead->create("create table ohead ("
" oid bigint not null,"
" head longblob not null,"
" primary key (oid)"
") type = innodb;");
rc = m_t_rbody->create("create table rbody ("
" oid bigint not null,"
" body longblob,"
" primary key (oid)"
") type = innodb;");
rc = m_t_dbody->create("create table dbody ("
" oid bigint not null,"
" body longblob,"
" primary key (oid)"
") type = innodb;");
rc = m_t_class->create("create table class ("
" cidoix bigint not null,"
" primary key (cidoix)"
") type = innodb;");
rc = m_t_name->create("create table name ("
" poid bigint not null,"
" normname tinyblob not null,"
" oid bigint not null,"
" primary key (poid, normname(31))"
") type = innodb;");
rc = m_t_info->create("create table info ("
" id int not null,"
" volume longblob not null,"
" primary key (id)"
") type = innodb;");
#if 0
try {
rc = m_env->txn_begin(0, &txn, 0);
} catch (wb_dbms_error &e) {
printf("m_env->txn_begin, %s\n", e.what().c_str());
}
#endif
return 0;
}
pwr_tOid wb_dbms::new_oid(wb_dbms_txn *txn)
{
int rc = 0;
pwr_tOid oid = pwr_cNOid;
oid.vid = m_vid;
wb_dbms_rbody b(this, oid);
rc = b.get(txn, offsetof(pwr_sRootVolume, NextOix), sizeof(pwr_tOix), &oid.oix);
if (rc)
printf("wb_db::new_oid, b.get, rc %d\n", rc);
oid.oix++;
rc = b.upd(txn, offsetof(pwr_sRootVolume, NextOix), sizeof(pwr_tOix), &oid.oix);
if (rc)
printf("wb_dbms::new_oid, b.upd, rc %d\n", rc);
return oid;
}
pwr_tOid wb_dbms::new_oid(wb_dbms_txn *txn, pwr_tOid oid)
{
pwr_tOid woid;
woid.vid = m_vid;
woid.oix = oid.oix;
try {
wb_dbms_ohead o(this, txn, woid);
} catch (wb_dbms_error &e) {
return woid;
}
cout << " Old oix found, force new " << woid.oix << " !\n";
return new_oid(txn);
}
int wb_dbms::del_family(wb_dbms_txn *txn, wb_dbms_cursor *cp, pwr_tOid poid)
{
int ret = 0;
#if 0
dbName name;
name.poid = poid;
name.normname = "";
pwr_tOid oid = 0;
FamilyKey nk(po, );
FamiltData nd(&oid, sizeof(oid));
wb_dbms_cursor *ncp;
cp->dup(*ncp, 0);
while ((ret = cp->get(&nk, &nd, DB_NEXT)) != DB_NOTFOUND) {
del_family(txn, ncp, oid);
cp->del();
oh_k ok(nd);
oh_d od();
m_dbms_ohead->get(txn, &ok, &od, 0);
wb_DbClistK ck(od);
m_db_class->del(txn, &ck, 0);
wb_DbBodyK bk(od);
m_db_obody->del(txn, &bk, 0);
m_db_ohead->del(txn, &ok, 0);
}
ncp->close();
ret = m_db_name->del(txn, &key, 0);
#endif
return ret;
}
/* Save all changes done in the current transaction. */
bool wb_dbms::commit(pwr_tStatus *sts)
{
int rc = 0;
rc = m_txn->commit();
if (rc)
printf("wb_dbms::commit, rc %d\n", rc);
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
*sts = rc;
return true;
}
/* Abort the current transactionm, the database is restored to
the state it had before the current transaction started. */
bool wb_dbms::abort(pwr_tStatus *sts)
{
*sts = m_txn->abort();
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
return true;
}
wb_dbms_txn *wb_dbms::begin(wb_dbms_txn *txn)
{
m_env->txn_begin(0, (wb_dbms_txn **)&m_txn);
return txn;
}
wb_dbms_txn *wb_dbms::subBegin(wb_dbms_txn *txn)
{
txn->subBegin();
return txn;
}
bool wb_dbms::deleteFamily(pwr_tStatus *sts, wb_dbms_ohead *o)
{
wb_dbms_txn *txn = 0;
m_env->txn_begin(m_txn, &txn);
try {
//unadopt(txn, wb_Position(o));
//del_ohead(txn, o);
//del_clist(txn, o);
//del_body(txn, o);
//txn->commit(0);
//o->mark(is_deleted);
}
catch (wb_dbms_error &e) {
txn->abort();
}
return true;
}
#if 0
bool wb_dbms::deleteOset(pwr_tStatus *sts, wb_oset *o)
{
wb_dbms_txn *txn = 0;
m_env->txn_begin(m_txn, &txn, 0);
try {
//del_family(txn, o);
//unadopt(txn, wb_Position(o));
//del_ohead(txn, o);
//del_clist(txn, o);
//del_name(txn, o);
//del_body(txn, o);
txn->commit(0);
}
catch (wb_dbms_error &e) {
txn->abort();
}
return true;
}
#endif
bool wb_dbms::importVolume(wb_export &e)
{
try {
e.exportHead(*this);
e.exportRbody(*this);
e.exportDbody(*this);
e.exportMeta(*this);
return true;
}
catch (wb_dbms_error &e) {
printf("exeption: %s\n", e.what().c_str());
return false;
}
}
bool wb_dbms::importHead(pwr_tOid oid, pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, pwr_tOid aoid, pwr_tOid foid, pwr_tOid loid,
const char *name, const char *normname, pwr_mClassDef flags,
pwr_tTime ohTime, pwr_tTime rbTime, pwr_tTime dbTime,
size_t rbSize, size_t dbSize)
{
wb_dbms_ohead o(this, oid, cid, poid, boid, aoid, foid, loid, name, normname, flags, ohTime, rbTime, dbTime, rbSize, dbSize);
o.ins(m_txn);
wb_dbms_name n(this, oid, poid, normname);
int rc = n.ins(m_txn);
if (rc) {
char newName[50];
sprintf(newName, "O%u_%s", oid.oix, name);
newName[31] = '\0';
wb_name nn(newName);
o.name(nn);
o.upd(m_txn);
n.name(nn);
n.ins(m_txn);
}
wb_dbms_class c(this, cid, oid);
c.ins(m_txn);
if (oid.oix == pwr_cNOix) { // This is the volume object
wb_dbms_info i(this);
i.cid(cid);
i.vid(oid.vid);
i.name(name);
i.ins(m_txn);
}
return true;
}
bool wb_dbms::importRbody(pwr_tOid oid, size_t size, void *body)
{
wb_dbms_rbody b(this, oid, size, body);
wb_dbms_ohead oh(this, oid);
pwr_tTime time;
clock_gettime(CLOCK_REALTIME, &time);
oh.get(m_txn);
oh.rbTime(time);
oh.upd(m_txn);
b.ins(m_txn);
return true;
}
bool wb_dbms::importDbody(pwr_tOid oid, size_t size, void *body)
{
wb_dbms_dbody b(this, oid, size, body);
wb_dbms_ohead oh(this, oid);
pwr_tTime time;
clock_gettime(CLOCK_REALTIME, &time);
oh.get(m_txn);
oh.dbTime(time);
oh.upd(m_txn);
b.ins(m_txn);
return true;
}
bool wb_dbms::importMeta(dbs_sMenv *mep)
{
pwr_tStatus sts = 1;
printf("Import meta, my filename: %s\n", m_env->fileName());
if (mep != 0)
dbs_Split(&sts, mep, m_env->fileName());
return true;
}
int wb_dbms::initTables()
{
m_t_class = new wb_dbms_table(this);
m_t_class->queryGet(new wb_dbms_get_class(this));
m_t_class->querySucc(new wb_dbms_succ_class(this));
m_t_class->queryPred(new wb_dbms_pred_class(this));
m_t_class->queryIns(new wb_dbms_ins_class(this));
m_t_class->queryUpd(0);
m_t_class->queryDel(new wb_dbms_del_class(this));
m_t_class->queryCursor(new wb_dbms_cursor_class(this));
m_t_dbody = new wb_dbms_table(this);
m_t_dbody->queryGet(new wb_dbms_get_dbody(this));
m_t_dbody->querySucc(0);
m_t_dbody->queryPred(0);
m_t_dbody->queryIns(new wb_dbms_ins_dbody(this));
m_t_dbody->queryUpd(new wb_dbms_upd_dbody(this));
m_t_dbody->queryDel(new wb_dbms_del_dbody(this));
m_t_dbody->queryCursor(new wb_dbms_cursor_dbody(this));
m_t_info = new wb_dbms_table(this);
m_t_info->queryGet(new wb_dbms_get_info(this));
m_t_info->querySucc(0);
m_t_info->queryPred(0);
m_t_info->queryIns(new wb_dbms_ins_info(this));
m_t_info->queryUpd(new wb_dbms_upd_info(this));
m_t_info->queryDel(new wb_dbms_del_info(this));
m_t_info->queryCursor(NULL);
m_t_ohead = new wb_dbms_table(this);
m_t_ohead->queryGet(new wb_dbms_get_ohead(this));
m_t_ohead->querySucc(0);
m_t_ohead->queryPred(0);
m_t_ohead->queryIns(new wb_dbms_ins_ohead(this));
m_t_ohead->queryUpd(new wb_dbms_upd_ohead(this));
m_t_ohead->queryDel(new wb_dbms_del_ohead(this));
m_t_ohead->queryCursor(new wb_dbms_cursor_ohead(this));
m_t_rbody = new wb_dbms_table(this);
m_t_rbody->queryGet(new wb_dbms_get_rbody(this));
m_t_rbody->querySucc(0);
m_t_rbody->queryPred(0);
m_t_rbody->queryIns(new wb_dbms_ins_rbody(this));
m_t_rbody->queryUpd(new wb_dbms_upd_rbody(this));
m_t_rbody->queryDel(new wb_dbms_del_rbody(this));
m_t_rbody->queryCursor(new wb_dbms_cursor_rbody(this));
m_t_name = new wb_dbms_table(this);
m_t_name->queryGet(new wb_dbms_get_name(this));
m_t_name->querySucc(0);
m_t_name->queryPred(0);
m_t_name->queryIns(new wb_dbms_ins_name(this));
m_t_name->queryUpd(0);
m_t_name->queryDel(new wb_dbms_del_name(this));
m_t_name->queryCursor(new wb_dbms_cursor_name(this));
return 0;
}
wb_dbms_env::wb_dbms_env(const char *v_fileName) :
m_con(0), m_fileName(0), m_host(0), m_user(0), m_passwd(0), m_dbName(0), m_port(0), m_socket(0), m_exists(false)
{
fileName(v_fileName);
}
wb_dbms_env::wb_dbms_env(const char *v_host, const char *v_user, const char *v_passwd,
const char *v_dbName, unsigned int v_port, const char *v_socket) :
m_con(0), m_fileName(0), m_host(0), m_user(0), m_passwd(0), m_dbName(0), m_port(0), m_socket(0), m_exists(false)
{
host(v_host);
user(v_user);
passwd(v_passwd);
dbName(v_dbName);
port(v_port);
socket(v_socket);
}
void wb_dbms_env::host(const char *host)
{
if (!host)
return;
m_host = (char *)realloc(m_host, strlen(host));
strcpy(m_host, host);
}
void wb_dbms_env::user(const char *user)
{
if (!user)
return;
m_user = (char *)realloc(m_user, strlen(user));
strcpy(m_user, user);
}
void wb_dbms_env::passwd(const char *passwd)
{
if (!passwd)
return;
m_passwd = (char *)realloc(m_passwd, strlen(passwd));
strcpy(m_passwd, passwd);
}
void wb_dbms_env::dbName(const char *dbName)
{
if (!dbName)
return;
m_dbName = (char *)realloc(m_dbName, strlen(dbName));
strcpy(m_dbName, dbName);
}
void wb_dbms_env::fileName(const char *fileName)
{
if (!fileName)
return;
m_fileName = (char *)realloc(m_fileName, strlen(fileName));
strcpy(m_fileName, fileName);
}
void wb_dbms_env::port(const unsigned int port)
{
m_port = port;
}
void wb_dbms_env::socket(const char *socket)
{
if (!socket)
return;
m_socket = (char *)realloc(m_socket, strlen(socket));
strcpy(m_socket, socket);
}
wb_dbms_env::wb_dbms_env() :
m_con(0), m_fileName(0), m_host(0), m_user(0), m_passwd(0), m_dbName(0), m_port(0), m_socket(0), m_exists(false)
{
};
int wb_dbms_env::close()
{
return 0;
}
int wb_dbms_env::open(const char *v_host, const char *v_user, const char *v_passwd,
const char *v_dbName, unsigned int v_port, const char *v_socket)
{
host(v_host);
user(v_user);
passwd(v_passwd);
dbName(v_dbName);
port(v_port);
socket(v_socket);
m_con = mysql_init(NULL);
MYSQL *con = mysql_real_connect(m_con, host(), user(), passwd(), dbName(), port(), socket(), 0);
if (con == 0) {
printf("Failed to connect to database: Error: %s\n", mysql_error(m_con));
return 1;
}
char sql[255];
sprintf(sql, "use %s", dbName());
int rc = mysql_query(m_con, sql);
if (rc) {
printf("%s\n", mysql_error(m_con));
printf("%s\n", sql);
return rc;
} else {
printf("database open %s\n", sql);
}
return 0;
}
int wb_dbms_env::create(const char *v_fileName, const char *v_host, const char *v_user,
const char *v_passwd, const char *v_dbName, unsigned int v_port,
const char *v_socket)
{
fileName(v_fileName);
host(v_host);
user(v_user);
passwd(v_passwd);
dbName(v_dbName);
port(v_port);
socket(v_socket);
create();
return 0;
}
MYSQL *wb_dbms_env::createDb(void)
{
m_con = mysql_init(NULL);
MYSQL *con = mysql_real_connect(m_con, host(), user(), passwd(), 0, port(), socket(), 0);
printf("Tried to connect to database, con %x: Status: %s\n", (int)con, mysql_error(m_con));
if (con == 0) {
printf("Failed to connect to database: Error: %s\n", mysql_error(m_con));
return 0;
}
char sql[255];
sprintf(sql, "create database %s", dbName());
int rc = mysql_query(m_con, sql);
if (rc) {
printf("%s\n", mysql_error(m_con));
printf("%s\n", sql);
return 0;
}
sprintf(sql, "use %s", dbName());
rc = mysql_query(m_con, sql);
if (rc) {
printf("%s\n", mysql_error(m_con));
printf("%s\n", sql);
return 0;
}
return con;
}
MYSQL *wb_dbms_env::openDb()
{
m_con = mysql_init(NULL);
MYSQL *con = mysql_real_connect(m_con, host(), user(), passwd(), dbName(), port(), socket(), 0);
printf("Tried to connect to database, con %x: Status: %s\n", (int)con, mysql_error(m_con));
if (con == 0) {
printf("Failed to connect to database: Error: %s\n", mysql_error(m_con));
return 0;
}
return con;
}
int wb_dbms_env::create()
{
struct stat sb;
char name[512];
cdh_ToLower(m_fileName, m_fileName);
printf("wb_dbms_env::create: %s\n", m_fileName);
/* Create the directory, read/write/access owner and group. */
if (stat(name, &sb) != 0) {
if (mkdir(name, S_IRWXU | S_IRWXG) != 0) {
fprintf(stderr, "wb_dbms_env::create: mkdir: %s, %s\n", m_fileName, strerror(errno));
return errno;
}
}
sprintf(name, "%s/%s", m_fileName, "connection.dmsql");
if (stat(name, &sb) != 0) {
FILE *fp;
fp = fopen(name, "w+b");
if (fp == NULL) {
printf("** Cannot open file: %s, %s\n", name, strerror(errno));
return errno;
}
fprintf(fp, "HOST...: %s\n", host());
fprintf(fp, "USER...: %s\n", user());
fprintf(fp, "PASSWD.: %s\n", passwd());
fprintf(fp, "DB_NAME: %s\n", dbName());
fprintf(fp, "PORT...: %d\n", port());
fprintf(fp, "SOCKET.: %s\n", socket());
fclose(fp);
}
return 0;
}
int wb_dbms_env::open(const char* v_fileName)
{
fileName(v_fileName);
return open();
}
int wb_dbms_env::open(void)
{
char var[32];
char value[32];
char buf[512];
char *s;
char *valp;
int rc;
cdh_ToLower(m_fileName, m_fileName);
sprintf(buf, "%s/%s", m_fileName, "connection.dbms");
FILE *fp = fopen(buf, "r");
if (fp == NULL) {
printf("** Cannot open file: %s, %s\n", buf, strerror(errno));
return errno;
}
while ((s = fgets(buf, sizeof(buf) - 1, fp))) {
if (*s == '#')
continue;
rc = sscanf(s, " %[A-Z_] %*[^ ] %s", var, value);
if (rc < 1)
continue;
if (rc == 1)
valp = 0;
else
valp = value;
printf("rc: %d, var: %s, value: %s\n", rc, var, valp);
if (strcmp(valp, "(null)") == 0)
valp = 0;
if (strcmp(var, "HOST") == 0) {
host(valp);
}
else if (strcmp(var, "USER") == 0) {
user(valp);
}
else if (strcmp(var, "PASSWD") == 0) {
passwd(valp);
}
else if (strcmp(var, "DB_NAME") == 0) {
dbName(valp);
}
else if (strcmp(var, "PORT") == 0) {
if (valp == 0)
port(0);
else
port(atoi(valp));
}
else if (strcmp(var, "SOCKET") == 0) {
socket(valp);
}
else {
printf("Unknown connection parameter! : %s\n", var);
}
}
printf("ready!!!\n");
fclose(fp);
return 0;
}
int wb_dbms_env::txn_begin(wb_dbms_txn *pid, wb_dbms_txn **tid)
{
int rc = mysql_rollback(m_con);
if (rc)
printf("wb_dbms::abort, rc %d\n", rc);
rc = mysql_autocommit(m_con, 0);
if (rc)
printf("mysql_autocommit(m_con, 0) : %d\n", rc);
if (tid && !*tid) {
*tid = new wb_dbms_txn(this);
}
return rc;
}
wb_dbms_info::wb_dbms_info(wb_dbms *db) :
m_db(db), m_data(&m_volume, sizeof(m_volume))
{
}
void wb_dbms_info::get(wb_dbms_txn *txn)
{
int index = 1;
int ret;
wb_dbms_qe key(&index, sizeof(index));
wb_dbms_qe data(&m_volume, sizeof(m_volume));
try {
ret = m_db->m_t_info->get(txn, &key, &data);
printf("info get: %d\n", ret);
} catch (wb_dbms_error &e) {
printf("info get Error, %d\n", ret);
std::cout << e.what().c_str();
}
}
void wb_dbms_info::ins(wb_dbms_txn *txn)
{
int index = 1;
int ret;
m_key.data(&index);
m_key.size(sizeof(index));
m_key.bSize(sizeof(index));
ret = m_db->m_t_info->ins(txn, &m_key, &m_data);
printf("info ins: %d\n", ret);
}
void wb_dbms_info::upd(wb_dbms_txn *txn)
{
int index = 1;
int ret;
m_key.data(&index);
m_key.size(sizeof(index));
m_key.bSize(sizeof(index));
ret = m_db->m_t_info->upd(txn, &m_key, &m_data);
printf("info ins: %d\n", ret);
}
wb_dbms_class::wb_dbms_class(wb_dbms *db) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_dbc(0)
{
}
wb_dbms_class::wb_dbms_class(wb_dbms *db, wb_dbms_txn *txn, pwr_tCid cid) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_dbc(0)
{
m_k.oix = pwr_cNOix;
m_k.cid = cid;
}
wb_dbms_class::wb_dbms_class(wb_dbms *db, pwr_tCid cid, pwr_tOid oid) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_dbc(0)
{
m_k.oix = oid.oix;
m_k.cid = cid;
}
wb_dbms_class::wb_dbms_class(wb_dbms *db, wb_dbms_ohead &o) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_dbc(0)
{
m_k.oix = o.oid().oix;
m_k.cid = o.cid();
}
bool wb_dbms_class::succ(pwr_tOid oid)
{
m_k.oix = oid.oix;
int rc = m_db->m_t_class->succ(m_db->m_txn, &m_key, 0);
return rc == 0;
}
bool wb_dbms_class::succClass(pwr_tCid cid)
{
m_k.cid = cid + 1;
m_k.oix = pwr_cNOix;
int rc = m_db->m_t_class->succ(m_db->m_txn, &m_key, 0);
return rc == 0;
}
bool wb_dbms_class::pred(pwr_tOid oid)
{
m_k.oix = oid.oix;
int rc = m_db->m_t_class->pred(m_db->m_txn, &m_key, 0);
return rc == 0;
}
int wb_dbms_class::ins(wb_dbms_txn *txn)
{
return m_db->m_t_class->ins(txn, &m_key, 0);
}
int wb_dbms_class::upd(wb_dbms_txn *txn)
{
return m_db->m_t_class->upd(txn, &m_key, 0);
}
int wb_dbms_class::del(wb_dbms_txn *txn)
{
return m_db->m_t_class->del(txn, &m_key, 0);
}
void wb_dbms_class::iter(void (*func)(pwr_tOid oid, pwr_tCid cid))
{
m_db->m_t_class->cursor(m_db->m_txn, &m_key, 0, &m_dbc);
/* Initialize the key/data pair so the flags aren't set. */
memset(&m_k, 0, sizeof(m_k));
m_key.data(&m_k);
m_key.size(sizeof(m_k));
m_key.bSize(sizeof(m_k));
/* Walk through the database. */
while (m_dbc->get() == 0) {
pwr_tOid oid;
oid.oix = m_k.oix;
oid.vid = m_db->vid();
func(oid, m_k.cid);
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
wb_dbms_class::~wb_dbms_class()
{
if (m_dbc)
m_dbc->close();
}
wb_dbms_class_iterator::wb_dbms_class_iterator(wb_dbms *db) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_atEnd(false), m_rc(0)
{
memset(&m_k, 0, sizeof(m_k));
m_atEnd = (m_rc != 0);
}
wb_dbms_class_iterator::wb_dbms_class_iterator(wb_dbms *db, pwr_tCid cid) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_atEnd(false), m_rc(0)
{
memset(&m_k, 0, sizeof(m_k));
m_atEnd = (m_rc != 0);
m_k.oix = pwr_cNOix;
m_k.cid = cid;
}
wb_dbms_class_iterator::wb_dbms_class_iterator(wb_dbms *db, pwr_tCid cid, pwr_tOid oid) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_atEnd(false), m_rc(0)
{
memset(&m_k, 0, sizeof(m_k));
m_atEnd = (m_rc != 0);
m_k.oix = oid.oix;
m_k.cid = cid;
}
bool wb_dbms_class_iterator::first()
{
m_k.oix = pwr_cNOix;
m_k.cid = pwr_cNCid;
m_rc = m_db->m_t_class->succ(m_db->m_txn, &m_key, 0);
m_atEnd = (m_rc != 0);
return !m_atEnd;
}
bool wb_dbms_class_iterator::succObject()
{
if (!m_atEnd) {
m_rc = m_db->m_t_class->succ(m_db->m_txn, &m_key, 0);
m_atEnd = (m_rc != 0);
}
return !m_atEnd;
}
bool wb_dbms_class_iterator::succClass()
{
m_k.oix = pwr_cNOix;
m_k.cid++;
m_rc = m_db->m_t_class->succ(m_db->m_txn, &m_key, 0);
m_atEnd = (m_rc != 0);
return !m_atEnd;
}
bool wb_dbms_class_iterator::succClass(pwr_tCid cid)
{
m_k.oix = pwr_cNOix;
m_k.cid = cid + 1;
m_rc = m_db->m_t_class->succ(m_db->m_txn, &m_key, 0);
m_atEnd = (m_rc != 0);
return !m_atEnd;
}
wb_dbms_class_iterator::~wb_dbms_class_iterator()
{
}
wb_dbms_name::wb_dbms_name(wb_dbms *db, wb_dbms_txn *txn) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_data(&m_d, sizeof(m_d))
{
memset(&m_k, 0, sizeof(m_k));
m_k.poid = pwr_cNOid;
}
wb_dbms_name::wb_dbms_name(wb_dbms *db, wb_dbms_ohead &o) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_data(&m_d, sizeof(m_d))
{
memset(&m_k, 0, sizeof(m_k));
m_k.poid = o.poid();
strcpy(m_k.normname, o.normname());
m_d.oid = o.oid();
}
wb_dbms_name::wb_dbms_name(wb_dbms *db, pwr_tOid oid, pwr_tOid poid, const char *name) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_data(&m_d, sizeof(m_d))
{
wb_name n(name);
memset(&m_k, 0, sizeof(m_k));
m_k.poid = poid;
strcpy(m_k.normname, n.normName(cdh_mName_object));
m_d.oid = oid;
}
wb_dbms_name::wb_dbms_name(wb_dbms *db, wb_dbms_txn *txn, pwr_tOid poid, wb_name &name) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_data(&m_d, sizeof(m_d))
{
memset(&m_k, 0, sizeof(m_k));
m_k.poid = poid;
strcpy(m_k.normname, name.normName(cdh_mName_object));
m_d.oid = pwr_cNOid;
}
wb_dbms_name::wb_dbms_name(wb_dbms *db, pwr_tOid poid, const char *name) :
m_db(db), m_key(&m_k, sizeof(m_k)), m_data(&m_d, sizeof(m_d))
{
memset(&m_k, 0, sizeof(m_k));
memset(&m_d, 0, sizeof(m_d));
m_k.poid = poid;
strcpy(m_k.normname, name);
}
int wb_dbms_name::get(wb_dbms_txn *txn)
{
m_data.bSize(sizeof(m_d));
int rc = m_db->m_t_name->get(txn, &m_key, &m_data);
return rc;
}
int wb_dbms_name::ins(wb_dbms_txn *txn)
{
return m_db->m_t_name->ins(txn, &m_key, &m_data);
}
int wb_dbms_name::upd(wb_dbms_txn *txn)
{
return m_db->m_t_name->upd(txn, &m_key, &m_data);
}
int wb_dbms_name::del(wb_dbms_txn *txn)
{
return m_db->m_t_name->del(txn, &m_key, 0);
}
void wb_dbms_name::name(wb_name &name)
{
memset(m_k.normname, 0, sizeof(m_k.normname));
strcpy(m_k.normname, name.normName(cdh_mName_object));
}
void wb_dbms_name::iter(void (*func)(pwr_tOid poid, pwr_tObjName name, pwr_tOid oid))
{
int rc = 0;
m_db->m_t_name->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
memset(&m_k, 0, sizeof(m_k));
memset(&m_d, 0, sizeof(m_d));
/* Walk through the database and print out the key/data pairs. */
while ((rc = m_dbc->get()) == 0) {
func(m_k.poid, m_k.normname, m_d.oid);
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
wb_dbms_ohead::wb_dbms_ohead() :
m_db(0), m_key(&m_oid, sizeof(m_oid)), m_data(&m_o, sizeof(m_o))
{
memset(&m_o, 0, sizeof(m_o));
}
wb_dbms_ohead::wb_dbms_ohead(wb_dbms *db) :
m_db(db), m_key(&m_oid, sizeof(m_oid)), m_data(&m_o, sizeof(m_o))
{
memset(&m_o, 0, sizeof(m_o));
}
wb_dbms_ohead::wb_dbms_ohead(wb_dbms *db, pwr_tOid oid) :
m_db(db), m_key(&m_oid, sizeof(m_oid)), m_data(&m_o, sizeof(m_o))
{
memset(&m_o, 0, sizeof(m_o));
m_oid = m_o.oid = oid;
}
wb_dbms_ohead::wb_dbms_ohead(wb_dbms *db, wb_dbms_txn *txn, pwr_tOid oid) :
m_db(db), m_key(&m_oid, sizeof(m_oid)), m_data(&m_o, sizeof(m_o))
{
memset(&m_o, 0, sizeof(m_o));
m_oid = m_o.oid = oid;
get(txn);
}
wb_dbms_ohead::wb_dbms_ohead(wb_dbms *db, pwr_tOid oid, pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, pwr_tOid aoid, pwr_tOid foid, pwr_tOid loid,
const char *name, const char *normname, pwr_mClassDef flags,
pwr_tTime ohTime, pwr_tTime rbTime, pwr_tTime dbTime,
size_t rbSize, size_t dbSize) :
m_db(db), m_key(&m_oid, sizeof(m_oid)), m_data(&m_o, sizeof(m_o))
{
memset(&m_o, 0, sizeof(m_o));
m_oid = m_o.oid = oid;
m_o.cid = cid;
m_o.poid = poid;
strcpy(m_o.name, name);
strcpy(m_o.normname, normname);
m_o.time = ohTime;
m_o.boid = boid;
m_o.aoid = aoid;
m_o.foid = foid;
m_o.loid =loid;
m_o.flags = flags;
m_o.body[0].time = rbTime;
m_o.body[0].size = rbSize;
m_o.body[1].time = dbTime;
m_o.body[1].size = dbSize;
}
wb_dbms_ohead &wb_dbms_ohead::get(wb_dbms_txn *txn)
{
int rc = 0;
m_data.size(sizeof(m_o));
m_data.bSize(sizeof(m_o));
rc = m_db->m_t_ohead->get(txn, &m_key, &m_data);
if (rc)
throw wb_dbms_error(m_db, "wb_dbms_ohead::get(txn, &m_key, &m_data)");
return *this;
}
int wb_dbms_ohead::ins(wb_dbms_txn *txn)
{
return m_db->m_t_ohead->ins(txn, &m_key, &m_data);
}
int wb_dbms_ohead::upd(wb_dbms_txn *txn)
{
return m_db->m_t_ohead->upd(txn, &m_key, &m_data);
}
wb_dbms_ohead &wb_dbms_ohead::get(wb_dbms_txn *txn, pwr_tOid oid)
{
int rc = 0;
m_oid = oid;
rc = m_db->m_t_ohead->get(txn, &m_key, &m_data);
if ( rc /*////== DB_NOTFOUND*/)
throw wb_dbms_error(m_db, "wb_dbms_ohead::get(wb_dbms_txn *txn, pwr_tOid oid)");
if (rc)
printf("wb_db_ohead::get(txn, oid = %d.%d), get, rc %d\n", oid.vid, oid.oix, rc);
if (oid.oix != m_o.oid.oix)
printf("oid.oix (%d.%d) != m_o.oid.oix (%d.%d), %s\n", oid.vid, oid.oix, m_o.oid.vid, m_o.oid.oix, m_o.name);
return *this;
}
int wb_dbms_ohead::del(wb_dbms_txn *txn)
{
return m_db->m_t_ohead->del(txn, &m_key, 0);
}
void wb_dbms_ohead::name(wb_name &name)
{
memset(m_o.name, 0, sizeof(m_o.name));
memset(m_o.normname, 0, sizeof(m_o.normname));
strcpy(m_o.name, name.name(cdh_mName_object));
strcpy(m_o.normname, name.normName(cdh_mName_object));
}
void wb_dbms_ohead::name(pwr_tOid &oid)
{
memset(m_o.name, 0, sizeof(m_o.name));
memset(m_o.normname, 0, sizeof(m_o.normname));
sprintf(m_o.name, "O%d", oid.oix);
strcpy(m_o.normname, m_o.name);
}
void wb_dbms_ohead::clear()
{
memset(&m_o, 0, sizeof(m_o));
}
void wb_dbms_ohead::iter(void (*func)(pwr_tOid oid, dbms_sObject *op))
{
int rc = 0;
rc = m_db->m_t_ohead->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
/* Initialize the key/data pair so the flags aren't set. */
memset(&m_oid, 0, sizeof(m_oid));
memset(&m_o, 0, sizeof(m_o));
/* Walk through the database and print out the key/data pairs. */
while ((rc = m_dbc->get()) == 0) {
func(m_oid, &m_o);
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
void wb_dbms_ohead::iter(wb_import &i)
{
int rc = 0;
rc = m_db->m_t_ohead->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
memset(&m_oid, 0, sizeof(m_oid));
memset(&m_o, 0, sizeof(m_o));
while ((rc = m_dbc->get()) == 0) {
i.importHead(m_o.oid, m_o.cid, m_o.poid, m_o.boid, m_o.aoid, m_o.foid, m_o.loid, m_o.name, m_o.normname,
m_o.flags, m_o.time, m_o.body[0].time, m_o.body[1].time, m_o.body[0].size, m_o.body[1].size);
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
wb_dbms_rbody::wb_dbms_rbody(wb_dbms *db, pwr_tOid oid, size_t size, void *p) :
m_db(db), m_oid(oid), m_size(size), m_p(p), m_key(&m_oid, sizeof(m_oid)), m_data(p, size)
{
}
wb_dbms_rbody::wb_dbms_rbody(wb_dbms *db) :
m_db(db), m_oid(pwr_cNOid), m_size(0), m_p(0), m_key(&m_oid, sizeof(m_oid)), m_data(0, 0)
{
}
wb_dbms_rbody::wb_dbms_rbody(wb_dbms *db, pwr_tOid oid) :
m_db(db), m_oid(oid), m_size(0), m_p(0), m_key(&m_oid, sizeof(m_oid)), m_data(0, 0)
{
}
int wb_dbms_rbody::ins(wb_dbms_txn *txn)
{
return m_db->m_t_rbody->ins(txn, &m_key, &m_data);
}
int wb_dbms_rbody::upd(wb_dbms_txn *txn, size_t offset, size_t size, void *p)
{
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_data.data(m_db->m_buf);
int rc = m_db->m_t_rbody->get(txn, &m_key, &m_data);
if (rc)
return rc;
if (m_data.size() < size + offset)
printf("*** rbody::upd(offset %d, size %d, oix %d), size: %d\n", offset, size, m_oid.oix, m_data.size());
memcpy(m_db->m_buf + offset, p, size);
return m_db->m_t_rbody->upd(txn, &m_key, &m_data);
}
int wb_dbms_rbody::get(wb_dbms_txn *txn, size_t offset, size_t size, void *p)
{
m_data.bSize(sizeof(m_db->m_buf));
m_data.size(sizeof(m_db->m_buf));
m_data.data(m_db->m_buf);
int rc = m_db->m_t_rbody->get(txn, &m_key, &m_data);
if (rc)
return rc;
assert(sizeof(m_db->m_buf) >= size + offset);
if (m_data.size() < size + offset)
printf("*** rbody::get(offset %d, size %d, oix %d), size: %d\n", offset, size, m_oid.oix, m_data.size());
memcpy(p, m_db->m_buf + offset, size);
return 0;
}
int wb_dbms_rbody::del(wb_dbms_txn *txn)
{
return m_db->m_t_rbody->del(txn, &m_key, 0);
}
void wb_dbms_rbody::iter(void (*print)(pwr_tOid oid, size_t size))
{
int rc = 0;
memset(&m_oid, 0, sizeof(m_oid));
m_data.data(m_db->m_buf);
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_db->m_t_rbody->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
/* Walk through the database and print out the key/data pairs. */
while (1) {
try {
rc = m_dbc->get();
}
catch (wb_dbms_error &e) {
printf("Exc: %s\n", e.what().c_str());
}
if (rc != 0)
break;
print(m_oid, m_data.size());
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
void wb_dbms_rbody::iter(wb_import &i)
{
int rc = 0;
memset(&m_oid, 0, sizeof(m_oid));
m_data.data(m_db->m_buf);
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_db->m_t_rbody->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
while (1) {
try {
rc = m_dbc->get();
}
catch (wb_dbms_error &e) {
printf("Exc: %s\n", e.what().c_str());
}
if (rc != 0)
break;
i.importRbody(m_oid, m_data.size(), m_data.data());
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
wb_dbms_dbody::wb_dbms_dbody(wb_dbms *db, pwr_tOid oid, size_t size, void *p) :
m_db(db), m_oid(oid), m_size(size), m_p(p), m_key(&m_oid, sizeof(m_oid)), m_data(p, size)
{
}
wb_dbms_dbody::wb_dbms_dbody(wb_dbms *db) :
m_db(db), m_oid(pwr_cNOid), m_size(0), m_p(0), m_key(&m_oid, sizeof(m_oid)), m_data(0, 0)
{
}
wb_dbms_dbody::wb_dbms_dbody(wb_dbms *db, pwr_tOid oid) :
m_db(db), m_oid(oid), m_size(0), m_p(0), m_key(&m_oid, sizeof(m_oid)), m_data(0, 0)
{
}
int wb_dbms_dbody::ins(wb_dbms_txn *txn)
{
return m_db->m_t_dbody->ins(txn, &m_key, &m_data);
}
int wb_dbms_dbody::upd(wb_dbms_txn *txn, size_t offset, size_t size, void *p)
{
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_data.data(m_db->m_buf);
int rc = m_db->m_t_dbody->get(txn, &m_key, &m_data);
if (rc)
return rc;
if (m_data.size() < size + offset)
printf("*** dbody::upd(offset %d, size %d, oix %d), size: %d\n", offset, size, m_oid.oix, m_data.size());
memcpy(m_db->m_buf + offset, p, size);
return m_db->m_t_dbody->upd(txn, &m_key, &m_data);
}
int wb_dbms_dbody::get(wb_dbms_txn *txn, size_t offset, size_t size, void *p)
{
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_data.data(m_db->m_buf);
// printf("--- dbody::get(offset %d, size %d, oix %d)\n", offset, size, m_oid.oix);
int rc = m_db->m_t_dbody->get(txn, &m_key, &m_data);
if (rc)
return rc;
assert(sizeof(m_db->m_buf) >= size + offset);
if (m_data.size() < size + offset)
printf("*** dbody::get(offset %d, size %d, oix %d), size: %d\n", offset, size, m_oid.oix, m_data.size());
memcpy(p, m_db->m_buf + offset, size);
return 0;
}
int wb_dbms_dbody::del(wb_dbms_txn *txn)
{
return m_db->m_t_dbody->del(txn, &m_key, 0);
}
void wb_dbms_dbody::iter(void (*print)(pwr_tOid oid, size_t size))
{
int rc = 0;
memset(&m_oid, 0, sizeof(m_oid));
m_data.data(m_db->m_buf);
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_db->m_t_dbody->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
/* Walk through the database and print out the key/data pairs. */
while (1) {
try {
rc = m_dbc->get();
}
catch (wb_dbms_error &e) {
printf("Exc: %s\n", e.what().c_str());
}
if (rc != 0)
break;
print(m_oid, m_data.size());
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
void wb_dbms_dbody::iter(wb_import &i)
{
int rc = 0;
memset(&m_oid, 0, sizeof(m_oid));
m_data.data(m_db->m_buf);
m_data.size(sizeof(m_db->m_buf));
m_data.bSize(sizeof(m_db->m_buf));
m_db->m_t_dbody->cursor(m_db->m_txn, &m_key, &m_data, &m_dbc);
/* Walk through the database and print out the key/data pairs. */
while (1) {
try {
rc = m_dbc->get();
}
catch (wb_dbms_error &e) {
printf("Exc: %s\n", e.what().c_str());
}
if (rc != 0)
break;
i.importDbody(m_oid, m_data.size(), m_data.data());
}
m_dbc->close();
delete m_dbc;
m_dbc = 0;
}
int wb_dbms_txn::commit()
{
int rc;
rc = mysql_commit(m_env->con());
if (rc)
printf("wb_dbms::commit, rc %d\n", rc);
return rc;
}
int wb_dbms_txn::abort()
{
int rc = 0;
rc = mysql_rollback(m_env->con());
if (rc)
printf("wb_dbms::abort, rc %d\n", rc);
return rc;
}
int wb_dbms_txn::subBegin()
{
int rc = mysql_query(m_env->con(), "savepoint sub");
if (rc) goto error;
return rc;
error:
printf("%s rc %d, %s\n", "wb_dbms::subBegin()", rc, mysql_error(m_env->con()));
//throw wb_error(DB__TXNERROR);
return 1;
}
int wb_dbms_txn::subAbort()
{
int rc = mysql_query(m_env->con(), "rollback to savepoint sub");
if (rc) goto error;
return rc;
error:
printf("%s rc %d, %s\n", "wb_dbms::subAbort()", rc, mysql_error(m_env->con()));
//throw wb_error(DB__TXNERROR);
return 1;
}
int wb_dbms_query::prepare(const char *query, int nResult, int nParam)
{
int rc = 0;
static const char *method = "prepare";
if (!m_prepared) {
m_query = query;
m_stmt = mysql_stmt_init(m_db->con());
if (m_stmt == 0) error(method, "mysql_stmt_init");
rc = mysql_stmt_prepare(m_stmt, query, strlen(query));
if (rc) error(rc, method, "mysql_stmt_prepare");
m_nParam = mysql_stmt_param_count(m_stmt);
m_nResult = mysql_stmt_field_count(m_stmt);
assert((m_nParam == nParam) && (m_nResult == nResult));
if (m_nParam > 0) {
m_param.bind = (MYSQL_BIND *)calloc(m_nParam, sizeof(MYSQL_BIND));
m_param.length = (size_t *)calloc(m_nParam, sizeof(size_t));
m_param.is_null = (my_bool *)calloc(m_nParam, sizeof(my_bool));
for (int i = m_nParam - 1; i >= 0; i--) {
m_param.bind[i].is_null = &m_param.is_null[i];
m_param.bind[i].length = (long unsigned int *)&m_param.length[i];
}
}
if (m_nResult > 0) {
m_result.bind = (MYSQL_BIND *)calloc(m_nResult, sizeof(MYSQL_BIND));
m_result.length = (size_t *)calloc(m_nParam, sizeof(size_t));
m_result.is_null = (my_bool *)calloc(m_nResult, sizeof(my_bool));
for (int i = m_nResult - 1; i >= 0; i--) {
m_result.bind[i].is_null = &m_result.is_null[i];
m_result.bind[i].length = (long unsigned int *)&m_result.length[i];
}
}
m_prepared = true;
}
return rc;
}
int wb_dbms_query::bindQuery(void)
{
int rc = 0;
static const char *method = "bindQuery";
if (m_nParam > 0) {
rc = mysql_stmt_bind_param(m_stmt, m_param.bind);
if (rc) error(rc, method, "mysql_stmt_bind_param");
}
if (m_nResult > 0) {
rc = mysql_stmt_bind_result(m_stmt, m_result.bind);
if (rc) error(rc, method, "mysql_stmt_bind_result");
}
return rc;
}
void wb_dbms_query::bindParam(int index, enum enum_field_types type, char *var)
{
m_param.bind[index].buffer_type = type;
m_param.bind[index].buffer = var;
}
void wb_dbms_query::bindParam(int index, enum enum_field_types type, char *var, size_t size)
{
m_param.bind[index].buffer_type = type;
m_param.bind[index].buffer = var;
m_param.bind[index].buffer_length = size;
m_param.length[index] = size;
}
void wb_dbms_query::bindParam(int index, enum enum_field_types type, char *var, size_t size, size_t bsize)
{
m_param.bind[index].buffer_type = type;
m_param.bind[index].buffer = var;
m_param.bind[index].buffer_length = size;
m_param.length[index] = bsize;
}
void wb_dbms_query::bindParam(int index, enum enum_field_types type, wb_dbms_qe *par)
{
m_param.bind[index].buffer_type = type;
m_param.bind[index].buffer = par->data();
m_param.bind[index].buffer_length = par->bSize();
m_param.bind[index].length = (long unsigned int *)par->a_size();
m_param.bind[index].is_null = par->a_isNull();
}
void wb_dbms_query::bindResult(int index, enum enum_field_types type, char *var)
{
m_result.bind[index].buffer_type = type;
m_result.bind[index].buffer = var;
}
void wb_dbms_query::bindResult(int index, enum enum_field_types type, char *var, size_t size)
{
m_result.bind[index].buffer_type = type;
m_result.bind[index].buffer = var;
m_result.bind[index].buffer_length = size;
m_result.length[index] = size;
}
void wb_dbms_query::bindResult(int index, enum enum_field_types type, char *var, size_t size, size_t bsize)
{
m_result.bind[index].buffer_type = type;
m_result.bind[index].buffer = var;
m_result.bind[index].buffer_length = size;
m_result.length[index] = bsize;
}
void wb_dbms_query::bindResult(int index, enum enum_field_types type, wb_dbms_qe *par)
{
m_result.bind[index].buffer_type = type;
m_result.bind[index].buffer = par->data();
m_result.bind[index].buffer_length = par->bSize();
m_result.bind[index].length = (long unsigned int *)par->a_size();
m_result.bind[index].is_null = par->a_isNull();
}
void wb_dbms_query::error(int rc, const char *method, const char *func)
{
char s[200];
if (m_stmt) mysql_stmt_close(m_stmt);
m_stmt = 0;
m_prepared = false;
sprintf(s, "*** query \"%s\" %s %s %d %s\n", m_query, method, func, rc, mysql_error(m_db->con()));
throw wb_dbms_error(m_db, s);
}
void wb_dbms_query::error(const char *method, const char *func)
{
char s[200];
if (m_stmt) mysql_stmt_close(m_stmt);
m_stmt = 0;
m_prepared = false;
sprintf(s, "*** query \"%s\" %s %s %s\n", m_query, method, func, mysql_error(m_db->con()));
throw wb_dbms_error(m_db, s);
}
int wb_dbms_table::create(const char *query)
{
int rc = 0;
rc = mysql_query(m_db->con(), query);
if (rc) {
printf("%s\n", mysql_error(m_db->con()));
printf("%s\n", query);
}
return rc;
}
int wb_dbms_table::close()
{
return 0;
}
int wb_dbms_table::cursor(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data, wb_dbms_cursor **cp)
{
int rc = m_q_cursor->execute(txn, key, data);
if (rc != 0)
return rc;
*cp = new wb_dbms_cursor(m_q_cursor);
return 0;
}
wb_dbms_error::wb_dbms_error(wb_dbms *db, string str) : m_error_str(str)
{
m_errno = errno;
m_db = db;
if (db)
m_sql_error = mysql_error(m_db->con());
}
string wb_dbms_error::what() const
{
string s;
s = m_error_str + ", " + m_sql_error;
return s;
}
#endif
/*
* Proview $Id: wb_dbms.h,v 1.1 2007-10-18 09:11:01 claes Exp $
* Copyright (C) 2007 SSAB Oxelösund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#ifndef wb_dbms_h
#define wb_dbms_h
#if defined PWRE_CONF_MYSQL
#include <assert.h>
#include "pwr.h"
#include <mysql/mysql.h>
#include "wb_import.h"
#include <exception>
#include <string>
#include <errno.h>
class wb_name;
typedef struct {
pwr_tOid oid; /**< object identifier */
pwr_tCid cid; /**< class identifier */
pwr_tOid poid; /**< object identifier of parent */
pwr_tObjName name; /**< name of object */
pwr_tObjName normname; /**< normalized object name. */
pwr_tTime time; /**< time of last change in object header */
pwr_tOid boid; /**< object before this object. */
pwr_tOid aoid; /**< object after this object. */
pwr_tOid foid; /**< first child object. */
pwr_tOid loid; /**< last child object. */
pwr_mClassDef flags;
struct {
pwr_tTime time;
size_t size;
} body[2]; /**< bodies */
} dbms_sObject;
typedef struct
{
MYSQL_BIND *bind;
my_bool *is_null;
size_t *length;
} dbms_sBind;
class wb_dbms;
class wb_dbms_txn;
class wb_dbms_ohead;
class wb_destination;
class wb_dbms_table;
class wb_dbms_env;
class wb_dbms_txn
{
public:
wb_dbms_env *m_env;
wb_dbms_txn() {;}
wb_dbms_txn(wb_dbms_env *env) : m_env(env) {;}
wb_dbms_txn(const wb_dbms_txn &);
void operator = (const wb_dbms_txn &);
virtual ~ wb_dbms_txn() {;}
int abort();
int commit();
int subAbort();
int subBegin();
int subCommit() { return 0;}
void set_env(wb_dbms_env *env) {m_env = env;}
};
class wb_dbms_env
{
public:
MYSQL *m_con;
char *m_fileName;
char *m_host;
char *m_user;
char *m_passwd;
char *m_dbName;
unsigned int m_port;
char *m_socket;
bool m_exists;
/* Create a new file system environment:
wb_dbms_env *env = new wb_dbms_env();
env->create(fileName, host, user, passwd, dbName, port, socket);
MYSQL *con = env->createDb();
or:
wb_dbms_env *env = new wb_dbms_env(fileName, host, user, passwd, dbName, port, socket);
env->create();
MYSQL *con = env->createDb();
*/
wb_dbms_env();
/* Open an existing file system environment:
wb_dbms_env *env = new wb_dbms_env(fileName);
env->open();
MYSQL *con = env->openDb();
or:
wb_dbms_env *env = new wb_dbms_env();
env->open(fileName);
MYSQL *con = env->openDb();
*/
wb_dbms_env(const char *fileName);
/* Environment without file system environment:
wb_dbms_env *env = new wb_dbms_env(host, user, passwd, dbName, port, socket);
env->open();
MYSQL *con = env->openDb();
or:
wb_dbms_env *env = new wb_dbms_env();
env->open(host, user, passwd, dbName, port, socket);
MYSQL *con = env->openDb();
*/
wb_dbms_env(const char *host, const char *user, const char *passwd,
const char *dbName, unsigned int port, const char *socket);
/* Stop copying. */
wb_dbms_env(const wb_dbms_env &);
void operator = (const wb_dbms_env &);
virtual ~ wb_dbms_env() { close();}
int create(const char *fileName, const char *host, const char *user, const char *passwd,
const char *dbName, unsigned int port, const char *socket);
int open(void);
int open(const char *fileName);
int open(const char *host, const char *user, const char *passwd,
const char *dbName, unsigned int port, const char *socket);
MYSQL *createDb(void);
MYSQL *openDb(void);
bool exists() { return m_exists;}
int close(void);
void fileName(const char *fileName);
void host(const char *host);
void user(const char *user);
void passwd(const char *passwd);
void dbName(const char *dbName);
void port(unsigned int port);
void socket(const char *socket);
inline char *fileName(void) { return m_fileName;}
inline char *host(void) { return m_host;}
inline char *user(void) { return m_user;}
inline char *passwd(void) { return m_passwd;}
inline char *dbName(void) { return m_dbName;}
inline unsigned int port(void) { return m_port;}
inline char *socket(void) { return m_socket;}
inline MYSQL *con(void) {
return m_con;
}
int txn_begin(wb_dbms_txn *pid, wb_dbms_txn **tid);
private:
int create();
};
class wb_dbms_qe
{
public:
char *m_data;
int m_off;
size_t m_size;
size_t m_bSize;
my_bool m_isNull;
wb_dbms_qe() : m_data(0), m_off(0), m_size(0), m_bSize(0), m_isNull(0) {;}
wb_dbms_qe(void *data, size_t size) : m_data((char *)data), m_off(0), m_size(size), m_bSize(size), m_isNull(0) {;}
~wb_dbms_qe() {;}
wb_dbms_qe(const wb_dbms_qe &);
void operator = (const wb_dbms_qe &);
void data(void *data) { m_data = (char *)data; }
char *data() const { return m_data; }
void size(size_t size) { m_size = size; }
size_t size() const { return m_size; }
void offset(size_t off) { m_off = off; }
size_t offset() const { return m_off; }
void bSize(size_t bSize) { m_bSize = bSize; }
size_t bSize() const { return m_bSize; }
size_t *a_size() { return &m_size; }
my_bool *a_isNull() { return &m_isNull; }
};
class wb_dbms_query
{
public:
wb_dbms *m_db;
bool m_prepared;
MYSQL_STMT *m_stmt;
dbms_sBind m_result;
dbms_sBind m_param;
const char *m_query;
int m_nResult;
int m_nParam;
wb_dbms_query() : m_db(0), m_prepared(false), m_stmt(0) {;}
virtual ~wb_dbms_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
int prepare(const char *query, int nResult, int nParam);
void bindParam(int index, enum enum_field_types type);
void bindParam(int index, char *var);
void bindParam(int index, enum enum_field_types type, char *var);
void bindParam(int index, char *var, size_t size);
void bindParam(int index, enum enum_field_types type, char *var, size_t size);
void bindParam(int index, enum enum_field_types type, char *var, size_t size, size_t bsize);
void bindParam(int index, enum enum_field_types type, wb_dbms_qe *par);
void bindResult(int index, enum enum_field_types type);
void bindResult(int index, char *var);
void bindResult(int index, enum enum_field_types type, char *var);
void bindResult(int index, char *var, size_t size);
void bindResult(int index, enum enum_field_types type, char *var, size_t size);
void bindResult(int index, enum enum_field_types type, char *var, size_t size, size_t bsize);
void bindResult(int index, enum enum_field_types type, wb_dbms_qe *par);
int bindQuery(void);
void error(const char *method, const char* function);
void error(int rc, const char *method, const char* function);
};
class wb_dbms_cursor
{
public:
wb_dbms_query *m_query;
wb_dbms_cursor(wb_dbms_query *query) : m_query(query) {;}
~wb_dbms_cursor() {;}
inline int get()
{
return mysql_stmt_fetch(m_query->m_stmt);
}
inline int count() { return 0;}
inline int close()
{
return mysql_stmt_free_result(m_query->m_stmt);
}
};
class wb_dbms_table
{
public:
wb_dbms *m_db;
wb_dbms_query *m_q_get;
wb_dbms_query *m_q_succ;
wb_dbms_query *m_q_pred;
wb_dbms_query *m_q_ins;
wb_dbms_query *m_q_upd;
wb_dbms_query *m_q_del;
wb_dbms_query *m_q_cursor;
wb_dbms_table(wb_dbms *db) : m_db(db) {;}
virtual ~wb_dbms_table() {;}
int create(const char *query);
int close();
int open(wb_dbms_txn *txn, const char *name, const char *subname, int dbtype, int mode);
int cursor(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data, wb_dbms_cursor **cp);
inline void queryGet(wb_dbms_query *query) {
m_q_get = query;
}
inline void querySucc(wb_dbms_query *query) {
m_q_succ = query;
}
inline void queryPred(wb_dbms_query *query) {
m_q_pred = query;
}
inline void queryIns(wb_dbms_query *query) {
m_q_ins = query;
}
inline void queryUpd(wb_dbms_query *query) {
m_q_upd = query;
}
inline void queryDel(wb_dbms_query *query) {
m_q_del = query;
}
inline void queryCursor(wb_dbms_query *query) {
m_q_cursor = query;
}
inline int get(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
return m_q_get->execute(txn, key, data);
}
inline int succ(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
return m_q_succ->execute(txn, key, data);
}
inline int pred(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
return m_q_pred->execute(txn, key, data);
}
inline int ins(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
return m_q_ins->execute(txn, key, data);
}
inline int upd(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
return m_q_upd->execute(txn, key, data);
}
inline int del(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
return m_q_del->execute(txn, key, data);
}
/*virtual*/ void err(int, const char *, ...);
};
class wb_dbms : public wb_import
{
public:
pwr_tVid m_vid;
pwr_tCid m_cid;
wb_dbms_env *m_env;
MYSQL *m_con;
wb_dbms_txn *m_txn;
pwr_tObjName m_volumeName;
wb_dbms_table *m_t_ohead;
wb_dbms_table *m_t_rbody;
wb_dbms_table *m_t_dbody;
wb_dbms_table *m_t_class;
wb_dbms_table *m_t_name;
wb_dbms_table *m_t_info;
char m_buf[65532];
private:
int open();
int createDb();
public:
wb_dbms();
wb_dbms(pwr_tVid vid);
~wb_dbms() {;}
int initTables();
inline MYSQL *con() {
return m_con;
}
inline wb_dbms_table *tOhead() {
return m_t_ohead;
}
inline wb_dbms_table *tRbody() {
return m_t_rbody;
}
inline wb_dbms_table *tDbody() {
return m_t_dbody;
}
inline wb_dbms_table *tClass() {
return m_t_class;
}
inline wb_dbms_table *tName() {
return m_t_name;
}
inline wb_dbms_table *tInfo() {
return m_t_info;
}
pwr_tCid cid() { return m_cid;}
pwr_tVid vid() { return m_vid;}
//pwr_tTime time() { return m_volume.time;}
const char *volumeName() { return m_volumeName;}
pwr_tOid new_oid(wb_dbms_txn *txn);
pwr_tOid new_oid(wb_dbms_txn *txn, pwr_tOid oid);
void open(const char *fileName);
void open(wb_dbms_env *env);
void copy(wb_export &e, const char *fileName);
void copy(wb_export &e, wb_dbms_env *env);
void copy(wb_export &e, pwr_tVid vid, pwr_tCid cid, const char *volumeName, const char *fileName);
void copy(wb_export &e, pwr_tVid vid, pwr_tCid cid, const char *volumeName, wb_dbms_env *env);
void create(pwr_tVid vid, pwr_tCid cid, const char *volumeName, const char *fileName);
void create(pwr_tVid vid, pwr_tCid cid, const char *volumeName, wb_dbms_env *env);
int close();
int del_family(wb_dbms_txn *txn, wb_dbms_cursor *cp, pwr_tOid poid);
wb_dbms_txn *begin(wb_dbms_txn *txn);
wb_dbms_txn *subBegin(wb_dbms_txn *txn);
bool commit(pwr_tStatus *sts);
bool abort(pwr_tStatus *sts);
//void adopt(wb_dbms_txn *txn, wb_dbms_ohead &o, wb_destination &dest);
//void unadopt(wb_dbms_txn *txn, wb_dbms_ohead &o);
bool deleteFamily(pwr_tStatus *sts, wb_dbms_ohead *o);
//bool deleteOset(pwr_tStatus *sts, wb_oset *o);
bool importVolume(wb_export &e);
bool importHead(pwr_tOid oid, pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, pwr_tOid aoid, pwr_tOid foid, pwr_tOid loid,
const char *name, const char *normname, pwr_mClassDef flags,
pwr_tTime ohTime, pwr_tTime rbTime, pwr_tTime dbTime,
size_t rbSize, size_t dbSize);
bool importRbody(pwr_tOid oid, size_t size, void *body);
bool importDbody(pwr_tOid oid, size_t size, void *body);
bool importDocBlock(pwr_tOid oid, size_t size, char *block) { return true;}
bool importMeta(dbs_sMenv *mep);
void checkClassList(pwr_tOid oid, pwr_tCid cid, bool update);
};
class wb_dbms_info
{
public:
wb_dbms *m_db;
struct
{
pwr_tVid vid;
pwr_tCid cid;
pwr_tTime time;
pwr_tObjName name;
} m_volume;
wb_dbms_qe m_key;
wb_dbms_qe m_data;
wb_dbms_info(wb_dbms *db);
~wb_dbms_info() {;}
void ins(wb_dbms_txn *txn);
void upd(wb_dbms_txn *txn);
void get(wb_dbms_txn *txn);
pwr_tCid cid() { return m_volume.cid;}
pwr_tVid vid() { return m_volume.vid;}
pwr_tTime time() { return m_volume.time;}
char *name() { return m_volume.name;}
void cid(pwr_tCid cid) { m_volume.cid = cid;}
void vid(pwr_tVid vid) { m_volume.vid = vid;}
void time(pwr_tTime time) { m_volume.time = time;}
void name(char const *name) { strcpy(m_volume.name, name);}
};
class wb_dbms_ohead
{
public:
dbms_sObject m_o;
pwr_tOid m_oid;
wb_dbms *m_db;
wb_dbms_qe m_key;
wb_dbms_qe m_data;
wb_dbms_cursor *m_dbc;
wb_dbms_ohead();
wb_dbms_ohead(wb_dbms *db);
wb_dbms_ohead(wb_dbms *db, pwr_tOid oid);
wb_dbms_ohead(wb_dbms *db, wb_dbms_txn *txn, pwr_tOid oid);
wb_dbms_ohead(wb_dbms *db, pwr_tOid oid, pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, pwr_tOid aoid, pwr_tOid foid, pwr_tOid loid,
const char *name, const char *normname, pwr_mClassDef flags,
pwr_tTime ohTime, pwr_tTime rbTime, pwr_tTime dbTime,
size_t rbSize, size_t dbSize);
wb_dbms_ohead &get(wb_dbms_txn *txn);
wb_dbms_ohead &get(wb_dbms_txn *txn, pwr_tOid oid);
void setDb(wb_dbms *db) { m_db = db;}
int ins(wb_dbms_txn *txn);
int upd(wb_dbms_txn *txn);
int del(wb_dbms_txn *txn);
pwr_tOid oid() { return m_o.oid;}
pwr_tVid vid() { return m_o.oid.vid;}
pwr_tOix oix() { return m_o.oid.oix;}
pwr_tCid cid() { return m_o.cid;}
pwr_tOid poid() { return m_o.poid;}
pwr_tOid foid() { return m_o.foid;}
pwr_tOid loid() { return m_o.loid;}
pwr_tOid boid() { return m_o.boid;}
pwr_tOid aoid() { return m_o.aoid;}
pwr_tTime ohTime() { return m_o.time;}
const char *name() { return m_o.name;}
const char *normname() {return m_o.normname;}
pwr_mClassDef flags() { return m_o.flags;}
size_t rbSize() { return m_o.body[0].size;}
size_t dbSize() { return m_o.body[1].size;}
pwr_tTime rbTime() { return m_o.body[0].time;}
pwr_tTime dbTime() { return m_o.body[1].time;}
void name(wb_name &name);
void name(pwr_tOid &oid);
void oid(pwr_tOid oid) { m_o.oid = m_oid = oid;}
void cid(pwr_tCid cid) { m_o.cid = cid;}
void poid(pwr_tOid oid) { m_o.poid = oid;}
void foid(pwr_tOid oid) { m_o.foid = oid;}
void loid(pwr_tOid oid) { m_o.loid = oid;}
void boid(pwr_tOid oid) { m_o.boid = oid;}
void aoid(pwr_tOid oid) { m_o.aoid = oid;}
void flags(pwr_mClassDef flags) { m_o.flags = flags;}
void rbSize(size_t size) { m_o.body[0].size = size;}
void dbSize(size_t size) { m_o.body[1].size = size;}
void ohTime(pwr_tTime &time) { m_o.time = time;}
void rbTime(pwr_tTime &time) { m_o.body[0].time = time;}
void dbTime(pwr_tTime &time) { m_o.body[1].time = time;}
void clear();
void iter(void (*func)(pwr_tOid oid, dbms_sObject *op)); // select oix, o from ohead
void iter(wb_import &i); // select oix, o from ohead
};
typedef struct
{
pwr_tOid poid;
pwr_tObjName normname;
} dbms_sNameKey;
typedef struct
{
pwr_tOid oid;
} dbms_sNameData;
class wb_dbms_name
{
public:
dbms_sNameKey m_k;
dbms_sNameData m_d;
wb_dbms *m_db;
wb_dbms_qe m_key;
wb_dbms_qe m_data;
wb_dbms_cursor *m_dbc;
wb_dbms_name(wb_dbms *db, wb_dbms_txn *txn);
wb_dbms_name(wb_dbms *db, wb_dbms_ohead &o);
wb_dbms_name(wb_dbms *db, pwr_tOid poid, const char *name);
wb_dbms_name(wb_dbms *db, pwr_tOid oid, pwr_tOid poid, const char *name);
wb_dbms_name(wb_dbms *db, wb_dbms_txn *txn, pwr_tOid poid, wb_name &name);
int get(wb_dbms_txn *txn);
int ins(wb_dbms_txn *txn);
int upd(wb_dbms_txn *txn);
int del(wb_dbms_txn *txn);
void name(wb_name &name);
void iter(void (*print)(pwr_tOid poid, pwr_tObjName name, pwr_tOid oid));
pwr_tOid oid() { return m_d.oid;}
};
class wb_dbms_class
{
public:
struct
{
pwr_tOix oix;
pwr_tCid cid;
} m_k;
wb_dbms *m_db;
wb_dbms_qe m_key;
wb_dbms_cursor *m_dbc;
wb_dbms_class(wb_dbms *db);
wb_dbms_class(wb_dbms *db, pwr_tCid cid);
wb_dbms_class(wb_dbms *db, pwr_tCid cid, pwr_tOid oid);
wb_dbms_class(wb_dbms *db, wb_dbms_ohead &o);
wb_dbms_class(wb_dbms *db, wb_dbms_txn *txn, pwr_tCid cid);
~wb_dbms_class();
bool succ(pwr_tOid oid);
bool succClass(pwr_tCid cid);
bool pred(pwr_tOid oid);
int ins(wb_dbms_txn *txn);
int upd(wb_dbms_txn *txn);
int del(wb_dbms_txn *txn);
pwr_tCid cid() { return m_k.cid;}
pwr_tOid oid() {
pwr_tOid oid;
oid.oix = m_k.oix;
oid.vid = m_db->vid();
return oid;
}
void iter(void (*func)(pwr_tOid oid, pwr_tCid cid));
};
class wb_dbms_class_iterator
{
struct
{
pwr_tOix oix;
pwr_tCid cid;
} m_k;
wb_dbms *m_db;
wb_dbms_qe m_key;
bool m_atEnd;
int m_rc;
public:
wb_dbms_class_iterator(wb_dbms *db);
wb_dbms_class_iterator(wb_dbms *db, pwr_tCid cid);
wb_dbms_class_iterator(wb_dbms *db, pwr_tCid cid, pwr_tOid oid);
~wb_dbms_class_iterator();
inline bool atEnd() {return m_atEnd;}
bool first();
bool succObject();
bool succClass();
bool succClass(pwr_tCid cid);
inline pwr_tOid oid() {
pwr_tOid oid;
oid.vid = m_db->vid();
oid.oix = m_k.oix;
return oid;
}
inline pwr_tCid cid() {return m_k.cid;}
inline void oid(pwr_tOid oid) {m_k.oix = oid.oix;}
inline void cid(pwr_tCid cid) {m_k.cid = cid;}
};
class wb_dbms_dbody
{
public:
wb_dbms *m_db;
pwr_tOid m_oid;
size_t m_size;
void *m_p;
wb_dbms_qe m_key;
wb_dbms_qe m_data;
wb_dbms_cursor *m_dbc;
wb_dbms_dbody(wb_dbms *db);
wb_dbms_dbody(wb_dbms *db, pwr_tOid oid);
wb_dbms_dbody(wb_dbms *db, pwr_tOid oid, size_t size, void *p);
void oid(pwr_tOid oid) {m_oid = oid;}
int get(wb_dbms_txn *txn, size_t offset, size_t size, void *p);
int ins(wb_dbms_txn *txn);
int ins(wb_dbms_txn *txn, size_t offset, size_t size, void *p);
int upd(wb_dbms_txn *txn);
int upd(wb_dbms_txn *txn, size_t offset, size_t size, void *p);
int del(wb_dbms_txn *txn);
void iter(void (*print)(pwr_tOid oid, size_t size));
void iter(wb_import &i);
};
class wb_dbms_rbody
{
public:
wb_dbms *m_db;
pwr_tOid m_oid;
size_t m_size;
void *m_p;
wb_dbms_qe m_key;
wb_dbms_qe m_data;
wb_dbms_cursor *m_dbc;
wb_dbms_rbody(wb_dbms *db);
wb_dbms_rbody(wb_dbms *db, pwr_tOid oid);
wb_dbms_rbody(wb_dbms *db, pwr_tOid oid, size_t size, void *p);
void oid(pwr_tOid oid) {m_oid = oid;}
int get(wb_dbms_txn *txn, size_t offset, size_t size, void *p);
int ins(wb_dbms_txn *txn);
int ins(wb_dbms_txn *txn, size_t offset, size_t size, void *p);
int upd(wb_dbms_txn *txn);
int upd(wb_dbms_txn *txn, size_t offset, size_t size, void *p);
int del(wb_dbms_txn *txn);
void iter(void (*print)(pwr_tOid oid, size_t size));
void iter(wb_import &i);
};
class wb_dbms_get_query : public wb_dbms_query
{
public:
wb_dbms_get_query() {;}
virtual ~wb_dbms_get_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
int rc = 0;
static const char *method = "execute";
bind(txn, key, data);
rc = mysql_stmt_execute(m_stmt);
if (rc) error(rc, method, "mysql_stmt_execute");
rc = mysql_stmt_store_result(m_stmt);
if (rc) error(rc, method, "mysql_stmt_store_result");
if (mysql_stmt_num_rows(m_stmt) == 0)
return 1;
rc = mysql_stmt_fetch(m_stmt);
if (rc) error(rc, method, "mysql_stmt_fetch");
mysql_stmt_free_result(m_stmt);
return 0;
}
};
class wb_dbms_iter_query : public wb_dbms_query
{
public:
wb_dbms_iter_query() {;}
virtual ~wb_dbms_iter_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
int rc = 0;
static const char *method = "execute";
bind(txn, key, data);
rc = mysql_stmt_execute(m_stmt);
if (rc) error(rc, method, "mysql_stmt_execute");
rc = mysql_stmt_store_result(m_stmt);
if (rc) error(rc, method, "mysql_stmt_store_result");
if (mysql_stmt_num_rows(m_stmt) == 0)
return 1;
rc = mysql_stmt_fetch(m_stmt);
if (rc) error(rc, method, "mysql_stmt_fetch");
mysql_stmt_free_result(m_stmt);
if (m_result.is_null[0])
return 1;
return 0;
}
};
class wb_dbms_ins_query : public wb_dbms_query
{
public:
wb_dbms_ins_query() {;}
virtual ~wb_dbms_ins_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
int rc = 0;
static const char *method = "execute";
bind(txn, key, data);
rc = mysql_stmt_execute(m_stmt);
if (rc) error(rc, method, "mysql_stmt_execute");
if (mysql_stmt_affected_rows(m_stmt) == 1)
return 0;
return 1;
}
};
class wb_dbms_upd_query : public wb_dbms_query
{
public:
wb_dbms_upd_query() {;}
virtual ~wb_dbms_upd_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
int rc = 0;
static const char *method = "execute";
bind(txn, key, data);
rc = mysql_stmt_execute(m_stmt);
if (rc) error(rc, method, "mysql_stmt_execute");
if (mysql_stmt_affected_rows(m_stmt) == 1)
return 0;
return 1;
}
};
class wb_dbms_del_query : public wb_dbms_query
{
public:
wb_dbms_del_query() {;}
virtual ~wb_dbms_del_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
int rc = 0;
static const char *method = "execute";
bind(txn, key, data);
rc = mysql_stmt_execute(m_stmt);
if (rc) error(rc, method, "mysql_stmt_execute");
if (mysql_stmt_affected_rows(m_stmt) == 1)
return 0;
return 1;
}
};
class wb_dbms_cursor_query : public wb_dbms_query
{
public:
wb_dbms_cursor_query() {;}
virtual ~wb_dbms_cursor_query() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) = 0;
virtual int execute(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
int rc = 0;
static const char *method = "execute";
bind(txn, key, data);
rc = mysql_stmt_execute(m_stmt);
if (rc) error(rc, method, "mysql_stmt_execute");
return 0;
}
};
class wb_dbms_get_info : public wb_dbms_get_query
{
public:
wb_dbms_get_info(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_get_info() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select volume from info where id = ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindParam(0, MYSQL_TYPE_LONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_ins_info : public wb_dbms_ins_query
{
public:
wb_dbms_ins_info(wb_dbms *db) { m_db = db;}
~wb_dbms_ins_info() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("insert into info (id, volume) values (?, ?)", 0, 2);
bindParam(0, MYSQL_TYPE_LONG, (char *) key->data(), key->size());
bindParam(1, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindQuery();
return 0;
}
};
class wb_dbms_upd_info : public wb_dbms_upd_query
{
public:
wb_dbms_upd_info(wb_dbms *db) { m_db = db;}
~wb_dbms_upd_info() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("update info set volume = ? where id = ?", 0, 2);
bindParam(0, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindParam(1, MYSQL_TYPE_LONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_del_info : public wb_dbms_del_query
{
public:
wb_dbms_del_info(wb_dbms *db) { m_db = db;}
~wb_dbms_del_info() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("delete from inf where id = ?", 0, 1);
bindParam(0, MYSQL_TYPE_LONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_get_ohead : public wb_dbms_get_query
{
public:
wb_dbms_get_ohead(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_get_ohead() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select head from ohead where oid = ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_ins_ohead : public wb_dbms_ins_query
{
public:
wb_dbms_ins_ohead(wb_dbms *db) { m_db = db;}
~wb_dbms_ins_ohead() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("insert into ohead (oid, head) values (?, ?)", 0, 2);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindParam(1, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindQuery();
return 0;
}
};
class wb_dbms_upd_ohead : public wb_dbms_upd_query
{
public:
wb_dbms_upd_ohead(wb_dbms *db) { m_db = db;}
~wb_dbms_upd_ohead() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("update ohead set head = ? where oid = ?", 0, 2);
bindParam(0, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindParam(1, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_del_ohead : public wb_dbms_del_query
{
public:
wb_dbms_del_ohead(wb_dbms *db) { m_db = db;}
~wb_dbms_del_ohead() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("delete from ohead where oid = ?", 0, 1);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_cursor_ohead : public wb_dbms_cursor_query
{
public:
wb_dbms_cursor_ohead(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_cursor_ohead() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select oid, head from ohead", 2, 0);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindResult(1, MYSQL_TYPE_LONG_BLOB, data);
bindQuery();
return 0;
}
};
class wb_dbms_get_dbody : public wb_dbms_get_query
{
public:
wb_dbms_get_dbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_get_dbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select body from dbody where oid = ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONG_BLOB, data);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_ins_dbody : public wb_dbms_ins_query
{
public:
wb_dbms_ins_dbody(wb_dbms *db) { m_db = db;}
~wb_dbms_ins_dbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("insert into dbody (oid, body) values (?, ?)", 0, 2);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindParam(1, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindQuery();
return 0;
}
};
class wb_dbms_upd_dbody : public wb_dbms_upd_query
{
public:
wb_dbms_upd_dbody(wb_dbms *db) { m_db = db;}
~wb_dbms_upd_dbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("update dbody set body = ? where oid = ?", 0, 2);
bindParam(0, MYSQL_TYPE_LONG_BLOB, data);
bindParam(1, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
#if 0
class wb_dbms_pupd_dbody : public wb_dbms_upd_query
{
public:
wb_dbms_pupd_dbody(wb_dbms *db) { m_db = db;}
~wb_dbms_pupd_dbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
//prepare("update dbody set body = concat(substring(body, 1, ?), ?, substring(body, ?, 500000)) where oid = ?", 0, 4);
/*
update rbody set body = concat(substring(body, 1, 50), repeat('x', 10), substring(body, 61, 68)) where oid = 853238203023360;
*/
int size_1 = 10;//data->offset();
int size_2 = 20;//data->offset() + data->size() + 1;
pwr_tOid oid;
oid.vid = 198660;
oid.oix = 76202;
//char a[] = "9";
//char b[] = "344";
//bindParam(0, MYSQL_TYPE_LONG, (char *) &size_1);
//bindParam(0, MYSQL_TYPE_STRING, a, strlen(a));
bindParam(0, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
// bindParam(2, MYSQL_TYPE_LONG, (char *) &size_2, sizeof(size_2));
//bindParam(2, MYSQL_TYPE_LONG, (char *) &size_2);
//bindParam(2, MYSQL_TYPE_STRING, b, strlen(b));
bindParam(1, MYSQL_TYPE_LONGLONG, (char *) &oid);
//bindParam(3, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
#endif
class wb_dbms_del_dbody : public wb_dbms_del_query
{
public:
wb_dbms_del_dbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_del_dbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("delete from dbody where oid = ?", 0, 1);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_cursor_dbody : public wb_dbms_cursor_query
{
public:
wb_dbms_cursor_dbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_cursor_dbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select oid, body from dbody", 2, 0);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindResult(1, MYSQL_TYPE_LONG_BLOB, data);
bindQuery();
return 0;
}
};
class wb_dbms_get_rbody : public wb_dbms_get_query
{
public:
wb_dbms_get_rbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_get_rbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select body from rbody where oid = ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONG_BLOB, data);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_ins_rbody : public wb_dbms_ins_query
{
public:
wb_dbms_ins_rbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_ins_rbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("insert into rbody (oid, body) values (?, ?)", 0, 2);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindParam(1, MYSQL_TYPE_LONG_BLOB, (char *)data->data(), data->size());
bindQuery();
return 0;
}
};
class wb_dbms_upd_rbody : public wb_dbms_upd_query
{
public:
wb_dbms_upd_rbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_upd_rbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("update rbody set body = ? where oid = ?", 0, 2);
bindParam(0, MYSQL_TYPE_LONG_BLOB, data);
bindParam(1, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_del_rbody : public wb_dbms_del_query
{
public:
wb_dbms_del_rbody(wb_dbms *db) { m_db = db;}
~wb_dbms_del_rbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("delete from rbody where oid = ?", 0, 1);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_cursor_rbody : public wb_dbms_cursor_query
{
public:
wb_dbms_cursor_rbody(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_cursor_rbody() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select oid, body from rbody", 2, 0);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindResult(1, MYSQL_TYPE_LONG_BLOB, data);
bindQuery();
return 0;
}
};
class wb_dbms_get_class : public wb_dbms_get_query
{
public:
wb_dbms_get_class(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_get_class() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select cidoix from class where cidoix = ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_succ_class : public wb_dbms_iter_query
{
public:
wb_dbms_succ_class(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_succ_class() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select min(cidoix) from class where cidoix > ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_pred_class : public wb_dbms_iter_query
{
public:
wb_dbms_pred_class(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_pred_class() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select max(cidoix) from class where cidoix < ?", 1, 1);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_ins_class : public wb_dbms_ins_query
{
public:
wb_dbms_ins_class(wb_dbms *db) { m_db = db;}
~wb_dbms_ins_class() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("insert into class (cidoix) values (?)", 0, 1);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_del_class : public wb_dbms_del_query
{
public:
wb_dbms_del_class(wb_dbms *db) { m_db = db;}
~wb_dbms_del_class() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("delete from class where cidoix = ?", 0, 1);
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_cursor_class : public wb_dbms_cursor_query
{
public:
wb_dbms_cursor_class(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_cursor_class() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select cidoix from class", 1, 0);
bindResult(0, MYSQL_TYPE_LONGLONG, (char *) key->data(), key->size());
bindQuery();
return 0;
}
};
class wb_dbms_get_name : public wb_dbms_get_query
{
public:
wb_dbms_get_name(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_get_name() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select oid from name where poid = ? and normname = ?", 1, 2);
dbms_sNameKey *nk = (dbms_sNameKey *)key->data();
bindResult(0, MYSQL_TYPE_LONGLONG, (char *)data->data(), data->size());
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)&nk->poid, sizeof(nk->poid));
bindParam(1, MYSQL_TYPE_TINY_BLOB, (char *)&nk->normname, sizeof(nk->normname));
bindQuery();
return 0;
}
};
class wb_dbms_ins_name : public wb_dbms_ins_query
{
public:
wb_dbms_ins_name(wb_dbms *db) { m_db = db;}
~wb_dbms_ins_name() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("insert into name (poid, normname, oid) values (?, ?, ?)", 0, 3);
dbms_sNameKey *nk = (dbms_sNameKey *)key->data();
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)&nk->poid, sizeof(nk->poid));
bindParam(1, MYSQL_TYPE_TINY_BLOB, (char *)&nk->normname, sizeof(nk->normname));
bindParam(2, MYSQL_TYPE_LONGLONG, (char *)data->data(), data->size());
bindQuery();
return 0;
}
};
class wb_dbms_del_name : public wb_dbms_del_query
{
public:
wb_dbms_del_name(wb_dbms *db) { m_db = db;}
~wb_dbms_del_name() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("delete from name where poid = ? and normname = ?", 0, 2);
dbms_sNameKey *nk = (dbms_sNameKey *)key->data();
bindParam(0, MYSQL_TYPE_LONGLONG, (char *)&nk->poid, sizeof(nk->poid));
bindParam(1, MYSQL_TYPE_TINY_BLOB, (char *)&nk->normname, sizeof(nk->normname));
bindQuery();
return 0;
}
};
class wb_dbms_cursor_name : public wb_dbms_cursor_query
{
public:
wb_dbms_cursor_name(wb_dbms *db) { m_db = db;}
virtual ~wb_dbms_cursor_name() {;}
virtual int bind(wb_dbms_txn *txn, wb_dbms_qe *key, wb_dbms_qe *data) {
prepare("select poid, normname, oid from name", 3, 0);
dbms_sNameKey *nk = (dbms_sNameKey *)key->data();
bindResult(0, MYSQL_TYPE_LONGLONG, (char *)&nk->poid, sizeof(nk->poid));
bindResult(1, MYSQL_TYPE_TINY_BLOB, (char *)&nk->normname, sizeof(nk->normname));
bindResult(2, MYSQL_TYPE_LONGLONG, (char *)data->data(), data->size());
bindQuery();
return 0;
}
};
using namespace std;
class wb_dbms_error
{
string m_error_str;
string m_sql_error;
int m_errno;
wb_dbms *m_db;
public:
wb_dbms_error(wb_dbms *db, string str);
string what() const;
};
#endif
#endif
/*
* Proview $Id: wb_orepdbms.cpp,v 1.1 2007-10-18 09:11:01 claes Exp $
* Copyright (C) 2007 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#if defined PWRE_CONF_MYSQL
#include "wb_orepdbms.h"
#include "wb_vrepdbms.h"
wb_orepdbms::wb_orepdbms() :
m_o(0), m_oid(pwr_cNOid)
{
}
wb_orepdbms::wb_orepdbms(pwr_tOid oid) :
m_o(0), m_oid(oid)
{
}
wb_orepdbms::wb_orepdbms(dbms_sObject *o) :
m_o(o), m_oid(o->oid)
{
}
wb_orepdbms::~wb_orepdbms()
{
}
void *
wb_orepdbms::operator new(size_t size, wb_vrepdbms *v)
{
return (void *)v->new_wb_orepdbms(size);
}
#if 1
void
wb_orepdbms::operator delete(void *p)
{
wb_orepdbms *o = (wb_orepdbms *)p;
((wb_vrepdbms *)o->m_vrep)->delete_wb_orepdbms(p);
}
#endif
//
// Operations declared in wb_orep
//
pwr_tOid wb_orepdbms::oid() const
{
return m_oid;
}
pwr_tVid wb_orepdbms::cid() const
{
pwr_tStatus sts;
return m_vrep->cid(&sts, (wb_orep*)this);
}
pwr_tVid wb_orepdbms::vid() const
{
pwr_tStatus sts;
return m_vrep->vid(&sts, (wb_orep*)this);
}
pwr_tOix wb_orepdbms::oix() const
{
pwr_tStatus sts;
return m_vrep->oix(&sts, (wb_orep*)this);
}
pwr_tOid wb_orepdbms::poid() const
{
pwr_tStatus sts;
return m_vrep->poid(&sts, (wb_orep*)this);
}
pwr_tOid wb_orepdbms::foid() const
{
pwr_tStatus sts;
return m_vrep->foid(&sts, (wb_orep*)this);
}
pwr_tOid wb_orepdbms::loid() const
{
pwr_tStatus sts;
return m_vrep->loid(&sts, (wb_orep*)this);
}
pwr_tOid wb_orepdbms::boid() const
{
pwr_tStatus sts;
return m_vrep->boid(&sts, (wb_orep*)this);
}
pwr_tOid wb_orepdbms::aoid() const
{
pwr_tStatus sts;
return m_vrep->aoid(&sts, (wb_orep*)this);
}
wb_name wb_orepdbms::longName()
{
pwr_tStatus sts;
return m_vrep->longName(&sts, (wb_orep*)this);
}
const char * wb_orepdbms::name() const
{
pwr_tStatus sts;
return m_vrep->objectName(&sts, (wb_orep*)this);
}
pwr_tTime wb_orepdbms::ohTime() const
{
pwr_tStatus sts;
return m_vrep->ohTime(&sts, (wb_orep*)this);
}
pwr_tTime wb_orepdbms::rbTime() const
{
pwr_tStatus sts;
return m_vrep->rbTime(&sts, (wb_orep*)this);
}
pwr_tTime wb_orepdbms::dbTime() const
{
pwr_tStatus sts;
return m_vrep->dbTime(&sts, (wb_orep*)this);
}
pwr_mClassDef wb_orepdbms::flags() const
{
pwr_tStatus sts;
return m_vrep->flags(&sts, (wb_orep*)this);
}
bool wb_orepdbms::isOffspringOf(const wb_orep *o) const
{
pwr_tStatus sts;
return m_vrep->isOffspringOf(&sts, (wb_orep*)this, o);
}
wb_orep *wb_orepdbms::ancestor(pwr_tStatus *sts)
{
return m_vrep->ancestor(sts, (wb_orep*)this);
}
wb_orep *wb_orepdbms::parent(pwr_tStatus *sts)
{
return m_vrep->parent(sts, (wb_orep*)this);
}
wb_orep *wb_orepdbms::after(pwr_tStatus *sts)
{
return m_vrep->after(sts, (wb_orep*)this);
}
wb_orep *wb_orepdbms::before(pwr_tStatus *sts)
{
return m_vrep->before(sts, (wb_orep*)this);
}
wb_orep* wb_orepdbms::first(pwr_tStatus *sts)
{
return m_vrep->first(sts, (wb_orep*)this);
}
wb_orep *wb_orepdbms::child(pwr_tStatus *sts, wb_name &name)
{
return m_vrep->child(sts, (wb_orep*)this, name);
}
wb_orep *wb_orepdbms::last(pwr_tStatus *sts)
{
return m_vrep->last(sts, (wb_orep*)this);
}
wb_orep *wb_orepdbms::next(pwr_tStatus *sts)
{
return m_vrep->next(sts, (wb_orep*)this);
}
wb_orep *wb_orepdbms::previous(pwr_tStatus *sts)
{
return m_vrep->previous(sts, (wb_orep*)this);
}
wb_adrep *wb_orepdbms::attribute(pwr_tStatus*, const char *aname)
{
return 0;
}
wb_adrep *wb_orepdbms::attribute(pwr_tStatus*)
{
return 0;
}
#endif
/*
* Proview $Id: wb_orepdbms.h,v 1.1 2007-10-18 09:11:01 claes Exp $
* Copyright (C) 2005 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#ifndef wb_orepdbms_h
#define wb_orepdbms_h
#if defined PWRE_CONF_MYSQL
#include "pwr.h"
#include "wb_orep.h"
#include "pwr_class.h"
#include "wb_dbms.h"
class wb_vrepdbms;
class wb_orepdbms : wb_orep
{
friend class wb_vrepdbms;
dbms_sObject *m_o;
pwr_tOid m_oid;
public:
wb_orepdbms();
wb_orepdbms(pwr_tOid oid);
wb_orepdbms(dbms_sObject *o);
~wb_orepdbms();
void* operator new(size_t size, wb_vrepdbms *v);
void operator delete(void *p);
virtual pwr_tOid oid() const;
virtual pwr_tVid vid() const;
virtual pwr_tOix oix() const;
virtual pwr_tCid cid() const;
virtual pwr_tOid poid() const;
virtual pwr_tOid foid() const;
virtual pwr_tOid loid() const;
virtual pwr_tOid boid() const;
virtual pwr_tOid aoid() const;
virtual const char * name() const;
virtual wb_name longName();
virtual pwr_tTime ohTime() const;
virtual pwr_tTime rbTime() const;
virtual pwr_tTime dbTime() const;
virtual pwr_mClassDef flags() const;
virtual bool isOffspringOf(const wb_orep *o) const;
// Navigational operations
virtual wb_orep *ancestor(pwr_tStatus *sts); //< get object at top of hierarchy
virtual wb_orep *parent(pwr_tStatus *sts);
virtual wb_orep *after(pwr_tStatus *sts); //< get next sibling
virtual wb_orep *before(pwr_tStatus *sts); //< get previous sibling
virtual wb_orep *first(pwr_tStatus *sts); //< get first child
virtual wb_orep *child(pwr_tStatus *sts, wb_name &name); //< get named child
virtual wb_orep *last(pwr_tStatus *sts); //< get last child
virtual wb_orep *next(pwr_tStatus *sts); //< get next in list of objects of same class in one volume
virtual wb_orep *previous(pwr_tStatus *sts); //< get previous in list of objects of same class in one volume
virtual wb_adrep *attribute(pwr_tStatus*, const char *name);
virtual wb_adrep *attribute(pwr_tStatus*);
wb_erep *erep() const { return m_vrep->erep();}
wb_vrep *vrep() const { return m_vrep;}
virtual ldh_eVolRep vtype() const { return ldh_eVolRep_Dbms;}
};
#endif
#endif
/*
* Proview $Id: wb_vrepdbms.cpp,v 1.1 2007-10-18 09:11:01 claes Exp $
* Copyright (C) 2007 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#if defined PWRE_CONF_MYSQL
#include <sys/stat.h>
#include <errno.h>
#include "co_cdh.h"
#include "co_tree.h"
#include "co_time.h"
#include "wb_dbms.h"
#include "wb_vrepdbms.h"
#include "wb_orepdbms.h"
#include "wb_cdrep.h"
#include "wb_bdrep.h"
#include "wb_adrep.h"
#include "wb_erep.h"
#include "wb_dbs.h"
#include "wb_ldh.h"
#include "wb_merep.h"
#include "wb_attribute.h"
#include "wb_dblock.h"
#include "co_msgwindow.h"
#include "wb_vrepwbl.h"
typedef struct sArefKey
{
pwr_tCid cid;
pwr_eBix bix;
int offset;
} sArefKey;
typedef struct sAref
{
tree_sNode node;
sArefKey key;
} sAref;
typedef struct sAttributeInfo {
pwr_tAttrRef aref;
pwr_tAix aix;
pwr_tUInt32 nElement;
} sAttributeInfo;
typedef struct sAttributeKey {
pwr_tCid cid;
pwr_eBix bix;
pwr_tUInt32 oStart;
pwr_tUInt32 oEnd;
} sAttributeKey;
typedef struct sAttribute {
tree_sNode node;
sAttributeKey key;
sAttributeInfo o;
sAttributeInfo n;
} sAttribute;
typedef struct sClass
{
tree_sNode node;
pwr_tCid cid;
pwr_tObjName name;
pwr_tTime o_time;
pwr_tTime n_time;
pwr_tUInt32 count;
} sClass;
static int comp_attribute(tree_sTable *tp, tree_sNode *x, tree_sNode *y);
static int comp_aref(tree_sTable *tp, tree_sNode *x, tree_sNode *y);
void wb_vrepdbms::unref()
{
if (--m_nRef == 0) {
wb_dblock::dbunlock(m_fileName);
delete this;
}
}
wb_vrep *wb_vrepdbms::ref()
{
m_nRef++;
return this;
}
wb_vrepdbms::wb_vrepdbms(wb_erep *erep, const char *fileName) :
m_erep(erep), m_nRef(0), m_ohead(), m_oid_th(0)
{
strcpy(m_fileName, fileName);
wb_dblock::dblock( m_fileName);
wb_dbms_env *env = new wb_dbms_env(fileName);
env->open();
m_db = new wb_dbms();
m_db->open(env);
m_ohead.setDb(m_db);
strcpy(m_name, m_db->volumeName());
m_vid = m_db->vid();
m_cid = m_db->cid();
m_merep = new wb_merep(m_fileName, erep, this);
m_merep->compareMeta(m_name, erep->merep());
}
wb_vrepdbms::wb_vrepdbms(wb_erep *erep, pwr_tVid vid, pwr_tCid cid, const char *volumeName, const char *fileName) :
m_erep(erep), m_nRef(0), m_ohead(), m_oid_th(0)
{
strcpy(m_fileName, fileName);
wb_dblock::dblock( m_fileName);
m_db = new wb_dbms();
m_db->create(vid, cid, volumeName, fileName);
m_ohead.setDb(m_db);
strcpy(m_name, m_db->volumeName());
m_vid = m_db->vid();
m_cid = m_db->cid();
m_merep = m_erep->merep();
m_merep->copyFiles(m_fileName);
}
wb_erep *wb_vrepdbms::erep()
{
return m_erep;
}
wb_vrep *wb_vrepdbms::next()
{
pwr_tStatus sts;
return m_erep->nextVolume( &sts, m_db->vid());
}
wb_merep *wb_vrepdbms::merep() const
{
return m_merep;
}
wb_srep *wb_vrepdbms::newSession()
{
return 0;
}
void wb_vrepdbms::objectName(pwr_tOid oid, char *name, int level)
{
if (cdh_ObjidIsNull(oid))
return;
wb_dbms_ohead o(m_db, m_db->m_txn, oid);
if (o.oix() == pwr_cNOix) {
strcpy(name, o.name());
strcat(name, ":");
} else {
objectName(o.poid(), name, level+1);
strcat(name, o.name());
if (level > 0)
strcat(name, "-");
}
}
wb_name wb_vrepdbms::longName(pwr_tStatus *sts, const wb_orep *o)
{
*sts = LDH__SUCCESS;
char name[512];
try {
objectName(o->oid(), name, 0);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
name[0] = '\0';
}
return wb_name(name);
}
bool wb_vrepdbms::isOffspringOf(pwr_tStatus *sts, const wb_orep *child, const wb_orep *parent)
{
return false;
}
bool wb_vrepdbms::isLocal(const wb_orep *o)
{
if (o)
return o->oid().vid == wb_vrep::vid();
return false;
}
bool wb_vrepdbms::createSnapshot(const char *fileName, const pwr_tTime *time)
{
try {
wb_dbs dbs(this);
if ( fileName)
dbs.setFileName( fileName);
dbs.importVolume(*this);
return true;
} catch (wb_error& e) {
return false;
}
}
void wb_vrepdbms::objectName(const wb_orep *o, char *str)
{
if (str)
*str = '\0';
}
const char *wb_vrepdbms::objectName(pwr_tStatus *sts, const wb_orep *o)
{
*sts = LDH__SUCCESS;
try {
m_ohead.get(m_db->m_txn, o->oid());
return m_ohead.name();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
void wb_vrepdbms::load()
{
}
wb_orep* wb_vrepdbms::object(pwr_tStatus *sts)
{
*sts = LDH__SUCCESS;
try {
pwr_tOid oid;
oid.vid = m_vid;
oid.oix = pwr_cNOix;
m_ohead.get(m_db->m_txn, oid);
m_ohead.get(m_db->m_txn, m_ohead.foid());
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
catch (wb_error &e) {
*sts = LDH__NOSUCHOBJ;
return 0;
}
}
wb_orep* wb_vrepdbms::object(pwr_tStatus *sts, pwr_tOid oid)
{
*sts = LDH__SUCCESS;
try {
m_ohead.get(m_db->m_txn, oid);
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_error &e) {
*sts = e.sts();
return 0;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep* wb_vrepdbms::object(pwr_tStatus *sts, wb_name &name)
{
pwr_tOid poid;
poid.vid = m_db->m_vid;
poid.oix = pwr_cNOix;
*sts = LDH__SUCCESS;
try {
for (int i = 0; name.hasSegment(i); i++) {
wb_dbms_name n(m_db, poid, name.normSegment(i));
int rc = n.get(m_db->m_txn);
if (rc) {
*sts = LDH__NOSUCHOBJ;
return 0;
}
poid = n.oid();
}
m_ohead.get(m_db->m_txn, poid);
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep* wb_vrepdbms::object(pwr_tStatus *sts, const wb_orep *parent, wb_name &name)
{
*sts = LDH__SUCCESS;
try {
wb_dbms_name n(m_db, m_db->m_txn, parent->oid(), name);
m_ohead.get(m_db->m_txn, n.oid());
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::copyObject(pwr_tStatus *sts, const wb_orep *orep, wb_destination &d, wb_name &name)
{
*sts = LDH__SUCCESS;
wb_dbms_txn *txn = m_db->subBegin(m_db->m_txn);
void *p = 0;
try {
int rs = 0;
pwr_tTime time;
pwr_tOid oid = m_db->new_oid(txn);
wb_dbms_ohead o(m_db, txn, orep->oid());
clock_gettime(CLOCK_REALTIME, &time);
if (o.rbSize()) {
o.rbTime(time);
p = calloc(1, o.rbSize());
wb_dbms_rbody rb(m_db, orep->oid());
rs = rb.get(txn, 0, o.rbSize(), p);
if (rs)
printf("wb_vrepdbms::copyObject, rb.get rs %d\n", rs);
rb.oid(oid);
rs = rb.ins(txn);
if (rs)
printf("wb_vrepdbms::copyObject, rb.ins rs %d\n", rs);
free(p);
p = 0;
}
if (o.dbSize()) {
o.dbTime(time);
p = calloc(1, o.dbSize());
wb_dbms_dbody db(m_db, orep->oid());
rs = db.get(txn, 0, o.dbSize(), p);
if (rs)
printf("wb_vrepdbms::copyObject, db.get rs %d\n", rs);
db.oid(oid);
rs = db.ins(txn);
if (rs)
printf("wb_vrepdbms::copyObject, db.ins rs %d\n", rs);
free(p);
p = 0;
}
o.oid(oid);
if (name)
o.name(name);
else
o.name(oid);
o.ohTime(time);
o.poid(pwr_cNOid);
o.boid(pwr_cNOid);
o.aoid(pwr_cNOid);
o.foid(pwr_cNOid);
o.loid(pwr_cNOid);
adopt(txn, o, d);
rs = o.ins(txn);
if (rs)
printf("wb_vrepdbms::copyObject, o.put rs %d\n", rs);
wb_dbms_class c(m_db, o);
rs = c.ins(txn);
if (rs)
printf("wb_vrepdbms::copyObject, c.put rs %d\n", rs);
txn->subCommit();
return new (this) wb_orepdbms(&o.m_o);
}
catch (wb_error &e) {
txn->subAbort();
if (p)
free(p);
*sts = e.sts();
return 0;
}
catch (wb_dbms_error &e) {
txn->subAbort();
if (p)
free(p);
*sts = LDH__DBERROR;
return 0;
}
}
bool wb_vrepdbms::copyOset(pwr_tStatus *sts, wb_oset *oset, wb_destination &d)
{
return false;
}
wb_orep* wb_vrepdbms::createObject(pwr_tStatus *sts, wb_cdef cdef, wb_destination &d, wb_name &name)
{
*sts = LDH__SUCCESS;
wb_dbms_txn *txn = m_db->subBegin(m_db->m_txn);
void *p = 0;
try {
int rs = 0;
pwr_tTime time;
pwr_tOid oid = m_db->new_oid(txn);
wb_dbms_ohead o(m_db, oid);
clock_gettime(CLOCK_REALTIME, &time);
o.cid(cdef.cid());
if (name)
o.name(name);
else
o.name(oid);
o.ohTime(time);
o.flags(cdef.flags());
o.rbSize(cdef.size(pwr_eBix_rt));
o.dbSize(cdef.size(pwr_eBix_dev));
adopt(txn, o, d);
if (o.rbSize()) {
pwr_tStatus sts = 1;
o.rbTime(time);
p = calloc(1, o.rbSize());
cdef.templateBody(&sts, pwr_eBix_rt, p, o.oid());
wb_dbms_rbody b(m_db, o.oid(), o.rbSize(), p);
rs = b.ins(txn);
if (rs)
printf("wb_vrepdbms::createObject, rb.ins rs %d\n", rs);
free(p);
p = 0;
}
if (o.dbSize()) {
pwr_tStatus sts = 1;
o.dbTime(time);
p = calloc(1, o.dbSize());
cdef.templateBody(&sts, pwr_eBix_dev, p, o.oid());
wb_dbms_dbody b(m_db, o.oid(), o.dbSize(), p);
rs = b.ins(txn);
if (rs)
printf("wb_vrepdbms::createObject, db.ins rs %d\n", rs);
free(p);
p = 0;
}
rs = o.ins(txn);
if (rs)
printf("wb_vrepdbms::createObject, o.ins rs %d\n", rs);
wb_dbms_class c(m_db, o);
rs = c.ins(txn);
if (rs)
printf("wb_vrepdbms::createObject, c.ins rs %d\n", rs);
rs = txn->subCommit();
return new (this) wb_orepdbms(&o.m_o);
}
catch (wb_error &e) {
txn->subAbort();
if (p)
free(p);
//*sts = e.sts();
throw e;
}
catch (wb_dbms_error &e) {
txn->subAbort();
if (p)
free(p);
*sts = LDH__DBERROR;
return 0;
}
}
bool wb_vrepdbms::deleteObject(pwr_tStatus *sts, wb_orep *orp)
{
*sts = LDH__SUCCESS;
wb_dbms_ohead o(m_db, orp->oid());
wb_dbms_txn *txn = m_db->subBegin(m_db->m_txn);
try {
o.get(txn);
unadopt(txn, o);
wb_dbms_class c(m_db, o);
c.del(txn);
wb_dbms_dbody db(m_db, o.oid());
db.del(txn);
wb_dbms_rbody rb(m_db, o.oid());
rb.del(txn);
o.del(txn);
txn->subCommit();
return true;
}
catch (wb_error &e) {
txn->subAbort();
*sts = e.sts();
return 0;
}
catch (wb_dbms_error &e) {
txn->subAbort();
*sts = LDH__DBERROR;
return false;
}
}
bool wb_vrepdbms::deleteFamilyMember(pwr_tOid oid, wb_dbms_txn *txn)
{
if (cdh_ObjidIsNull(oid))
return false;
int rs = 0;
wb_dbms_ohead o(m_db, oid);
o.get(txn);
deleteFamilyMember(o.foid(), txn);
deleteFamilyMember(o.aoid(), txn);
wb_dbms_class c(m_db, o);
rs = c.del(txn);
if (rs)
printf("wb_vrepdbms::deleteFamilyMember, c.del rs %d\n", rs);
wb_dbms_dbody db(m_db, o.oid());
rs = db.del(txn);
wb_dbms_rbody rb(m_db, o.oid());
rs = rb.del(txn);
wb_dbms_name n(m_db, o.oid(), o.poid(), o.normname());
rs = n.del(txn);
if (rs)
printf("wb_vrepdbms::deleteFamilyMember, n.del rs %d\n", rs);
rs = o.del(txn);
if (rs)
printf("wb_vrepdbms::deleteFamilyMember, o.del rs %d\n", rs);
return true;
}
bool wb_vrepdbms::deleteFamily(pwr_tStatus *sts, wb_orep *orp)
{
*sts = LDH__SUCCESS;
wb_dbms_ohead o(m_db, orp->oid());
wb_dbms_txn *txn = m_db->subBegin(m_db->m_txn);
try {
o.get(txn);
printf("wb_vrepdbms::deleteFamily %s\n", o.name());
unadopt(txn, o);
deleteFamilyMember(o.oid(), txn);
txn->subCommit();
printf("wb_vrepdbms::deleteFamily success\n");
return true;
}
catch (wb_dbms_error &e) {
printf("wb_vrepdbms::deleteFamily failure, %s\n", e.what().c_str());
txn->subAbort();
*sts = LDH__DBERROR;
return false;
}
}
bool wb_vrepdbms::deleteOset(pwr_tStatus *sts, wb_oset *oset)
{
*sts = LDH__NYI;
return false;
}
bool wb_vrepdbms::moveObject(pwr_tStatus *sts, wb_orep *orp, wb_destination &d)
{
*sts = LDH__SUCCESS;
wb_dbms_txn *txn = m_db->subBegin(m_db->m_txn);
try {
wb_dbms_ohead o(m_db, txn, orp->oid());
unadopt(txn, o);
adopt(txn, o, d);
o.upd(txn);
txn->subCommit();
}
catch (wb_error &e) {
txn->subAbort();
*sts = e.sts();
return 0;
}
catch (wb_dbms_error &e) {
txn->subAbort();
*sts = LDH__DBERROR;
}
return true;
}
bool wb_vrepdbms::renameObject(pwr_tStatus *sts, wb_orep *orp, wb_name &name)
{
*sts = LDH__SUCCESS;
wb_dbms_txn *txn = m_db->subBegin(m_db->m_txn);
try {
int rc = 0;
m_ohead.get(txn, orp->oid());
wb_dbms_name n(m_db, m_ohead);
rc = n.del(txn);
if (rc)
printf("wb_vrepdbms::renameObject, n.del rc %d\n", rc);
n.name(name);
rc = n.ins(txn);
if (rc) {
printf("wb_vrepdbms::renameObject, n.ins rc %d\n", rc);
*sts = LDH__NAMALREXI;
txn->abort();
m_ohead.clear();
return false;
}
m_ohead.name(name);
m_ohead.upd(txn);
txn->subCommit();
return true;
}
catch (wb_dbms_error &e) {
txn->subAbort();
printf("wb_vrepdbms::renameObject, exception %s\n", e.what().c_str());
m_ohead.clear();
*sts = LDH__DBERROR;
return false;
}
}
bool wb_vrepdbms::writeAttribute(pwr_tStatus *sts, wb_orep *orp, pwr_eBix bix, size_t offset, size_t size, void *p)
{
try {
int rc = 0;
m_ohead.get(m_db->m_txn, orp->oid());
*sts = LDH__SUCCESS;
pwr_tTime time;
clock_gettime(CLOCK_REALTIME, &time);
switch (bix) {
case pwr_eBix_rt:
{
wb_dbms_rbody rb(m_db, m_ohead.oid());
rc = rb.upd(m_db->m_txn, offset, size, p);
m_ohead.rbTime(time);
m_ohead.upd(m_db->m_txn);
if (rc)
printf("wb_vrepdbms::writeAttribute rb.upd rc %d\n", rc);
break;
}
case pwr_eBix_dev:
{
wb_dbms_dbody db(m_db, m_ohead.oid());
rc = db.upd(m_db->m_txn, offset, size, p);
m_ohead.dbTime(time);
m_ohead.upd(m_db->m_txn);
if (rc)
printf("wb_vrepdbms::writeAttribute db.upd rc %d\n", rc);
break;
}
default:
break;
}
return true;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return false;
}
}
void *wb_vrepdbms::readAttribute(pwr_tStatus *sts, const wb_orep *orp, pwr_eBix bix, size_t offset, size_t size, void *p)
{
int rc = 0;
try {
m_ohead.get(m_db->m_txn, orp->oid());
*sts = LDH__SUCCESS;
switch (bix) {
case pwr_eBix_rt:
{
wb_dbms_rbody rb(m_db, m_ohead.oid());
rc = rb.get(m_db->m_txn, offset, size, p);
break;
}
case pwr_eBix_dev:
{
wb_dbms_dbody db(m_db, m_ohead.oid());
rc = db.get(m_db->m_txn, offset, size, p);
break;
}
default:
p = 0;
}
if (rc)
*sts = LDH__NOSUCHATTR;
return p;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHATTR;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
void *wb_vrepdbms::readBody(pwr_tStatus *sts, const wb_orep *orp, pwr_eBix bix, void *p)
{
int rc = 0;
try {
m_ohead.get(m_db->m_txn, orp->oid());
*sts = LDH__SUCCESS;
switch (bix) {
case pwr_eBix_rt:
{
wb_dbms_rbody rb(m_db, m_ohead.oid());
rc = rb.get(m_db->m_txn, 0, m_ohead.rbSize(), p);
break;
}
case pwr_eBix_dev:
{
wb_dbms_dbody db(m_db, m_ohead.oid());
rc = db.get(m_db->m_txn, 0, m_ohead.dbSize(), p);
break;
}
default:
p = 0;
}
if (rc)
*sts = LDH__NOSUCHBODY;
return p;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHBODY;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
bool wb_vrepdbms::writeBody(pwr_tStatus *sts, wb_orep *o, pwr_eBix bix, void *p)
{
try {
int rc = 0;
m_ohead.get(m_db->m_txn, o->oid());
*sts = LDH__SUCCESS;
pwr_tTime time;
clock_gettime(CLOCK_REALTIME, &time);
switch (bix) {
case pwr_eBix_rt:
{
wb_dbms_rbody rb(m_db, m_ohead.oid());
rc = rb.upd(m_db->m_txn, 0, m_ohead.rbSize(), p);
if (rc)
printf("wb_vrepdbms::writeBody rb.upd rc %d\n", rc);
m_ohead.rbTime(time);
m_ohead.upd(m_db->m_txn);
break;
}
case pwr_eBix_dev:
{
wb_dbms_dbody db(m_db, m_ohead.oid());
rc = db.upd(m_db->m_txn, 0, m_ohead.dbSize(), p);
if (rc)
printf("wb_vrepdbms::writeBody db.upd rc %d\n", rc);
m_ohead.dbTime(time);
m_ohead.upd(m_db->m_txn);
break;
}
default:
break;
}
return true;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return false;
}
}
wb_orep *wb_vrepdbms::ancestor(pwr_tStatus *sts, const wb_orep *o)
{
*sts = LDH__NYI;
return 0;
}
pwr_tCid wb_vrepdbms::cid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).cid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
pwr_tTime wb_vrepdbms::ohTime(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).ohTime();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
pwr_tTime t = {0, 0};
printf("vrepdbms: %s\n", e.what().c_str());
return t;
}
}
pwr_tTime wb_vrepdbms::rbTime(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).rbTime();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
pwr_tTime t = {0, 0};
printf("vrepdbms: %s\n", e.what().c_str());
return t;
}
}
pwr_tTime wb_vrepdbms::dbTime(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).dbTime();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
pwr_tTime t = {0, 0};
printf("vrepdbms: %s\n", e.what().c_str());
return t;
}
}
pwr_mClassDef wb_vrepdbms::flags(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).flags();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
pwr_mClassDef flags; flags.m = 0;
return flags;
}
}
pwr_tVid wb_vrepdbms::vid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).vid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNVid;
}
}
pwr_tOid wb_vrepdbms::oid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).oid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOid;
}
}
pwr_tOix wb_vrepdbms::oix(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).oix();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOix;
}
}
pwr_tOid wb_vrepdbms::poid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).poid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOid;
}
}
pwr_tOid wb_vrepdbms::foid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).foid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOid;
}
}
pwr_tOid wb_vrepdbms::loid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).loid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOid;
}
}
pwr_tOid wb_vrepdbms::aoid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).aoid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOid;
}
}
pwr_tOid wb_vrepdbms::boid(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
return m_ohead.get(m_db->m_txn, orp->oid()).boid();
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return pwr_cNOid;
}
}
wb_orep *wb_vrepdbms::parent(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
m_ohead.get(m_db->m_txn, m_ohead.get(m_db->m_txn, orp->oid()).poid());
if ( m_ohead.oid().oix == 0) {
*sts = LDH__NO_PARENT;
return 0;
}
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::after(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
pwr_tOid aoid = m_ohead.get(m_db->m_txn, orp->oid()).aoid();
if (cdh_ObjidIsNull(aoid)) {
*sts = LDH__NO_SIBLING;
return 0;
}
m_ohead.get(m_db->m_txn, aoid);
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::before(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
pwr_tOid boid = m_ohead.get(m_db->m_txn, orp->oid()).boid();
if (cdh_ObjidIsNull(boid)) {
*sts = LDH__NO_SIBLING;
return 0;
}
m_ohead.get(m_db->m_txn, boid);
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::first(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
pwr_tOid foid = m_ohead.get(m_db->m_txn, orp->oid()).foid();
if (cdh_ObjidIsNull(foid)) {
*sts = LDH__NO_CHILD;
return 0;
}
m_ohead.get(m_db->m_txn, foid);
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::child(pwr_tStatus *sts, const wb_orep *orp, wb_name &name)
{
*sts = LDH__SUCCESS;
try {
wb_dbms_name n(m_db, m_db->m_txn, orp->oid(), name);
m_ohead.get(m_db->m_txn, n.oid());
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::last(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
pwr_tOid loid = m_ohead.get(m_db->m_txn, orp->oid()).loid();
if (cdh_ObjidIsNull(loid)) {
*sts = LDH__NO_CHILD;
return 0;
}
m_ohead.get(m_db->m_txn, loid);
return new (this) wb_orepdbms(&m_ohead.m_o);
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::object(pwr_tStatus *sts, pwr_tCid cid)
{
*sts = LDH__SUCCESS;
try {
wb_dbms_class c(m_db, m_db->m_txn, cid);
pwr_tOid oid;
oid.vid = m_vid;
oid.oix = 0;
if (c.succ(oid)) {
if (c.cid() == cid) {
m_ohead.get(m_db->m_txn, c.oid());
return new (this) wb_orepdbms(&m_ohead.m_o);
}
}
*sts = LDH__NOSUCHOBJ;
return 0;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::next(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
m_ohead.get(m_db->m_txn, orp->oid());
wb_dbms_class c(m_db, m_db->m_txn, m_ohead.cid());
if (c.succ(m_ohead.oid())) {
if (c.cid() == m_ohead.cid()) {
m_ohead.get(m_db->m_txn, c.oid());
return new (this) wb_orepdbms(&m_ohead.m_o);
}
}
*sts = LDH__NOSUCHOBJ;
return 0;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::nextClass(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
m_ohead.get(m_db->m_txn, orp->oid());
wb_dbms_class c(m_db, m_db->m_txn, m_ohead.cid());
if (c.succClass(m_ohead.cid())) {
if ( c.cid() == m_ohead.cid()) {
m_ohead.get(m_db->m_txn, c.oid());
return new (this) wb_orepdbms(&m_ohead.m_o);
}
}
*sts = LDH__NOSUCHOBJ;
return 0;
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms: %s\n", e.what().c_str());
return 0;
}
}
wb_orep *wb_vrepdbms::previous(pwr_tStatus *sts, const wb_orep *orp)
{
*sts = LDH__SUCCESS;
try {
m_ohead.get(m_db->m_txn, orp->oid());
wb_dbms_class c(m_db, m_db->m_txn, m_ohead.cid());
if (c.pred(m_ohead.oid())) {
m_ohead.get(m_db->m_txn, c.oid());
return new (this) wb_orepdbms(&m_ohead.m_o);
} else {
//*sts = LDH__?;
return 0;
}
}
catch (wb_dbms_error &e) {
*sts = LDH__NOSUCHOBJ;
printf("vrepdbms %s\n", e.what().c_str());
return 0;
}
}
void wb_vrepdbms::adopt(wb_dbms_txn *txn, wb_dbms_ohead &o, wb_destination &dest)
{
int rc = 0;
wb_dbms_ohead d(m_db, txn, dest.oid());
switch (dest.code()) {
case ldh_eDest_IntoFirst:
o.poid(d.oid());
o.boid(pwr_cNOid);
o.aoid(d.foid());
break;
case ldh_eDest_IntoLast:
o.poid(d.oid());
o.aoid(pwr_cNOid);
o.boid(d.loid());
break;
case ldh_eDest_After:
o.poid(d.poid());
o.boid(d.oid());
o.aoid(d.aoid());
break;
case ldh_eDest_Before:
o.poid(d.poid());
o.boid(d.boid());
o.aoid(d.oid());
break;
default:
;// throw
}
wb_dbms_ohead p(m_db, txn, o.poid());
if (o.boid().vid != pwr_cNVid) {
wb_dbms_ohead b(m_db, txn, o.boid());
b.aoid(o.oid());
rc = b.upd(txn);
if (rc)
printf("wb_vrepdbms:adopt, b.upd rc %d\n", rc);
} else {
p.foid(o.oid());
}
if (o.aoid().vid != pwr_cNVid) {
wb_dbms_ohead a(m_db, txn, o.aoid());
a.boid(o.oid());
rc = a.upd(txn);
if (rc)
printf("wb_vrepdbms:adopt, a.upd rc %d\n", rc);
} else {
p.loid(o.oid());
}
rc = p.upd(txn);
if (rc)
printf("wb_vrepdbms:adopt, p.upd rc %d\n", rc);
wb_dbms_name n(m_db, o.oid(), o.poid(), o.normname());
rc = n.ins(txn);
if (rc) {
printf("wb_vrepdbms:adopt, n.ins rc %d\n", rc);
throw wb_error(LDH__NAMALREXI);
}
}
void wb_vrepdbms::unadopt(wb_dbms_txn *txn, wb_dbms_ohead &o)
{
int rc = 0;
wb_dbms_ohead p(m_db, txn, o.poid());
if (o.boid().vid != pwr_cNVid) {
wb_dbms_ohead b(m_db, txn, o.boid());
b.aoid(o.aoid());
rc = b.upd(txn);
if (rc)
printf("wb_vrepdbms:unadopt, b.upd rc %d\n", rc);
} else {
p.foid(o.aoid());
}
if (o.aoid().vid != pwr_cNVid) {
wb_dbms_ohead a(m_db, txn, o.aoid());
a.boid(o.boid());
rc = a.upd(txn);
if (rc)
printf("wb_vrepdbms:unadopt, a.upd rc %d\n", rc);
} else {
p.loid(o.boid());
}
wb_dbms_name n(m_db, o.oid(), o.poid(), o.normname());
rc = n.del(txn);
if (rc)
printf("wb_vrepdbms:unadopt, n.del rc %d\n", rc);
o.poid(pwr_cNOid);
o.aoid(pwr_cNOid);
o.boid(pwr_cNOid);
rc = p.upd(txn);
if (rc)
printf("wb_vrepdbms:unadopt, p.upd rc %d\n", rc);
rc = o.upd(txn);
if (rc)
printf("wb_vrepdbms:unadopt, o.upd rc %d\n", rc);
}
bool wb_vrepdbms::exportVolume(wb_import &i)
{
return i.importVolume(*this);
}
bool wb_vrepdbms::exportHead(wb_import &i)
{
wb_dbms_ohead *op = new wb_dbms_ohead(m_db);
op->iter(i);
delete(op);
return true;
}
bool wb_vrepdbms::exportRbody(wb_import &i)
{
wb_dbms_rbody *rp = new wb_dbms_rbody(m_db);
rp->iter(i);
delete(rp);
return true;
}
bool wb_vrepdbms::exportDbody(wb_import &i)
{
wb_dbms_dbody *dp = new wb_dbms_dbody(m_db);
dp->iter(i);
delete(dp);
return true;
}
bool wb_vrepdbms::exportDocBlock(wb_import &i)
{
return false;
}
bool wb_vrepdbms::exportMeta(wb_import &i)
{
return false;
}
bool wb_vrepdbms::exportTree(wb_treeimport &i, pwr_tOid oid)
{
return exportTreeHelper(i, oid, true);
}
bool wb_vrepdbms::exportTreeHelper(wb_treeimport &i, pwr_tOid oid, bool isRoot)
{
m_ohead.get(m_db->m_txn, oid);
void *rbody = 0;
void *dbody = 0;
int rbSize = m_ohead.rbSize();
int dbSize = m_ohead.dbSize();
if (rbSize) {
rbody = (void *)malloc(rbSize);
wb_dbms_rbody rb(m_db, oid);
int rc = rb.get(m_db->m_txn, 0, rbSize, rbody);
if (rc)
printf("wb_vrepdbms::exportTreeObject, rb.get: %d\n", rc);
}
if (dbSize) {
dbody = (void *)malloc(dbSize);
wb_dbms_dbody db(m_db, oid);
int rc = db.get(m_db->m_txn, 0, dbSize, dbody);
if (rc)
printf("wb_vrepdbms::exportTreeObject, db.get: %d\n", rc);
}
pwr_mClassDef flags = m_ohead.flags(); // flags.m = 0; // Fix !!!
if (isRoot) {
i.importTreeObject(m_merep, m_ohead.oid(), m_ohead.cid(), pwr_cNOid, pwr_cNOid, m_ohead.name(), flags,
m_ohead.rbSize(), m_ohead.dbSize(), rbody, dbody);
} else {
i.importTreeObject(m_merep, m_ohead.oid(), m_ohead.cid(), m_ohead.poid(), m_ohead.boid(), m_ohead.name(), flags,
m_ohead.rbSize(), m_ohead.dbSize(), rbody, dbody);
}
if (rbSize)
free(rbody);
if (dbSize)
free(dbody);
oid = m_ohead.foid();
while (cdh_ObjidIsNotNull(oid)) {
exportTreeHelper(i, oid, false);
m_ohead.get(m_db->m_txn, oid);
oid = m_ohead.aoid();
}
return true;
}
wb_orepdbms *wb_vrepdbms::new_wb_orepdbms(size_t size)
{
wb_orepdbms*o = (wb_orepdbms*) calloc(1, size);
o->m_vrep = this;
return o;
}
void wb_vrepdbms::delete_wb_orepdbms(void *p)
{
free(p);
}
bool wb_vrepdbms::importPasteObject(pwr_tOid doid, ldh_eDest destcode,
bool keepoid, pwr_tOid oid,
pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, const char *name, pwr_mClassDef flags,
size_t rbSize, size_t dbSize, void *rbody, void *dbody,
pwr_tOid *roid)
{
pwr_tStatus sts;
static pwr_tTime oTime;
if (cdh_ObjidIsNull(poid) && cdh_ObjidIsNull(boid)) {
if (m_oid_th) {
tree_DeleteTable(&sts, m_oid_th);
}
importTranslationTableClear();
importSetSourceVid(oid.vid);
m_oid_th = tree_CreateTable(&sts, sizeof(pwr_tOid), offsetof(sOentry, o_oid), sizeof(sOentry), 1000, tree_Comp_oid);
m_poep = (sOentry *)tree_Insert(&sts, m_oid_th, &poid);
clock_gettime(CLOCK_REALTIME, &oTime);
memset(&m_destination, 0, sizeof(m_destination));
m_destination.oid = doid;
if (cdh_ObjidIsNotNull(doid)) {
try {
m_ohead.get(m_db->m_txn, doid);
}
catch (wb_dbms_error &e) {
printf("vrepdbms desination (%d.%d) does not exist: %s\n", doid.vid, doid.oix, e.what().c_str());
throw wb_error(LDH__PASTEINCON);
}
}
switch (destcode) {
case ldh_eDest_After:
m_destination.poid = m_ohead.poid();
m_destination.foid = m_ohead.oid();
m_destination.loid = m_ohead.aoid();
break;
case ldh_eDest_Before:
m_destination.poid = m_ohead.poid();
m_destination.foid = m_ohead.boid();
m_destination.loid = m_ohead.oid();
break;
case ldh_eDest_IntoFirst:
m_destination.poid = m_ohead.oid();
m_destination.loid = m_ohead.foid();
break;
case ldh_eDest_IntoLast:
m_destination.poid = m_ohead.oid();
m_destination.foid = m_ohead.loid();
break;
default:
throw wb_error(LDH__NYI);
}
m_poep->n_oid = m_destination.poid;
}
sOentry *oep = (sOentry *)tree_Insert(&sts, m_oid_th, &oid);
sOentry *poep = oep->parent = (sOentry *)tree_Insert(&sts, m_oid_th, &poid);
if (cdh_ObjidIsNotNull(boid)) {
oep->before = (sOentry *)tree_Insert(&sts, m_oid_th, &boid);
poep->last = oep->before->after = oep;
} else {
poep->first = poep->last = oep;
}
if (keepoid) {
oep->n_oid = m_db->new_oid(m_db->m_txn, oid);
} else {
oep->n_oid = m_db->new_oid(m_db->m_txn);
}
importTranslationTableInsert(oid.oix, oep->n_oid.oix);
wb_name n(name);
m_db->importHead(oep->n_oid, cid, oep->parent->n_oid, pwr_cNOid, pwr_cNOid, pwr_cNOid, pwr_cNOid,
name, n.normName(), flags, oTime, oTime, oTime, rbSize, dbSize);
if (rbSize > 0) {
m_db->importRbody(oep->n_oid, rbSize, rbody);
}
if (dbSize > 0) {
m_db->importDbody(oep->n_oid, dbSize, dbody);
}
return true;
}
bool wb_vrepdbms::importPaste()
{
pwr_tStatus sts;
pwr_tTime oTime;
clock_gettime(CLOCK_REALTIME, &oTime);
sOentry *oep = (sOentry*)tree_Minimum(&sts, m_oid_th);
while (oep) {
if (oep != m_poep) {
m_ohead.get(m_db->m_txn, oep->n_oid);
m_ohead.poid(oep->parent->n_oid);
if (oep->before)
m_ohead.boid(oep->before->n_oid);
if (oep->after)
m_ohead.aoid(oep->after->n_oid);
if (oep->first)
m_ohead.foid(oep->first->n_oid);
if (oep->last)
m_ohead.loid(oep->last->n_oid);
m_ohead.ohTime(oTime);
m_ohead.ins(m_db->m_txn);
}
oep = (sOentry*)tree_Successor(&sts, m_oid_th, oep);
}
if (cdh_ObjidIsNull(m_destination.foid)) {
m_ohead.get(m_db->m_txn, m_destination.poid);
m_ohead.foid(m_poep->first->n_oid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
if (cdh_ObjidIsNotNull(m_destination.loid)) {
m_ohead.get(m_db->m_txn, m_destination.loid);
m_ohead.boid(m_poep->last->n_oid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
m_ohead.get(m_db->m_txn, m_poep->last->n_oid);
m_ohead.aoid(m_destination.loid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
}
}
if (cdh_ObjidIsNull(m_destination.loid)) {
m_ohead.get(m_db->m_txn, m_destination.poid);
m_ohead.loid(m_poep->last->n_oid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
if (cdh_ObjidIsNotNull(m_destination.foid)) {
m_ohead.get(m_db->m_txn, m_destination.foid);
m_ohead.aoid(m_poep->first->n_oid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
m_ohead.get(m_db->m_txn, m_poep->first->n_oid);
m_ohead.boid(m_destination.foid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
}
}
if (cdh_ObjidIsNotNull(m_destination.foid) && cdh_ObjidIsNotNull(m_destination.loid)) {
m_ohead.get(m_db->m_txn, m_destination.foid);
m_ohead.aoid(m_poep->first->n_oid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
m_ohead.get(m_db->m_txn, m_poep->first->n_oid);
m_ohead.boid(m_destination.foid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
m_ohead.get(m_db->m_txn, m_destination.loid);
m_ohead.boid(m_poep->last->n_oid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
m_ohead.get(m_db->m_txn, m_poep->last->n_oid);
m_ohead.aoid(m_destination.loid);
m_ohead.ohTime(oTime);
m_ohead.upd(m_db->m_txn);
}
importUpdateTree(this);
importTranslationTableClear();
tree_DeleteTable(&sts, m_oid_th);
m_oid_th = 0;
return true;
}
pwr_tStatus wb_vrepdbms::checkMeta()
{
pwr_tStatus sts = LDH__SUCCESS;
pwr_tStatus db_sts = LDH__SUCCESS;
int totalObjectCount = 0;
int nAref = 0;
int nClass = 0;
m_class_th = tree_CreateTable(&sts, sizeof(pwr_tCid), offsetof(sClass, cid), sizeof(sClass), 1000, tree_Comp_cid);
m_aref_th = tree_CreateTable(&sts, sizeof(sArefKey), offsetof(sAref, key), sizeof(sAref), 1000, comp_aref);
m_attribute_th = tree_CreateTable(&sts, sizeof(sAttributeKey), offsetof(sAttribute, key), sizeof(sAttribute), 1000, comp_attribute);
try {
wb_dbms_class_iterator ip(m_db);
for (ip.first(); !ip.atEnd(); ip.succClass()) {
nClass += checkClass(ip.cid());
checkAttributes(ip.cid());
}
for (ip.first(); !ip.atEnd(); ip.succObject()) {
pwr_tCid cid = ip.cid();
sClass *cp = (sClass *)tree_Find(&sts, m_class_th, &cid);
if (!cp)
continue;
cp->count++;
if (time_IsNull(&cp->n_time))
continue;
}
} catch (wb_dbms_error &e) {
printf("***wb_dbms_error vrepdbms: %s\n", e.what().c_str());
db_sts = LDH__DBERROR;
} catch (wb_error &e) {
printf("***wb_error vrepdbms: %s\n", e.what().c_str());
db_sts = LDH__DBERROR;
}
for (
sClass *cp = (sClass *)tree_Minimum(&sts, m_class_th);
cp != NULL;
cp = (sClass *)tree_Successor(&sts, m_class_th, cp)
) {
char o_timbuf[32];
char n_timbuf[32];
if (cp->count > 0) {
char buff[256];
if (time_IsNull(&cp->n_time)) {
time_AtoAscii(&cp->o_time, time_eFormat_DateAndTime, o_timbuf, sizeof(o_timbuf));
sprintf(buff, "Class \"%s\" [%s], %d object%s, does not exist in global scope",
cp->name, o_timbuf, cp->count, (cp->count == 1 ? "" : "s"));
MsgWindow::message('W', buff);
} else {
time_AtoAscii(&cp->o_time, time_eFormat_NumDateAndTime, o_timbuf, sizeof(o_timbuf));
time_AtoAscii(&cp->n_time, time_eFormat_NumDateAndTime, n_timbuf, sizeof(n_timbuf));
sprintf(buff, "Class \"%s\" [%s], %d object%s, can be updated to [%s]",
cp->name, o_timbuf, cp->count, (cp->count == 1 ? "" : "s"), n_timbuf);
MsgWindow::message('W', buff, msgw_ePop_No);
totalObjectCount += cp->count;
}
}
}
if (ODD(db_sts) && tree_Cardinality(&sts, m_class_th) != 0) {
char buff[256];
sprintf(buff, "A total of %d object%s of %d class%s, and %d attribute reference%s can be updated",
totalObjectCount, (totalObjectCount == 1 ? "" : "s"),
tree_Cardinality(&sts, m_class_th), (tree_Cardinality(&sts, m_class_th) == 1 ? "" : "es"),
nAref, (nAref == 1 ? "" : "s"));
MsgWindow::message('W', buff, msgw_ePop_No);
MsgWindow::message( 'W', "Classvolumes need update, execute 'Function->UpdateClasses'");
}
tree_DeleteTable(&sts, m_attribute_th);
tree_DeleteTable(&sts, m_aref_th);
tree_DeleteTable(&sts, m_class_th);
return sts;
}
static int
comp_attribute(tree_sTable *tp, tree_sNode *x, tree_sNode *y)
{
sAttribute *xp = (sAttribute *) x;
sAttribute *yp = (sAttribute *) y;
if (xp->key.cid > yp->key.cid)
return 1;
if (xp->key.cid < yp->key.cid)
return -1;
if (xp->key.bix > yp->key.bix)
return 1;
if (xp->key.bix < yp->key.bix)
return -1;
if (xp->key.oStart > yp->key.oEnd)
return 1;
if (xp->key.oEnd < yp->key.oStart)
return -1;
return 0;
}
static int
comp_aref(tree_sTable *tp, tree_sNode *x, tree_sNode *y)
{
sAref *xp = (sAref *) x;
sAref *yp = (sAref *) y;
if (xp->key.cid > yp->key.cid)
return 1;
if (xp->key.cid < yp->key.cid)
return -1;
if (xp->key.bix > yp->key.bix)
return 1;
if (xp->key.bix < yp->key.bix)
return -1;
if (xp->key.offset > yp->key.offset)
return 1;
if (xp->key.offset < yp->key.offset)
return -1;
return 0;
}
int wb_vrepdbms::updateArefs(pwr_tOid oid, pwr_tCid cid)
{
pwr_tStatus sts;
sArefKey ak;
int nAref[2] = {0, 0};
int rbSize = 0;
int dbSize = 0;
int rrc = 0;
int drc = 0;
ak.cid = cid;
ak.bix = pwr_eBix__;
ak.offset = 0;
char *rp = 0;
char *dp = 0;
sAref *ap = (sAref *)tree_FindSuccessor(&sts, m_aref_th, &ak);
if (ap == 0 || ap->key.cid != cid)
return 0;
try {
wb_dbms_ohead ohead(m_db, m_db->m_txn, oid);
rbSize = ohead.rbSize();
dbSize = ohead.dbSize();
wb_dbms_rbody rb(m_db, ohead.oid());
wb_dbms_dbody db(m_db, ohead.oid());
if (rbSize) {
rp = (char *)calloc(1, rbSize);
rrc = rb.get(m_db->m_txn, 0, rbSize, rp);
}
if (dbSize) {
dp = (char *)calloc(1, dbSize);
drc = db.get(m_db->m_txn, 0, dbSize, dp);
}
} catch (wb_dbms_error &e) {
ap = 0;
} catch (wb_error &e) {
ap = 0;
}
while (ap != 0 && ap->key.cid == cid) {
char *p = 0;
if (ap->key.bix == pwr_eBix_rt)
p = rp;
else if (ap->key.bix == pwr_eBix_dev)
p = dp;
else
p = 0;
if (p != 0) {
try {
pwr_sAttrRef *arp = (pwr_sAttrRef *)(p + ap->key.offset);
wb_db_ohead aohead(m_db, m_db->m_txn, arp->Objid);
wb_cdrep *n_cdrep = m_erep->merep()->cdrep(&sts, aohead.cid());
wb_bdrep *n_bdrep;
if (EVEN(sts))
printf("cdrep sts %d", sts);
else
n_bdrep = n_cdrep->bdrep(&sts, ap->key.bix);
if (EVEN(sts)) {
ap = (sAref *)tree_FindSuccessor(&sts, m_aref_th, &ap->key);
continue;
}
if ( arp->Flags.b.Object) {
// Check if rbody size of changed
pwr_tCid cid = aohead.cid();
sClass *cp = (sClass *)tree_Find(&sts, m_class_th, &cid);
if ( cp && cp->n_rbsize != cp->o_rbsize) {
arp->Size = cp->n_rbsize;
nAref[ap->key.bix - 1]++;
}
}
else {
sAttributeKey k;
k.cid = aohead.cid();
k.bix = ap->key.bix;
k.oStart = arp->Offset;
k.oEnd = arp->Offset + arp->Size - 1;
sAttribute *cap = (sAttribute *)tree_Find(&sts, m_attribute_th, &k);
if (cap != 0) {
nAref[ap->key.bix - 1]++;
if (arp->Size > cap->o.aref.Size) {
arp->Offset = 0;
arp->Size = n_bdrep->size();
} else if (arp->Offset == cap->o.aref.Offset && arp->Size == cap->o.aref.Size) {
arp->Offset = cap->n.aref.Offset;
arp->Size = cap->n.aref.Size;
} else if (cap->o.aref.Flags.b.Array) {
pwr_tUInt32 oElementSize = cap->o.aref.Size / cap->o.nElement;
pwr_tUInt32 oOffset = arp->Offset - cap->o.aref.Offset;
pwr_tUInt32 index = oOffset / oElementSize;
pwr_tUInt32 nElementSize = cap->n.aref.Size / cap->n.nElement;
if (index >= cap->n.nElement) {
index = cap->n.nElement - 1;
}
arp->Offset = cap->n.aref.Offset + (index * nElementSize);
arp->Size = nElementSize;
}
}
}
} catch (wb_dbms_error &e) {
//printf("wb_dbms_error vrepdbmsupdateArefs 2: %s, oid: %d.%d, cid: %d \n", e.what().c_str(), oid.vid, oid.oix, cid);
} catch (wb_error &e) {
//printf("wb_error vrepdbmsupdateArefs 2: oid: %d.%d, cid: %d %s\n", oid.vid, oid.oix, cid, e.what().c_str().c_str());
}
}
ap = (sAref *)tree_FindSuccessor(&sts, m_aref_th, &ap->key);
}
try {
wb_dbms_ohead ohead(m_db, m_db->m_txn, oid);
wb_dbms_rbody rb(m_db, ohead.oid());
wb_dbms_dbody db(m_db, ohead.oid());
if (rbSize && nAref[0]) {
rb.upd(m_db->m_txn, 0, rbSize, rp);
}
if (dbSize && nAref[1]) {
db.upd(m_db->m_txn, 0, dbSize, dp);
}
} catch (wb_dbms_error &e) {
//printf("wb_dbms_error vrepdbmsupdateArefs body.put: oid: %d.%d, cid: %d %s\n", oid.vid, oid.oix, cid, e.what().c_str());
} catch (wb_error &e) {
//printf("wb_error vrepdbmsupdateArefs body.put: oid: %d.%d, cid: %d %s\n", oid.vid, oid.oix, cid, e.what().c_str().c_str());
}
if (rp)
free(rp);
if (dp)
free(dp);
return nAref[0] + nAref[1];
}
pwr_tStatus wb_vrepdbms::updateMeta()
{
int rc = 0;
pwr_tStatus sts = LDH__SUCCESS;
pwr_tStatus db_sts = LDH__SUCCESS;
int nAref = 0;
int nObject = 0;
int nClass = 0;
int totalObjectCount = 0;
m_aref_th = tree_CreateTable(&sts, sizeof(sArefKey), offsetof(sAref, key), sizeof(sAref), 1000, comp_aref);
m_class_th = tree_CreateTable(&sts, sizeof(pwr_tCid), offsetof(sClass, cid), sizeof(sClass), 1000, tree_Comp_cid);
m_attribute_th = tree_CreateTable(&sts, sizeof(sAttributeKey), offsetof(sAttribute, key), sizeof(sAttribute), 1000, comp_attribute);
try {
wb_dbms_class_iterator ip(m_db);
for (ip.first(); !ip.atEnd(); ip.succClass()) {
try {
nClass += checkClass(ip.cid());
checkAttributes(ip.cid());
} catch (wb_error &e) {
printf("vrepdbms::updateMeta: %s\n", e.what().c_str());
}
}
for (ip.first(); !ip.atEnd(); ip.succObject()) {
pwr_tCid cid = ip.cid();
sClass *cp = (sClass *)tree_Find(&sts, m_class_th, &cid);
if (!cp)
continue;
cp->count++;
if (time_IsNull(&cp->n_time))
continue;
nAref += updateArefs(ip.oid(), ip.cid());
nObject += updateObject(ip.oid(), ip.cid());
}
} catch (wb_dbms_error &e) {
printf("vrepdbms:updateMeta: %s\n", e.what().c_str());
db_sts = LDH__DBERROR;
} catch (wb_error &e) {
printf("vrepdbms:updateMeta: %s\n", e.what().c_str());
db_sts = LDH__DBERROR;
}
for (
sClass *cp = (sClass *)tree_Minimum(&sts, m_class_th);
cp != NULL;
cp = (sClass *)tree_Successor(&sts, m_class_th, cp)
) {
char o_timbuf[32];
char n_timbuf[32];
if (cp->count > 0) {
char buff[256];
if (time_IsNull(&cp->n_time)) {
time_AtoAscii(&cp->o_time, time_eFormat_DateAndTime, o_timbuf, sizeof(o_timbuf));
sprintf(buff, "Class \"%s\" [%s], %d object%s, does not exist in global scope",
cp->name, o_timbuf, cp->count, (cp->count == 1 ? "" : "s"));
MsgWindow::message('W', buff);
} else {
time_AtoAscii(&cp->o_time, time_eFormat_NumDateAndTime, o_timbuf, sizeof(o_timbuf));
time_AtoAscii(&cp->n_time, time_eFormat_NumDateAndTime, n_timbuf, sizeof(n_timbuf));
sprintf(buff, "Class \"%s\" [%s], %d object%s, %s updated to [%s]",
cp->name, o_timbuf, cp->count, (cp->count == 1 ? "" : "s"),
(cp->count == 1 ? "was" : "were"), n_timbuf);
MsgWindow::message('I', buff, msgw_ePop_No);
totalObjectCount += cp->count;
}
}
}
if (ODD(db_sts) && tree_Cardinality(&sts, m_class_th) != 0 && totalObjectCount > 0) {
char buff[256];
commit(&rc);
if (rc) {
sprintf(buff, "A total of %d object%s of %d classe%s %s updated, but could not be saved to database.",
nObject, (nObject == 1 ? "" : "s"), tree_Cardinality(&sts, m_class_th),
(tree_Cardinality(&sts, m_class_th) == 1 ? "" : "s"),
(nObject == 1 ? "was" : "were"));
MsgWindow::message(co_error(rc), buff);
db_sts = LDH__DBERROR;
} else {
m_merep->copyFiles(m_fileName, m_erep->merep());
delete m_merep;
m_merep = new wb_merep(m_fileName, m_erep, this);
sprintf(buff, "A total of %d object%s of %d class%s, and %d attribute reference%s, %s updated",
totalObjectCount, (totalObjectCount == 1 ? "" : "s"),
tree_Cardinality(&sts, m_class_th), (tree_Cardinality(&sts, m_class_th) == 1 ? "" : "es"),
nAref, (nAref == 1 ? "" : "s"), (nAref == 1 ? "was" : "were"));
MsgWindow::message('I', buff);
}
}
else if ( ODD(db_sts)) {
// No changes, update file only
m_merep->copyFiles(m_fileName, m_erep->merep());
delete m_merep;
m_merep = new wb_merep(m_fileName, m_erep, this);
}
tree_DeleteTable(&sts, m_attribute_th);
tree_DeleteTable(&sts, m_aref_th);
tree_DeleteTable(&sts, m_class_th);
return sts;
}
/* Check if class is changed, return 1 if it is. */
int
wb_vrepdbms::checkClass(pwr_tCid cid)
{
static wb_cdrep *o_crep = 0;
static wb_cdrep *n_crep = 0;
pwr_tTime o_time = {0, 0};
pwr_tTime n_time = {0, 0};
pwr_tStatus sts;
o_crep = m_merep->cdrep(&sts, cid);
if (o_crep == 0) {
// Class does not exist
return 0;
}
o_time = o_crep->ohTime();
n_crep = m_erep->merep()->cdrep(&sts, cid);
if (n_crep == 0)
throw wb_error( LDH__NOSUCHCLASS);
n_time = n_crep->ohTime();
if (time_Acomp(&o_time, &n_time) != 0) {
sClass *ccp = (sClass *)tree_Insert(&sts, m_class_th, &cid);
ccp->o_time = o_time;
ccp->n_time = n_time;
ccp->o_rbsize = o_crep->size( pwr_eBix_rt);
ccp->n_rbsize = n_crep->size( pwr_eBix_rt);
strcpy(ccp->name, o_crep->name());
return 1;
}
return 0;
}
int
wb_vrepdbms::updateObject(pwr_tOid oid, pwr_tCid cid)
{
pwr_tStatus sts;
wb_cdrep *n_crep = m_erep->merep()->cdrep(&sts, cid);
if (n_crep == 0) {
return 0;
}
m_ohead.get(m_db->m_txn, oid);
wb_dbms_rbody rb(m_db, m_ohead.oid());
void *rp = calloc(1, m_ohead.rbSize());
if (m_ohead.rbSize())
rb.get(m_db->m_txn, 0, m_ohead.rbSize(), rp);
wb_dbms_dbody db(m_db, m_ohead.oid());
void *dp = calloc(1, m_ohead.dbSize());
if (m_ohead.dbSize())
db.get(m_db->m_txn, 0, m_ohead.dbSize(), dp);
void *rbody = 0;
void *dbody = 0;
pwr_tUInt32 rsize;
pwr_tUInt32 dsize;
int rc = 0;
n_crep->convertObject(m_merep, rp, dp, &rsize, &dsize, &rbody, &dbody);
if (rp)
free(rp);
if (dp)
free(dp);
pwr_tTime time;
clock_gettime(CLOCK_REALTIME, &time);
if (rbody) {
rc = rb.upd(m_db->m_txn, 0, rsize, rbody);
if (rc)
printf("wb_vrepdbms:writeBody rb.upd rc %d\n", rc);
rc = 0;
free(rbody);
m_ohead.rbSize(rsize);
m_ohead.rbTime(time);
}
if (dbody) {
rc = db.upd(m_db->m_txn, 0, dsize, dbody);
if (rc)
printf("wb_vrepdbms:writeBody db.upd rc %d\n", rc);
free(dbody);
m_ohead.dbSize(dsize);
m_ohead.dbTime(time);
}
m_ohead.ohTime(time);
m_ohead.upd(m_db->m_txn);
return 1;
}
void wb_vrepdbms::checkAttributes(pwr_tCid cid)
{
pwr_tStatus sts;
wb_cdrep *o_cdrep = m_merep->cdrep(&sts, cid);
if (EVEN(sts)) {
// This is really weird, should not happen.
printf("This is weird, class does not exist in old meta data, cid: %d, sts: %d\n", cid, sts);
return;
}
wb_cdrep *n_cdrep = m_erep->merep()->cdrep(&sts, cid);
if (EVEN(sts)) {
// The class does not exist in the new version of meta data
return;
}
for (int i = 0; i < 2; i++) {
pwr_eBix bix = i ? pwr_eBix_dev: pwr_eBix_rt;
wb_bdrep *n_bdrep = n_cdrep->bdrep(&sts, bix);
if (ODD(sts)) {
wb_bdrep *o_bdrep = o_cdrep->bdrep(&sts, bix);
if (ODD(sts)) {
wb_adrep *o_adrep = o_bdrep->adrep(&sts);
while (ODD(sts)) {
if (o_adrep->type() == pwr_eType_AttrRef) {
sArefKey a;
a.cid = cid;
a.bix = bix;
a.offset = o_adrep->offset();
tree_Insert(&sts, m_aref_th, &a);
}
// Indentify attribute with the same aix
bool found = false;
wb_adrep *n_adrep = n_bdrep->adrep( &sts);
while (ODD(sts)) {
if (o_adrep->aix() == n_adrep->aix()) {
found = true;
break;
}
wb_adrep *prev = n_adrep;
n_adrep = n_adrep->next(&sts);
delete prev;
}
if (found) {
if (
(o_adrep->offset() != n_adrep->offset()) ||
(o_adrep->size() != n_adrep->size()) ||
(o_adrep->type() != n_adrep->type()) ||
//(o_adrep->tid() != n_adrep->tid()) ||
(o_adrep->nElement() != n_adrep->nElement()) ||
(o_adrep->index() != n_adrep->index())
)
{
sAttributeKey ak;
sAttribute *ap;
ak.cid = cid;
ak.bix = bix;
ak.oStart = o_adrep->offset();
ak.oEnd = o_adrep->offset() + o_adrep->size() - 1;
ap = (sAttribute *) tree_Insert(&sts, m_attribute_th, &ak);
ap->o.aref = o_adrep->aref();
ap->n.aref = n_adrep->aref();
ap->o.aix = o_adrep->aix();
ap->n.aix = n_adrep->aix();
ap->o.nElement = o_adrep->nElement();
ap->n.nElement = n_adrep->nElement();
}
if (o_adrep->isClass() && n_adrep->subClass() == o_adrep->subClass()) {
checkSubClass( cid, o_adrep->subClass(), o_adrep->offset(), n_adrep->offset());
}
delete n_adrep;
}
wb_adrep *prev = o_adrep;
o_adrep = o_adrep->next(&sts);
delete prev;
}
if (o_adrep) delete o_adrep;
}
if (o_bdrep) delete o_bdrep;
}
if (n_bdrep) delete n_bdrep;
}
}
void wb_vrepdbms::checkSubClass(pwr_tCid cid, pwr_tCid subcid, unsigned int o_offset, unsigned int n_offset)
{
pwr_tStatus sts;
wb_cdrep *o_cdrep = m_merep->cdrep(&sts, subcid);
if (EVEN(sts)) throw wb_error(sts);
wb_cdrep *n_cdrep = m_erep->merep()->cdrep(&sts, subcid);
if (EVEN(sts)) return;
pwr_eBix bix = pwr_eBix_rt;
wb_bdrep *n_bdrep = n_cdrep->bdrep(&sts, bix);
if (EVEN(sts)) return;
wb_bdrep *o_bdrep = o_cdrep->bdrep(&sts, bix);
if (EVEN(sts)) return;
wb_adrep *o_adrep = o_bdrep->adrep(&sts);
while (ODD(sts)) {
bool found = false;
wb_adrep *n_adrep = n_bdrep->adrep(&sts);
while (ODD(sts)) {
if (o_adrep->aix() == n_adrep->aix()) {
found = true;
break;
}
wb_adrep *prev = n_adrep;
n_adrep = n_adrep->next(&sts);
delete prev;
}
if (found) {
if (
(o_adrep->offset() != n_adrep->offset()) ||
(o_adrep->size() != n_adrep->size()) ||
(o_adrep->type() != n_adrep->type()) ||
//(o_adrep->tid() != n_adrep->tid()) ||
(o_adrep->nElement() != n_adrep->nElement()) ||
(o_adrep->index() != n_adrep->index())) {
sAttributeKey ak;
sAttribute *ap;
ak.cid = cid;
ak.bix = bix;
ak.oStart = o_adrep->offset() + o_offset;
ak.oEnd = ak.oStart + o_adrep->size() - 1;
ap = (sAttribute *) tree_Insert(&sts, m_attribute_th, &ak);
ap->o.aref = o_adrep->aref();
ap->n.aref = n_adrep->aref();
ap->o.aix = o_adrep->aix();
ap->n.aix = n_adrep->aix();
ap->o.nElement = o_adrep->nElement();
ap->n.nElement = n_adrep->nElement();
}
if (o_adrep->isClass() && o_adrep->subClass() == n_adrep->subClass()) {
checkSubClass( cid, n_adrep->subClass(), o_adrep->offset(), n_adrep->offset());
} else if (o_adrep->type() == pwr_eType_AttrRef) {
sArefKey a;
a.cid = subcid;
a.bix = bix;
a.offset = o_adrep->offset();
tree_Insert(&sts, m_aref_th, &a);
}
if (n_adrep) delete n_adrep;
}
wb_adrep *prev = o_adrep;
o_adrep = o_adrep->next(&sts);
delete prev;
}
if (o_cdrep) delete o_cdrep;
if (n_cdrep) delete n_cdrep;
}
#endif
/*
* Proview $Id: wb_vrepdbms.h,v 1.1 2007-10-18 09:11:01 claes Exp $
* Copyright (C) 2007 SSAB Oxelsund AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the program, if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**/
#ifndef wb_vrepdbms_h
#define wb_vrepdbms_h
#if defined PWRE_CONF_MYSQL
#include "wb_vrep.h"
#include "wb_vrepdbs.h"
#include "wb_orepdbms.h"
#include "wb_dbms.h"
#include "co_tree.h"
class wb_vrepdbms : public wb_vrep
{
private:
bool deleteFamilyMember(pwr_tOid oid, wb_dbms_txn *txn);
typedef union {
struct {
pwr_tBit temporary : 1;
pwr_tBit exist : 1;
} b;
pwr_tBitMask m;
#define mOentry_temporary 1
#define mOentry_exist 2
} mOentry;
typedef struct sOentry
{
tree_sNode node;
pwr_tOid o_oid;
pwr_tOid n_oid;
struct sOentry *parent;
struct sOentry *before;
struct sOentry *after;
struct sOentry *first;
struct sOentry *last;
} sOentry;
sOentry *m_poep;
typedef struct sDestination
{
pwr_tOid oid;
pwr_tOid poid;
pwr_tOid foid;
pwr_tOid loid;
} sDestination;
sDestination m_destination;
protected:
wb_erep *m_erep;
wb_merep *m_merep;
//wb_merep *m_merepCheck;
unsigned int m_nRef;
char m_fileName[512];
char guard[500];
tree_sTable *m_attribute_th;
tree_sTable *m_aref_th;
tree_sTable *m_class_th;
public:
wb_dbms *m_db;
wb_dbms_ohead m_ohead;
wb_vrepdbms(wb_erep *erep, const char *fileName);
wb_vrepdbms(wb_erep *erep, pwr_tVid, pwr_tCid, const char *volumeName, const char *fileName);
tree_sTable *m_oid_th;
virtual void unref();
virtual wb_vrep *ref();
virtual ldh_eVolRep type() const { return ldh_eVolRep_Dbms;}
virtual wb_erep *erep();
virtual wb_merep *merep() const;
virtual wb_vrep *next();
virtual pwr_tTime ohTime(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tTime rbTime(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tTime dbTime(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_mClassDef flags(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOid oid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tVid vid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOix oix(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tCid cid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOid poid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOid foid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOid loid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOid boid(pwr_tStatus *sts, const wb_orep *o);
virtual pwr_tOid aoid(pwr_tStatus *sts, const wb_orep *o);
virtual const char * objectName(pwr_tStatus *sts, const wb_orep *o);
virtual wb_name longName(pwr_tStatus *sts, const wb_orep *o);
virtual bool isOffspringOf(pwr_tStatus *sts, const wb_orep *child, const wb_orep *parent);
virtual wb_orep *object(pwr_tStatus *sts);
virtual wb_orep *object(pwr_tStatus *sts, pwr_tOid oid);
virtual wb_orep *object(pwr_tStatus *sts, pwr_tCid cid);
virtual wb_orep *object(pwr_tStatus *sts, wb_name &name);
virtual wb_orep *object(pwr_tStatus *sts, const wb_orep *parent, wb_name &name);
virtual wb_orep *createObject(pwr_tStatus *sts, wb_cdef cdef, wb_destination &d, wb_name &name);
virtual wb_orep *copyObject(pwr_tStatus *sts, const wb_orep *orep, wb_destination &d, wb_name &name);
virtual bool copyOset(pwr_tStatus *sts, wb_oset *oset, wb_destination &d);
virtual bool moveObject(pwr_tStatus *sts, wb_orep *orep, wb_destination &d);
virtual bool deleteObject(pwr_tStatus *sts, wb_orep *orep);
virtual bool deleteFamily(pwr_tStatus *sts, wb_orep *orep);
virtual bool deleteOset(pwr_tStatus *sts, wb_oset *oset);
virtual bool renameObject(pwr_tStatus *sts, wb_orep *orep, wb_name &name);
virtual bool commit(pwr_tStatus *sts) {return m_db->commit(sts);}
virtual bool abort(pwr_tStatus *sts) {return m_db->abort(sts);}
virtual bool writeAttribute(pwr_tStatus *sts, wb_orep *o, pwr_eBix bix, size_t offset, size_t size, void *p);
virtual void *readAttribute(pwr_tStatus *sts, const wb_orep *o, pwr_eBix bix, size_t offset, size_t size, void *p);
virtual void *readBody(pwr_tStatus *sts, const wb_orep *o, pwr_eBix bix, void *p);
virtual bool writeBody(pwr_tStatus *sts, wb_orep *o, pwr_eBix bix, void *p);
virtual wb_orep *ancestor(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *parent(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *after(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *before(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *first(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *child(pwr_tStatus *sts, const wb_orep *o, wb_name &name);
virtual wb_orep *last(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *next(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *nextClass(pwr_tStatus *sts, const wb_orep *o);
virtual wb_orep *previous(pwr_tStatus *sts, const wb_orep *o);
virtual wb_srep *newSession();
virtual bool isLocal(const wb_orep *o);
virtual bool createSnapshot(const char *fileName, const pwr_tTime *time);
virtual void objectName(const wb_orep *o, char *str);
void objectName(pwr_tOid oid, char *name, int level);
void load();
pwr_tStatus checkMeta();
pwr_tStatus updateMeta();
int updateArefs(pwr_tOid oid, pwr_tCid cid);
int checkClass(pwr_tCid cid);
void checkAttributes(pwr_tCid cid);
void checkSubClass(pwr_tCid cid, unsigned int o_offset, unsigned int n_offset);
//bool classIsChanged(pwr_tCid cid);
virtual bool exportVolume(wb_import &e);
virtual bool exportHead(wb_import &e);
virtual bool exportRbody(wb_import &e);
virtual bool exportDbody(wb_import &e);
virtual bool exportDocBlock(wb_import &e);
virtual bool exportMeta(wb_import &e);
virtual bool exportTree(wb_treeimport &i, pwr_tOid oid);
bool exportTreeHelper(wb_treeimport &i, pwr_tOid oid, bool isRoot);
virtual bool importTree(bool keepref) { return false;}
virtual bool importTreeObject(wb_merep *merep, pwr_tOid oid, pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, const char *name, pwr_mClassDef flags,
size_t rbSize, size_t dbSize, void *rbody, void *dbody)
{ return false;}
virtual bool importPaste();
virtual bool importPasteObject(pwr_tOid destination, ldh_eDest destcode,
bool keepoid, pwr_tOid oid,
pwr_tCid cid, pwr_tOid poid,
pwr_tOid boid, const char *name, pwr_mClassDef flags,
size_t rbSize, size_t dbSize, void *rbody, void *dbody,
pwr_tOid *roid);
virtual void importIgnoreErrors() {}
#if 0
int del_family(DbTxn *txn, Dbc *cp, pwr_tOid poid);
#endif
void unadopt(wb_dbms_txn *txn, wb_dbms_ohead &o);
void adopt(wb_dbms_txn *txn, wb_dbms_ohead &o, wb_destination &dest);
wb_orepdbms *new_wb_orepdbms(size_t size);
void delete_wb_orepdbms(void *p);
virtual bool accessSupported( ldh_eAccess access) { return true;}
virtual const char *fileName() { return m_fileName;}
// virtual void checkClassList(pwr_tOid oid, pwr_tCid cid, bool update);
int updateObject(pwr_tOid oid, pwr_tCid cid);
//pwr_tStatus checkObject(pwr_tOid oid, pwr_tCid cid);
};
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment