📄 sybaseconnection.c
字号:
// Copyright (c) 1999-2001 David Muse// See the file COPYING for more information#include <sybaseconnection.h>#include <config.h>#include <datatypes.h>#include <rudiments/stringbuffer.h>#include <rudiments/charstring.h>#include <rudiments/rawbuffer.h>#include <stdio.h>#include <stdlib.h>stringbuffer *sybaseconnection::errorstring;bool sybaseconnection::deadconnection;sybaseconnection::sybaseconnection() : sqlrconnection_svr() { errorstring=NULL; dbused=false; dbversion=NULL;}sybaseconnection::~sybaseconnection() { delete errorstring; delete[] dbversion;}uint16_t sybaseconnection::getNumberOfConnectStringVars() { return NUM_CONNECT_STRING_VARS;}void sybaseconnection::handleConnectString() { sybase=connectStringValue("sybase"); lang=connectStringValue("lang"); setUser(connectStringValue("user")); setPassword(connectStringValue("password")); server=connectStringValue("server"); db=connectStringValue("db"); charset=connectStringValue("charset"); language=connectStringValue("language"); hostname=connectStringValue("hostname"); packetsize=connectStringValue("packetsize");}bool sybaseconnection::logIn(bool printerrors) { // set sybase if (sybase && sybase[0] && !environment::setValue("SYBASE",sybase)) { logInError("Failed to set SYBASE environment variable.",1); return false; } // set lang if (lang && lang[0] && !environment::setValue("LANG",lang)) { logInError("Failed to set LANG environment variable.",1); return false; } // set server if (server && server[0] && !environment::setValue("DSQUERY",server)) { logInError("Failed to set DSQUERY environment variable.",2); return false; } // allocate a context context=(CS_CONTEXT *)NULL; if (cs_ctx_alloc(CS_VERSION_100,&context)!=CS_SUCCEED) { logInError("failed to allocate a context structure",2); return false; } // init the context if (ct_init(context,CS_VERSION_100)!=CS_SUCCEED) { logInError("failed to initialize a context structure",3); return false; } // configure the error handling callbacks if (cs_config(context,CS_SET,CS_MESSAGE_CB, (CS_VOID *)sybaseconnection::csMessageCallback,CS_UNUSED, (CS_INT *)NULL) !=CS_SUCCEED) { logInError("failed to set a cslib error message callback",4); return false; } if (ct_callback(context,NULL,CS_SET,CS_CLIENTMSG_CB, (CS_VOID *)sybaseconnection::clientMessageCallback) !=CS_SUCCEED) { logInError("failed to set a client error message callback",4); return false; } if (ct_callback(context,NULL,CS_SET,CS_SERVERMSG_CB, (CS_VOID *)sybaseconnection::serverMessageCallback) !=CS_SUCCEED) { logInError("failed to set a server error message callback",4); return false; } // allocate a connection if (ct_con_alloc(context,&dbconn)!=CS_SUCCEED) { logInError("failed to allocate a connection structure",4); return false; } // set the user to use const char *user=getUser(); if (ct_con_props(dbconn,CS_SET,CS_USERNAME, (CS_VOID *)((user && user[0])?user:""), CS_NULLTERM,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the user",5); return false; } // set the password to use const char *password=getPassword(); if (ct_con_props(dbconn,CS_SET,CS_PASSWORD, (CS_VOID *)((password && password[0])?password:""), CS_NULLTERM,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the password",5); return false; } // set application name if (ct_con_props(dbconn,CS_SET,CS_APPNAME,(CS_VOID *)"sqlrelay", CS_NULLTERM,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the application name",5); return false; } // set hostname if (hostname && hostname[0] && ct_con_props(dbconn,CS_SET,CS_HOSTNAME,(CS_VOID *)hostname, CS_NULLTERM,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the hostname",5); return false; } // set packetsize uint16_t ps=charstring::toInteger(packetsize); if (packetsize && packetsize[0] && ct_con_props(dbconn,CS_SET,CS_PACKETSIZE, (CS_VOID *)&ps,sizeof(ps), (CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the packetsize",5); return false; } // FIXME: support this // set encryption /*if (encryption && charstring::toInteger(encryption)==1) { // FIXME: need to set CS_SEC_CHALLENGE/CS_SEC_NEGOTIATE // parameters too CS_INT enc=CS_TRUE; if (ct_con_props(dbconn,CS_SET,CS_SEC_ENCRYPTION, (CS_VOID *)&enc, CS_UNUSED,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the encryption",5); return false; } }*/ // init locale locale=NULL; if (cs_loc_alloc(context,&locale)!=CS_SUCCEED) { logInError("failed to allocate a locale structure",5); return false; } if (cs_locale(context,CS_SET,locale,CS_LC_ALL,(CS_CHAR *)NULL, CS_UNUSED,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to initialize a locale structure",6); return false; } // set language if (language && language[0] && cs_locale(context,CS_SET,locale,CS_SYB_LANG, (CS_CHAR *)language,CS_NULLTERM,(CS_INT *)NULL)!= CS_SUCCEED) { logInError("failed to set the language",6); return false; } // set charset if (charset && charset[0] && cs_locale(context,CS_SET,locale,CS_SYB_CHARSET, (CS_CHAR *)charset,CS_NULLTERM,(CS_INT *)NULL)!= CS_SUCCEED) { logInError("failed to set the charset",6); return false; } // set locale if (ct_con_props(dbconn,CS_SET,CS_LOC_PROP,(CS_VOID *)locale, CS_UNUSED,(CS_INT *)NULL)!=CS_SUCCEED) { logInError("failed to set the locale",6); return false; } // connect to the database if (ct_connect(dbconn,(CS_CHAR *)NULL,(CS_INT)0)!=CS_SUCCEED) { logInError("failed to connect to the database",6); return false; } return true;}void sybaseconnection::logInError(const char *error, uint16_t stage) { fprintf(stderr,"%s\n",error); if (errorstring) { fprintf(stderr,"%s\n",errorstring->getString()); } if (stage>5) { cs_loc_drop(context,locale); } if (stage>4) { ct_con_drop(dbconn); } if (stage>3) { ct_exit(context,CS_UNUSED); } if (stage>2) { cs_ctx_drop(context); }}sqlrcursor_svr *sybaseconnection::initCursor() { return (sqlrcursor_svr *)new sybasecursor((sqlrconnection_svr *)this);}void sybaseconnection::deleteCursor(sqlrcursor_svr *curs) { delete (sybasecursor *)curs;}void sybaseconnection::logOut() { cs_loc_drop(context,locale); ct_close(dbconn,CS_UNUSED); ct_con_drop(dbconn); ct_exit(context,CS_UNUSED); cs_ctx_drop(context);}const char *sybaseconnection::identify() { return "sybase";}const char *sybaseconnection::dbVersion() { return dbversion;}const char *sybaseconnection::bindFormat() { return "@*";}char sybaseconnection::bindVariablePrefix() { return '@';}sybasecursor::sybasecursor(sqlrconnection_svr *conn) : sqlrcursor_svr(conn) { prepared=false; sybaseconn=(sybaseconnection *)conn; cmd=NULL; languagecmd=NULL; cursorcmd=NULL; cursorname=NULL; // replace the regular expression used to detect creation of a // temporary table createtemp.compile("(create|CREATE)[ \\t\\r\\n]+(table|TABLE)[ \\t\\r\\n]+#"); createtemp.study(); cursorquery.compile("^(select|SELECT)[ \\t\\r\\n]+"); cursorquery.study(); rpcquery.compile("^(execute|exec|EXECUTE|EXEC)[ \\t\\r\\n]+"); rpcquery.study();}sybasecursor::~sybasecursor() { closeCursor(); delete[] cursorname;}bool sybasecursor::openCursor(uint16_t id) { clean=true; cursorname=charstring::parseNumber(id); if (ct_cmd_alloc(sybaseconn->dbconn,&languagecmd)!=CS_SUCCEED) { return false; } if (ct_cmd_alloc(sybaseconn->dbconn,&cursorcmd)!=CS_SUCCEED) { return false; } cmd=NULL; // switch to the correct database, get dbversion // (only do this once per connection) bool retval=true; if (sybaseconn->db && sybaseconn->db[0] && !sybaseconn->dbused) { int32_t len=charstring::length(sybaseconn->db)+4; char query[len+1]; snprintf(query,len+1,"use %s",sybaseconn->db); if (!(prepareQuery(query,len) && executeQuery(query,len,true))) { bool live; fprintf(stderr,"%s\n",errorMessage(&live)); retval=false; } else { sybaseconn->dbused=true; } cleanUpData(true,true); } if (!sybaseconn->dbversion) { char *query="sp_version installmaster"; int32_t len=charstring::length(query); if (!(prepareQuery(query,len) && executeQuery(query,len,true) && fetchRow())) { sybaseconn->dbversion= charstring::duplicate("unknown"); } else { const char *space= charstring::findFirst(data[1][0],' '); sybaseconn->dbversion= charstring::duplicate(data[1][0], space-data[1][0]); } cleanUpData(true,true); } return (retval && sqlrcursor_svr::openCursor(id));}bool sybasecursor::closeCursor() { bool retval=true; if (languagecmd) { retval=(ct_cmd_drop(languagecmd)==CS_SUCCEED); languagecmd=NULL; } if (cursorcmd) { retval=(retval && (ct_cmd_drop(cursorcmd)==CS_SUCCEED)); cursorcmd=NULL; } cmd=NULL; return retval;}bool sybasecursor::prepareQuery(const char *query, uint32_t length) { clean=true; this->query=(char *)query; this->length=length; paramindex=0; outbindindex=0; isrpcquery=false; if (cursorquery.match(query)) { // initiate a cursor command cmd=cursorcmd; if (ct_cursor(cursorcmd,CS_CURSOR_DECLARE, (CS_CHAR *)cursorname,CS_NULLTERM, (CS_CHAR *)query,length, CS_READ_ONLY)!=CS_SUCCEED) { return false; } } else if (rpcquery.match(query)) { // initiate an rpc command isrpcquery=true; cmd=languagecmd; if (ct_command(languagecmd,CS_RPC_CMD, (CS_CHAR *)rpcquery.getSubstringEnd(0), length-rpcquery.getSubstringEndOffset(0), CS_UNUSED)!=CS_SUCCEED) { return false; } } else { // initiate a language command cmd=languagecmd; if (ct_command(languagecmd,CS_LANG_CMD, (CS_CHAR *)query,length, CS_UNUSED)!=CS_SUCCEED) { return false; } } clean=false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -