/****************************************************************************/ // SQLMGR.C v1.0 - 06 11 1990 /****************************************************************************/ /* */ /* Copyright (c) 1989-1993 Bernhard Strassl */ /* Institute for Applied Computer Science and Information Systems */ /* University of Vienna, Austria */ /* */ /* See file COPYRIGHT in this directory for details. If this file is */ /* missing please mail to bernhard@ani.univie.ac.at */ /****************************************************************************/ #include #include #include #include #include #include #include #include SqlMgr::SqlMgr(const char* uidstr) { if(!(uidstr && start(uidstr))) { curUID = NULL; svr = NULL; immHandle = 0; active = FALSE; } } SqlMgr::~SqlMgr() { if(active == TRUE) svr->disconnect(allCursors->at(immHandle)); delete svr; if(curUID != NULL) free(curUID); } bool SqlMgr::start(const char* uidstr) { if(curUID != NULL) free(curUID); curUID = strdup(uidstr); CursorInfo* ci; svr = new SqlSvr; active = FALSE; if((ci = svr->connect(curUID)) != (CursorInfo* )NULL) { immHandle = ci->cndx; active = TRUE; } else cb_error("class SqlManager: connect failed"); return(active); } SqlHandle SqlMgr::open(const char* stmt, ...) { SqlParser p; BindDescr* all; BindInfo* bi; CursorInfo* ci; char *sqlStmt, *stmtb; if(active == FALSE) return(0); stmtb = strdup(stmt); sqlStmt = p.parse(stmtb); all = p.getAll(); int i = 0; va_list ap; va_start(ap, stmt); while(bi = all->next(i)) { void* aPtr = va_arg(ap, void*); bi->setBuffer(aPtr); if(bi->indpFollows()) { short* iPtr = va_arg(ap, short*); bi->setIndp(iPtr); } } va_end(ap); all->itemCount = 0; // prevents deletion of the infos delete all; if((ci = svr->connect(curUID)) == (CursorInfo* )NULL) { cb_error("class SqlManager: connect failed"); free(stmtb); return(0); } if(svr->compile(ci, sqlStmt) == FALSE) { cb_error("class SqlManager: compile failed"); free(stmtb); return(0); } if(bind(ci, p.getInputs(), p.getOutputs()) == FALSE) cb_error("class SqlManager: operation may cause uncorrect results"); free(stmtb); return(ci->cndx); } bool SqlMgr::execute(SqlHandle h) { if(active == TRUE && checkHandle(h) == TRUE) return(svr->exec(allCursors->at(h))); else return(FALSE); } bool SqlMgr::fetch(SqlHandle h) { short fret = 0; // not used, fetchEOF determined by getStatus() if(active == TRUE && checkHandle(h) == TRUE) return(svr->fetch(allCursors->at(h), fret)); else return(FALSE); } bool SqlMgr::close(SqlHandle& h) { if(active == FALSE || checkHandle(h) == FALSE || svr->disconnect(allCursors->at(h)) == FALSE) return(FALSE); if(outdescrs[h] != (BindDescr* )NULL) { delete outdescrs[h]; outdescrs[h] = (BindDescr* )NULL; } h = 0; return(TRUE); } bool SqlMgr::perform(const char* stmt,...) { SqlParser p; BindDescr* all; BindInfo* bi; char *sqlStmt, *stmtb; CursorInfo* ci = allCursors->at(immHandle); if(active == FALSE) return(FALSE); stmtb = strdup(stmt); sqlStmt = p.parse(stmtb); all = p.getAll(); int i = 0; va_list ap; va_start(ap, stmt); while(bi = all->next(i)) { void* aPtr = va_arg(ap, void*); bi->setBuffer(aPtr); if(bi->indpFollows()) { short* iPtr = va_arg(ap, short*); bi->setIndp(iPtr); } } va_end(ap); all->itemCount = 0; // prevents deletion of the infos delete all; if(svr->compile(ci, sqlStmt) == FALSE) { cb_error("class SqlManager: perform - compile failed"); free(stmtb); return(FALSE); } if(bind(ci, p.getInputs(), p.getOutputs()) == FALSE) { cb_error("class SqlManager: operation may cause uncorrect results"); free(stmtb); return(FALSE); } if(execute(immHandle) == FALSE) { cb_error("class SqlManager: perform - execute failed"); free(stmtb); return(FALSE); } if(outdescrs[immHandle] != (BindDescr* )NULL) { delete outdescrs[immHandle]; outdescrs[immHandle] = (BindDescr* )NULL; free(stmtb); return(fetch(immHandle)); } free(stmtb); return(TRUE); } bool SqlMgr::changeUser(const char* newUID) { if(curUID != NULL) free(curUID); curUID = strdup(newUID); if(suspend(TRUE) == TRUE) return(suspend(FALSE)); return(FALSE); } bool SqlMgr::suspend(bool flg) { CursorInfo* ci; if(flg == TRUE) { if(active == FALSE) return(TRUE); active = !(svr->disconnect(allCursors->at(immHandle)) == TRUE) ? TRUE : FALSE; return(active == FALSE ? TRUE : FALSE); } if((ci = svr->connect(curUID)) == (CursorInfo* )NULL) cb_error("class SqlManager: suspend reconnect failed"); immHandle = ci->cndx; return(active = TRUE); } bool SqlMgr::commit() { if(active == TRUE) return(svr->commit(allCursors->at(immHandle))); return(FALSE); } bool SqlMgr::rollback() { if(active == TRUE) return(svr->rollback(allCursors->at(immHandle))); return(FALSE); } short SqlMgr::status(SqlHandle h) { int stat = 0; if(active == TRUE && checkHandle(h) == TRUE) { if(svr->getStatus(allCursors->at(h), stat) == FALSE) cb_error("class SqlManager: can't get current status"); else { for(int i = 0; i < CB_MAX_ERRCOUNT; i++) { if(perrors[i] == stat) return(i); } return(CB_ERR_UNKNOWN); } } return(CB_ERR_NONE); } long SqlMgr::rowCount(SqlHandle h) { long rows = 0L; if(active == FALSE || checkHandle(h) == FALSE) return(0L); if(svr->getCurRowCount(allCursors->at(h), rows) == FALSE) cb_error("class SqlManager: can't get current row count"); return(rows); } bool SqlMgr::setErrorHandler(CbErrorHandler errfunc) { pErrorHandler = errfunc; return(TRUE); } bool SqlMgr::setMuLevel(short) { cb_error("class SqlManager - setMultiUserLevel: sorry, not implemented in this version"); return(FALSE); } bool SqlMgr::svrCmd(char*, ...) { cb_error("class SqlManager - serverCommand: sorry, not implemented in this version"); return(FALSE); } int SqlMgr::svrStatus(SqlHandle h) { int stat = 0; if(active == TRUE && checkHandle(h) == TRUE) { if(svr->getStatus(allCursors->at(h), stat) == FALSE) { cb_error("class SqlManager: can't get server status"); return(0); } } return(stat); } bool SqlMgr::checkHandle(SqlHandle& h) { if(!h) { h = immHandle; return(TRUE); } return((bool )(allCursors->at(h) != (CursorInfo* )NULL)); } bool SqlMgr::bind(CursorInfo* ci, BindDescr* bi, BindDescr* bo) { bool bindOk = TRUE; if(bi->itemCount > 0) { if(svr->bindInput(ci, bi) == FALSE) { cb_error("class SqlManager: bind input failed"); bindOk = FALSE; } else ; } delete bi; if(bo->itemCount > 0) { if(svr->bindOutput(ci, bo) == FALSE) { cb_error("class SqlManager: bind output failed"); bindOk = FALSE; } else ; outdescrs[ci->cndx] = bo; } else { delete bo; outdescrs[ci->cndx] = (BindDescr* )NULL; } return(bindOk); } // functions needed for C language interface SqlMgr* sql_init(char* uid) { return(new SqlMgr(uid)); } void sql_terminate(SqlMgr* mgr) { delete mgr; }