#include "ext/standard/info.h"
#include <sqlcli.h> /* ovrimos header
*/
-#if !defined(WIN32)
+
+#ifndef WIN32 /* stricmp is defined in sqlcli */
# define stricmp strcasecmp
#endif
+
static longreadlen = 0;
static void column_to_string(SQLS stmt, int i, char *buffer, int *len);
* As an alternative you can use the unixODBC driver available at
* http://www.ovrimos.com which supports SSL.
*
+ * This module is also non-reentrant (there should be no problem with that
+ * in php)
+ *
* Contact support@ovrimos.com for more information.
*/
-
+
+
+/* static structures introduced in order to support the old
+ * ovrimos-php-api with the new multi-threaded library --nmav.
+ */
+typedef struct {
+ SQLH connection;
+ SQLS * statements;
+ int nstatements;
+} STATE;
+
+static STATE * states = NULL;
+static int nstates = 0;
+
/* {{{ proto int ovrimos_connect(string host, string db, string user, string password)
Connect to an Ovrimos database */
PHP_FUNCTION(ovrimos_connect)
arg4->value.str.val, &conn, 0)) {
RETURN_LONG(0);
}
- RETURN_LONG((int) conn + 1);
+
+ /* add to connections - so CloseAll() will
+ * work.
+ */
+ nstates++;
+ states = erealloc( states, nstates * sizeof(STATE));
+ if (states==NULL) RETURN_FALSE;
+
+ states[nstates-1].statements = NULL;
+ states[nstates-1].nstatements = 0;
+ states[nstates-1].connection = conn;
+
+ /* return the index to the states structure
+ * (nstates is index+1)
+ */
+ RETURN_LONG( nstates);
}
/* }}} */
{
pval *arg1;
SQLH conn;
+ int i,j, index;
+ STATE* new_states;
+
if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE
|| arg1->type != IS_LONG) {
WRONG_PARAM_COUNT;
}
- conn = (SQLH) (arg1->value.lval - 1);
- (void) sqlDisConnect(conn);
+
+ index = arg1->value.lval - 1;
+ if ( index > nstates || index < 0) {
+ RETURN_FALSE;
+ }
+
+ conn = states[ index].connection;
+
+ /* free all the statements associated with
+ * the connection. (called results in php)
+ */
+
+ for (i=0;i < states[ index].nstatements;i++) {
+ if ( states[ index].statements[i]!=NULL) {
+ sqlFreeStmt( states[ index].statements[i]);
+ }
+ }
+ if (states[ index].statements!=NULL)
+ efree( states[ index].statements);
+
+ /* close the SQL_Handle
+ */
+ sqlDisconnect(conn);
+
+ if (nstates-1==0) { /* only one connection */
+ states = NULL;
+ nstates = 0;
+ return;
+ }
+
+ /* more than one connections
+ */
+ new_states = emalloc( (nstates-1)*sizeof(STATE));
+ if (new_states==NULL) RETURN_FALSE;
+
+ for (j=i=0;i<nstates;i++) {
+ if ( i!=index)
+ new_states[j++] = states[i];
+ }
+
+ efree( states);
+ states = new_states;
+ nstates--;
+
+ return;
}
/* }}} */
{
pval *arg1;
SQLH conn;
- (void) sqlDisconnectAll();
+ int i, j;
+
+ if (nstates==0) return;
+
+ for (i=0;i<nstates;i++) {
+ /* free all statements within the connection
+ */
+ for (j=0;j < states[ i].nstatements;j++) {
+ sqlFreeStmt( states[ i].statements[j]);
+ }
+ if (states[ i].statements!=NULL)
+ efree( states[ i].statements);
+
+ /* disconnect */
+ conn = states[i].connection;
+ sqlDisconnect(conn);
+ }
+ efree( states);
+ nstates = 0;
+ states = NULL;
}
/* }}} */
/* }}} */
+static int local_sqlAllocStmt(int index, SQLH conn, SQLS *stmt, short int *sindex) {
+int ret;
+
+ ret = sqlAllocStmt( conn, stmt);
+ if (!ret) return ret;
+
+ states[index].nstatements++;
+ states[index].statements = erealloc( states[index].statements,
+ states[index].nstatements*sizeof( SQLS));
+
+ if (states[index].statements==NULL) return 0;
+
+ *sindex = states[index].nstatements - 1;
+
+ states[index].statements[ *sindex] = (*stmt);
+
+ return ret;
+}
+
+static int local_sqlFreeStmt(int index, int sindex, SQLS stmt) {
+int j, i;
+SQLS* new_statements;
+
+ sqlFreeStmt( stmt);
+
+ new_statements = emalloc( states[index].nstatements-1);
+ if (new_statements==NULL) return 0;
+
+ for (i=j=0;i<states[index].nstatements;i++)
+ if (i != sindex)
+ new_statements[j++] = states[index].statements[i];
+
+ efree( states[index].statements);
+ states[index].statements = new_statements;
+ states[index].nstatements--;
+
+ return 1;
+}
+
/* {{{ proto int ovrimos_prepare(int connection_id, string query)
Prepares a statement for execution */
PHP_FUNCTION(ovrimos_prepare)
SQLH conn;
char *query;
SQLS stmt;
-
+ short int index, sindex; /* 16 bits integers */
+ int ret;
+
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
convert_to_string(arg2);
- conn = (SQLH) (arg1->value.lval - 1);
+
+ index = arg1->value.lval - 1;
+
+ conn = (SQLH) states[ index].connection;
query = arg2->value.str.val;
- if (!sqlAllocStmt(conn, &stmt)) {
+ if (!local_sqlAllocStmt(index, conn, &stmt, &sindex)) {
RETURN_FALSE;
}
if (!sqlPrepare(stmt, query)) {
- sqlFreeStmt(stmt);
+ local_sqlFreeStmt(index, sindex, stmt);
RETURN_FALSE;
}
if (!sqlGetOutputColDescr(stmt)) {
- sqlFreeStmt(stmt);
+ local_sqlFreeStmt( index, sindex, stmt);
RETURN_FALSE;
}
if (!sqlGetParamDescr(stmt)) {
- sqlFreeStmt(stmt);
+ local_sqlFreeStmt( index, sindex, stmt);
RETURN_FALSE;
}
- RETURN_LONG((int) stmt + 1);
+
+ /* return an index states[].statements[]
+ * concated with the index to states[]
+ */
+
+ /* we add 1 to the indexes since 0 is normaly
+ * treated as false--error.
+ */
+
+ ret = (((int)(index+1)) << 16) | (int)(sindex+1);
+ RETURN_LONG( ret);
}
/* }}} */
SQLS stmt;
int numArgs;
int icol, colnb;
- numArgs = ARG_COUNT(ht);
+ short int index, sindex;
+ numArgs = ARG_COUNT(ht);
+
if (getParameters(ht, numArgs, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = states[ index].statements[ sindex];
colnb = sqlGetParamNb(stmt);
if (colnb != 0) {
char cname[126];
pval *arg1;
SQLS stmt;
-
+ int index, sindex;
+
if (getParameters(ht, 1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
+
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = states[ index].statements[ sindex];
+
if (!sqlGetCursorName(stmt, cname)) {
RETURN_FALSE;
}
/* }}} */
+/* This function returns a result id. The result ID contains
+ * the connection's ID and the statement's ID (concat).
+ * Every result is mapped to a statement.
+ */
+
/* {{{ proto int ovrimos_exec(int connection_id, string query)
Prepare and execute an SQL statement */
PHP_FUNCTION(ovrimos_exec)
SQLS stmt;
int numArgs;
char *query;
+ short int sindex, index;
+ int ret;
+
numArgs = ARG_COUNT(ht);
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
convert_to_long(arg1);
convert_to_string(arg2);
- conn = (SQLH) (arg1->value.lval - 1);
+
+ index = arg1->value.lval - 1;
+ conn = (SQLH) (states[ index].connection);
query = arg2->value.str.val;
- if (!sqlAllocStmt(conn, &stmt)) {
+ if (!local_sqlAllocStmt(index, conn, &stmt, &sindex)) {
RETURN_FALSE;
}
+
if (!sqlExecDirect(stmt, query)) {
- sqlFreeStmt(stmt);
+ local_sqlFreeStmt( index, sindex, stmt);
RETURN_FALSE;
}
if (!sqlGetOutputColDescr(stmt)) {
- sqlFreeStmt(stmt);
+ local_sqlFreeStmt( index, sindex, stmt);
RETURN_FALSE;
}
if (!sqlGetParamDescr(stmt)) {
- sqlFreeStmt(stmt);
+ local_sqlFreeStmt( index, sindex, stmt);
RETURN_FALSE;
}
- RETURN_LONG((int) stmt + 1);
+
+ ret = (((int)(index+1)) << 16) | (int)(sindex+1);
+ RETURN_LONG( ret);
}
/* }}} */
sint32 rownum = 0;
pval *arg_id, *arg_how = 0, *arg_row = 0, *arr, *tmp;
SQLS stmt;
+ int index, sindex;
int icol, colnb;
bool ret;
numArgs = ARG_COUNT(ht);
}
convert_to_long(arg_id);
- stmt = (SQLS) (arg_id->value.lval - 1);
+ sindex = (arg_id->value.lval & 0x0000ffff);
+ index = (arg_id->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = states[ index].statements[ sindex];
if (arg_how != 0) {
if (arg_how->type != IS_STRING) {
if (!ret) {
RETURN_FALSE;
}
+
colnb = sqlGetOutputColNb(stmt);
for (icol = 0; icol < colnb; icol++) {
int len;
tmp->value.str.len = 0;
/* Produce column value in 'tmp' ... */
+
column_to_string(stmt, icol, buffer, &len);
tmp->value.str.len = len;
tmp->value.str.val = estrndup(buffer, len);
zend_hash_index_update(arr->value.ht, icol, &tmp,
sizeof(pval *), NULL);
}
+
RETURN_TRUE;
}
sint32 rownum = 0;
pval *arg_id, *arg_how = 0, *arg_row = 0;
SQLS stmt;
+ int index, sindex;
bool ret;
numArgs = ARG_COUNT(ht);
}
convert_to_long(arg_id);
- stmt = (SQLS) (arg_id->value.lval - 1);
+
+ sindex = (arg_id->value.lval & 0x0000ffff);
+ index = (arg_id->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
+
if (arg_how != 0) {
if (arg_how->type != IS_STRING) {
pval *arg_id, *arg_field;
int icol, colnb;
SQLS stmt;
- int len;
+ int len, index, sindex;
char buffer[1024];
if (numArgs != 2
&arg_field) == FAILURE) WRONG_PARAM_COUNT;
convert_to_long(arg_id);
- stmt = (SQLS) (arg_id->value.lval - 1);
+ sindex = (arg_id->value.lval & 0x0000ffff);
+ index = (arg_id->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
colnb = sqlGetOutputColNb(stmt);
int numArgs;
SQLS stmt;
int icol, colnb;
+ int index, sindex;
char buffer[1024];
int len;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
colnb = sqlGetOutputColNb(stmt);
{
pval *arg1;
SQLS stmt;
-
+ int index, sindex;
+
if (getParameters(ht, 1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
- sqlCloseCursor(stmt);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
+
+ sqlCloseCursor( stmt);
+ local_sqlFreeStmt( index, sindex, stmt);
RETURN_TRUE;
}
uint32 rows;
pval *arg1;
SQLS stmt;
+ int index, sindex;
if (getParameters(ht, 1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
+
sqlGetRowCount(stmt, &rows);
RETURN_LONG(rows);
{
pval *arg1;
SQLS stmt;
+ int index, sindex;
if (getParameters(ht, 1, &arg1) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
RETURN_LONG(sqlGetOutputColNb(stmt));
}
{
pval *arg1, *arg2;
SQLS stmt;
- int field;
+ int field, index, sindex;
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
convert_to_long(arg1);
convert_to_long(arg2);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
+
if (arg2->value.lval < 1) {
php_error(E_WARNING,
{
pval *arg1, *arg2;
SQLS stmt;
- int field;
+ int field, index, sindex;
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
convert_to_long(arg1);
convert_to_long(arg2);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
if (arg2->value.lval < 1) {
php_error(E_WARNING,
{
pval *arg1, *arg2;
SQLS stmt;
- int field;
+ int field, index, sindex;
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
WRONG_PARAM_COUNT;
convert_to_long(arg1);
convert_to_long(arg2);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
if (arg2->value.lval < 1) {
php_error(E_WARNING,
{
pval *arg1, *arg2;
SQLS stmt;
- int i, n;
+ int i, n, index, sindex;
if (getParameters(ht, 2, &arg1, &arg2) == FAILURE
|| arg2->type != IS_STRING) {
WRONG_PARAM_COUNT;
}
convert_to_long(arg1);
- stmt = (SQLS) (arg1->value.lval - 1);
+ sindex = (arg1->value.lval & 0x0000ffff);
+ index = (arg1->value.lval & 0xffff0000) >> 16;
+ sindex--; index--;
+
+ stmt = (SQLS) states[ index].statements[ sindex];
+
n = sqlGetOutputColNb(stmt);
for (i = 0; i < n; i++) {
if (!strcmp
PHP_FUNCTION(ovrimos_commit)
{
pval *arg1;
- SQLH conn;
+ SQLS stmt;
+ int index, i;
+
if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE
|| arg1->type != IS_LONG) {
WRONG_PARAM_COUNT;
}
-
+
convert_to_long( arg1);
- conn = (SQLH) (arg1->value.lval - 1);
- /* use of sqlcli 1.1.7 and later versions,
- * is recommended due to a bug which prevented proper
- * commit.
- */
- if (!sqlTransactCommit(conn)) {
- RETURN_FALSE;
+ index = (arg1->value.lval -1);
+
+ for (i=0;i<states[ index].nstatements;i++) {
+ stmt = states[ index].statements[ i];
+ if (stmt==NULL) {
+ continue;
+ }
+ if (!sqlCommit(stmt)) {
+ RETURN_FALSE;
+ }
}
RETURN_TRUE;
}
PHP_FUNCTION(ovrimos_rollback)
{
pval *arg1;
- SQLH conn;
+ SQLS stmt;
+ int index, i;
+
if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE
|| arg1->type != IS_LONG) {
WRONG_PARAM_COUNT;
}
- conn = (SQLH) (arg1->value.lval - 1);
- if (!sqlTransactRollback(conn)) {
- RETURN_FALSE;
+
+ convert_to_long( arg1);
+ index = (arg1->value.lval -1);
+
+ for (i=0;i<states[ index].nstatements;i++) {
+ stmt = (SQLS) states[ index].statements[ i];
+ if (stmt==NULL) continue;
+
+ if (!sqlRollback(stmt)) {
+ RETURN_FALSE;
+ }
}
RETURN_TRUE;
}