php-src/ext/fbsql/php_fbsql.c

3161 lines
82 KiB
C
Raw Normal View History

/*
+----------------------------------------------------------------------+
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2001 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http:/*www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Frank M. Kromann frank@frontbase.com> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
/* TODO:
*
* ? Safe mode implementation
*/
/* SB's list:
- BLOBs
- API for a more natural FB connect semantic
- Connect & set session
- Autoreconnect when disconnected
- Comments and cleanup
- Documentation
- Format database error messages as HTML.
BUGS
- Select db with no arguments
- Query with everything defaulted
*/
#include "php.h"
#include "php_globals.h"
#include "php_globals.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#if WIN32|WINNT
#include <winsock.h>
#else
#include <php_config.h>
#include <build-defs.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <netdb.h>
#include <netinet/in.h>
#endif
#include "php_ini.h"
#define HAVE_FBSQL 1
#if HAVE_FBSQL
#include "php_fbsql.h"
#include <signal.h>
static int le_result, le_link, le_plink, le_dba;
struct PHPFBDatabase;
typedef struct PHPFBDatabase PHPFBDatabase;
struct PHPFBResult;
typedef struct PHPFBResult PHPFBResult;
struct PHPFBLink;
typedef struct PHPFBLink PHPFBLink;
/* The PHPFBLink structure represents a fbsql link. The lion is used for
a connection to a machine, it may be persistant and is reference counted.
The reason for refcounting is mostly to avoid to think, it work independent of
any wierd and unforseen allocation deallocation order.
The PHPFBDatabse structure implements to actual connection to a FrontBase server
ot may be persistant is the link it is connected to is persistant, and refcounted
for the same reasons as above.
The PHPFBResult structure implements a result from the FrontBase server, and does all
required buffereing from of results.
In the PHP code the 3 above a data structures are referenced by means of integers in the
range from 1 to som configurable maximum. You can put a limit to the number of links, databases
and results. The integer identifications is implemented by insertion in the list, which is passed
as an argument to all the functions, please note the list is polymorph.
Database objects and link objects are all reused, base on the host name user name, host name database name
user name. So connecting twice to the same database as the same user will return the same database id.
We use the same coding for that as fbsql does, explioiting the underlying implementation of the lists.
Persistant objects are put in the persistent list as well, but only by name, if you connect to a persistant object
and it is not in the list it is simply added and get a new index, and refcounted. Tricky, tricky ...
*/
/* Some functions which should be exported from FBCAccess */
void* fbaObjectAtIndex();
void fbcInitialize();
void fbaRelease();
unsigned int fbaCount();
struct PHPFBDatabase
{
unsigned int retainCount; /* The refcount */
unsigned int index; /* The index in the list */
PHPFBLink* link; /* A pointer to the corresponding link object, may be NULL if no link were used */
char* databaseName; /* The name of the database */
char* databasePassword; /* The database password */
FBCDatabaseConnection* connection; /* The connection to the database */
unsigned int errorNo; /* The latest error on the connection, 0 is ok. */
char* errorText; /* The error text */
unsigned int resultCount; /* Number of active result for this database */
unsigned int rowIndex; /* The row index of the latest row inserted into the database */
PHPFBResult** results; /* Pointer to the active results */
};
struct PHPFBResult
{
unsigned int retainCount; /* The refcount */
unsigned int index; /* The index into the list */
PHPFBLink* link; /* The link for the result, may be NULL if no link */
PHPFBDatabase* database; /* The database for the result, may be NULL of no database is related to the result */
FBCDatabaseConnection* connection; /* The database connection, just a convinience */
char* fetchHandle; /* The fetch handle, the id used by the server. */
FBCMetaData* metaData; /* The metadata describing the result */
FBCMetaData* ResultmetaData; /* The metadata describing the result */
FBCRowHandler* rowHandler; /* The row handler, the Frontbase structure used for accessing rows in the result */
unsigned int batchSize; /* The number of row to fetch when expanding the number of rows in the row handler */
int rowCount; /* The number of rows in the results set. The number of row is not in */
/* general known when the select is done, one typically needs to fetch all the row
to figure out how many row you got. When the rowCount is unknown the value is
0x7ffffffff */
int columnCount; /* Number of columns in the row set. */
int rowIndex; /* The current row index. */
int columnIndex; /* The current column index */
void** row; /* The last row accessed */
FBArray* array; /* The link may return a result set, the database list, we implement that by the */
/* FBArray, just a list of strings. */
FBCPList* list; /* The same special kind result just for property list from extract, schema info. */
unsigned int selectResults; /* number of results in select */
unsigned int currentResult; /* current result number */
};
struct PHPFBLink
{
unsigned int retainCount; /* The refcount */
unsigned int index; /* The index in the list */
int persistant; /* persistant ? */
char* hostName; /* Host name */
char* userName; /* User name */
char* userPassword; /* User password */
FBCExecHandler* execHandler; /* The exechandler, can be used for database operations */
unsigned int affectedRows;
long autoCommit; /* Enable or disable autoCommit */
PHPFBDatabase* currentDatabase; /* The latest referenced database on this link */
unsigned int databaseCount; /* The number of database connect to the link */
PHPFBDatabase** databases; /* and the pointers */
unsigned int resultCount; /* The number of link results */
PHPFBResult** results; /* and the pointers. Only used for list_dbs */
};
#define FBSQL_ASSOC 1<<0
#define FBSQL_NUM 1<<1
#define FBSQL_BOTH (FBSQL_ASSOC|FBSQL_NUM)
function_entry fbsql_functions[] = {
PHP_FE(fbsql_connect, NULL)
PHP_FE(fbsql_pconnect, NULL)
PHP_FE(fbsql_close, NULL)
PHP_FE(fbsql_select_db, NULL)
PHP_FE(fbsql_create_db, NULL)
PHP_FE(fbsql_drop_db, NULL)
PHP_FE(fbsql_start_db, NULL)
PHP_FE(fbsql_stop_db, NULL)
PHP_FE(fbsql_query, NULL)
PHP_FE(fbsql_db_query, NULL)
PHP_FE(fbsql_list_dbs, NULL)
PHP_FE(fbsql_list_tables, NULL)
PHP_FE(fbsql_list_fields, NULL)
PHP_FE(fbsql_error, NULL)
PHP_FE(fbsql_errno, NULL)
PHP_FE(fbsql_affected_rows, NULL)
PHP_FE(fbsql_insert_id, NULL)
PHP_FE(fbsql_result, NULL)
PHP_FE(fbsql_next_result, NULL)
PHP_FE(fbsql_num_rows, NULL)
PHP_FE(fbsql_num_fields, NULL)
PHP_FE(fbsql_fetch_row, NULL)
PHP_FE(fbsql_fetch_array, NULL)
PHP_FE(fbsql_fetch_object, NULL)
PHP_FE(fbsql_data_seek, NULL)
PHP_FE(fbsql_fetch_lengths, NULL)
PHP_FE(fbsql_fetch_field, NULL)
PHP_FE(fbsql_field_seek, NULL)
PHP_FE(fbsql_free_result, NULL)
PHP_FE(fbsql_field_name, NULL)
PHP_FE(fbsql_field_table, NULL)
PHP_FE(fbsql_field_len, NULL)
PHP_FE(fbsql_field_type, NULL)
PHP_FE(fbsql_field_flags, NULL)
/* Fontbase additions: */
PHP_FE(fbsql_autocommit, NULL)
PHP_FE(fbsql_commit, NULL)
PHP_FE(fbsql_rollback, NULL)
PHP_FE(fbsql_hostname, NULL)
PHP_FE(fbsql_database, NULL)
PHP_FE(fbsql_database_password, NULL)
PHP_FE(fbsql_username, NULL)
PHP_FE(fbsql_password, NULL)
PHP_FE(fbsql_warnings, NULL)
/* Aliases: */
PHP_FALIAS(fbsql, fbsql_db_query, NULL)
{NULL, NULL, NULL}
};
zend_module_entry fbsql_module_entry = {
"fbsql",
fbsql_functions,
PHP_MINIT(fbsql),
PHP_MSHUTDOWN(fbsql),
PHP_RINIT(fbsql),
2001-04-04 20:10:14 +00:00
PHP_RSHUTDOWN(fbsql),
PHP_MINFO(fbsql),
STANDARD_MODULE_PROPERTIES
};
ZEND_DECLARE_MODULE_GLOBALS(fbsql)
#ifdef COMPILE_DL_FBSQL
ZEND_GET_MODULE(fbsql)
#endif
2001-03-21 19:56:33 +00:00
void phpfbReleaseResult (PHPFBResult* result);
void phpfbReleaseDatabase (PHPFBDatabase* database);
void phpfbReleaseLink (PHPFBLink* link);
2001-03-21 19:56:33 +00:00
PHPFBResult* phpfbRetainResult (PHPFBResult* result)
{
if (result) result->retainCount++;
return result;
}
2001-03-21 19:56:33 +00:00
void phpfbReleaseResult (PHPFBResult* result)
{
unsigned int i;
FBSQLLS_FETCH();
if (result)
2001-03-21 19:56:33 +00:00
{
result->retainCount--;
2001-03-21 19:56:33 +00:00
if (result->retainCount == 0)
{
if (result->fetchHandle) fbcdcCancelFetch(result->connection,result->fetchHandle);
if (result->rowHandler) fbcrhRelease(result->rowHandler);
if (result->ResultmetaData) fbcmdRelease(result->ResultmetaData);
/* if (result->metaData) fbcmdRelease(result->metaData); */
2001-03-21 19:56:33 +00:00
if (result->list) fbcplRelease(result->list);
if (result->array) fbaRelease(result->array);
if (result->database)
{
for (i=0; i < result->database->resultCount; i++)
{
if (result->database->results[i] == result)
{
result->database->results[i] = NULL;
break;
}
}
phpfbReleaseDatabase(result->database);
}
if (result->link)
{
for (i=0; i < result->link->resultCount; i++)
{
if (result->link->results[i] == result)
{
result->link->results[i] = NULL;
break;
}
}
phpfbReleaseLink(result->link);
}
result->link = 0;
result->database = 0;
result->connection = NULL;
result->fetchHandle = NULL;
result->metaData = NULL;
result->rowHandler = NULL;
result->batchSize = 0;
result->rowCount = -1;
result->rowIndex = 0;
result->columnIndex = 0;
result->row = NULL;
result->array = NULL;
result->list = NULL;
free(result);
}
}
}
2001-03-21 19:56:33 +00:00
PHPFBDatabase* phpfbRetainDatabase (PHPFBDatabase* database)
{
if (database) database->retainCount++;
return database;
}
void phpfbReleaseDatabase (PHPFBDatabase* database)
{
if (database)
{
database->retainCount--;
if (database->retainCount == 0)
{
unsigned int i;
if (database->link)
{
for (i=0; i < database->link->databaseCount; i++)
{
if (database->link->databases[i] == database)
{
database->link->databases[i] = NULL;
break;
}
}
phpfbReleaseLink(database->link);
}
fbcdcClose(database->connection);
fbcdcRelease(database->connection);
free(database->databaseName);
free(database->databasePassword);
free(database->results);
free(database);
}
}
}
2001-03-21 19:56:33 +00:00
PHPFBLink* phpfbRetainLink (PHPFBLink* link)
{
2001-03-21 19:56:33 +00:00
if (link) link->retainCount++;
return link;
}
2001-03-21 19:56:33 +00:00
void phpfbReleaseLink (PHPFBLink* link)
{
2001-04-04 20:10:14 +00:00
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if (link)
{
link->retainCount--;
if (link->retainCount == 0)
{
2001-04-04 20:10:14 +00:00
if (link->index == FB_SQL_G(linkIndex)) FB_SQL_G(linkIndex)--;
2001-03-21 19:56:33 +00:00
free(link->hostName);
free(link->userName);
free(link->userPassword);
if (link->results) free(link->results);
if (link->databases) free(link->databases);
free(link);
}
}
}
PHPFBResult* phpfbQuery (INTERNAL_FUNCTION_PARAMETERS, char* sql, PHPFBDatabase* database);
PHP_INI_BEGIN()
2001-03-21 19:56:33 +00:00
STD_PHP_INI_BOOLEAN ("fbsql.allow_persistant", "1", PHP_INI_SYSTEM, OnUpdateInt, allowPersistent, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_BOOLEAN ("fbsql.generate_warnings", "0", PHP_INI_SYSTEM, OnUpdateInt, generateWarnings, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_BOOLEAN ("fbsql.autocommit", "1", PHP_INI_SYSTEM, OnUpdateInt, autoCommit, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_ENTRY_EX ("fbsql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateInt, maxPersistant, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.max_links", "128", PHP_INI_SYSTEM, OnUpdateInt, maxLinks, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.max_connections", "128", PHP_INI_SYSTEM, OnUpdateInt, maxConnections, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.max_results", "128", PHP_INI_SYSTEM, OnUpdateInt, maxResults, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.mbatchSize", "1000", PHP_INI_SYSTEM, OnUpdateInt, batchSize, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY ("fbsql.default_host", NULL, PHP_INI_SYSTEM, OnUpdateString, hostName, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_ENTRY ("fbsql.default_user", "_SYSTEM", PHP_INI_SYSTEM, OnUpdateString, userName, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_ENTRY ("fbsql.default_password", "", PHP_INI_SYSTEM, OnUpdateString, userPassword, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_ENTRY ("fbsql.default_database", "", PHP_INI_SYSTEM, OnUpdateString, databaseName, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_ENTRY ("fbsql.default_database_password", "", PHP_INI_SYSTEM, OnUpdateString, databasePassword, zend_fbsql_globals, fbsql_globals)
PHP_INI_END()
static void php_fbsql_init_globals(zend_fbsql_globals *fbsql_globals)
{
fbsql_globals->persistantCount = 0;
if (fbsql_globals->hostName==NULL)
{
char name[256];
gethostname(name,sizeof(name));
name[sizeof(name)-1] = 0;
fbsql_globals->hostName = strdup(name);
}
fbsql_globals->persistantCount = 0;
fbsql_globals->linkCount = 0;
fbsql_globals->resultCount = 0;
fbsql_globals->linkIndex = 0;
fbsql_globals->databaseIndex = 0;
fbsql_globals->resultIndex = 0;
}
PHP_MINIT_FUNCTION(fbsql)
{
ZEND_INIT_MODULE_GLOBALS(fbsql, php_fbsql_init_globals, NULL);
REGISTER_INI_ENTRIES();
fbcInitialize();
le_result = register_list_destructors(phpfbReleaseResult,NULL);
le_link = register_list_destructors(phpfbReleaseLink,NULL);
le_dba = register_list_destructors(phpfbReleaseDatabase,NULL);
REGISTER_LONG_CONSTANT("FBSQL_ASSOC", FBSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_NUM", FBSQL_NUM, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_BOTH", FBSQL_BOTH, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(fbsql)
{
2001-03-21 19:56:33 +00:00
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
PHP_RINIT_FUNCTION(fbsql)
{
return SUCCESS;
}
2001-04-04 20:10:14 +00:00
PHP_RSHUTDOWN_FUNCTION(fbsql)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(fbsql)
{
char buf[32];
FBSQLLS_FETCH();
php_info_print_table_start();
php_info_print_table_header(2, "FrontBase support", "enabled");
2001-03-21 19:56:33 +00:00
php_info_print_table_row(2, "Client API version", "2.20");
if (FB_SQL_G(allowPersistent))
{
sprintf(buf, "%ld", FB_SQL_G(persistantCount));
php_info_print_table_row(2, "Active Persistant Links", buf);
}
sprintf(buf, "%ld", FB_SQL_G(linkCount));
php_info_print_table_row(2, "Active Links", buf);
sprintf(buf, "%ld", FB_SQL_G(resultCount));
php_info_print_table_row(2, "Active Result Sets", buf);
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
2001-03-21 19:56:33 +00:00
PHPFBLink* phpfbConnect(INTERNAL_FUNCTION_PARAMETERS, char *hostName, char *userName, char *userPassword, int persistant)
{
/* Ref count databases and links!!
Search for the database/link in the hash plist and in the hashed list
If a link was non persistant then an is opened peristant just insert it
in the persistant list
Insert the persistant in the list and in the hash p list
Insert the non persistant in the */
PHPFBLink* result;
list_entry *lep;
int type;
char name[1024];
FBSQLLS_FETCH();
if (hostName == NULL) hostName = FB_SQL_G(hostName);
if (userName == NULL) userName = FB_SQL_G(userName);
if (userPassword == NULL) userPassword = FB_SQL_G(userPassword);
sprintf(name,"fbsql_%s_%s",hostName,userName);
if(zend_hash_find(&EG(persistent_list), name, strlen(name), (void **) &lep) == SUCCESS)
{
PHPFBLink* lnk;
result = lep->ptr;
lnk = zend_list_find(result->index,&type);
if (lnk != result) result->index = zend_list_insert(result, le_link);
}
2001-03-21 19:56:33 +00:00
else if(zend_hash_find(&EG(regular_list),name,strlen(name),(void **)&lep) == SUCCESS)
{
result = lep->ptr;
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkCount) == FB_SQL_G(maxLinks))
{
php_error(E_WARNING,"FrontBase link limit %d exceeded ", FB_SQL_G(maxLinks));
return NULL;
}
else
{
FBCExecHandler* execHandler = fbcehHandlerForHost(hostName,128);
list_entry le;
if (execHandler == NULL)
{
php_error(E_WARNING,"Cannot connect to host '%s'",hostName);
php_error(E_WARNING,fbcehClassErrorMessage());
return NULL;
}
result = malloc(sizeof(PHPFBLink));
result->retainCount = 1;
result->persistant = persistant;
result->hostName = strdup(hostName);
result->userName = strdup(userName);
result->userPassword = strdup(userPassword);
result->execHandler = execHandler;
result->affectedRows = 0;
result->autoCommit = FB_SQL_G(autoCommit);
result->currentDatabase = NULL;
result->databaseCount = 0;
result->databases = NULL;
result->resultCount = 0;
result->results = NULL;
le.ptr = result;
le.type = le_link;
if (zend_hash_update(persistant?&EG(persistent_list):&EG(regular_list), name, strlen(name), &le, sizeof(le), NULL)==FAILURE)
{
phpfbReleaseLink(result);
return NULL;
}
result->index = zend_list_insert (phpfbRetainLink(result), le_link);
FB_SQL_G(linkCount)++;
2001-03-21 19:56:33 +00:00
/* printf(" new %x %d \n",result,result->index); */
/* printf("Ny connection %x %x\n",result,result->execHandler); */
}
return result;
}
2001-03-23 00:58:59 +00:00
int phpfbFetchRow(PHPFBResult* result, int row)
{
if (result->rowHandler == NULL)
{
2001-03-23 00:58:59 +00:00
void *rawData = fbcdcFetch(result->connection,result->batchSize,result->fetchHandle);
if (rawData == NULL)
result->rowCount = 0;
else
result->rowHandler = fbcrhInitWith(rawData, result->metaData);
}
for (;;)
{
void *rawData;
2001-03-21 19:56:33 +00:00
if (row >= result->rowCount) return 0;
if (fbcrhRowCount(result->rowHandler) > (unsigned int)row) return 1;
rawData = fbcdcFetch(result->connection,result->batchSize,result->fetchHandle);
if (!fbcrhAddBatch(result->rowHandler,rawData)) result->rowCount = fbcrhRowCount(result->rowHandler);
}
return 0;
}
void phpfbDoConnect(INTERNAL_FUNCTION_PARAMETERS,int persistant)
{
PHPFBLink* result;
2001-03-21 19:56:33 +00:00
char *hostName = NULL;
char *userName = NULL;
char *userPassword = NULL;
int argc = ARG_COUNT(ht);
zval **argv[3];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 3)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
hostName = (*argv[0])->value.str.val;
}
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[1]);
userName = (*argv[1])->value.str.val;
}
2001-03-21 19:56:33 +00:00
if (argc == 3)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[2]);
userPassword = (*argv[2])->value.str.val;
}
result = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,hostName,userName,userPassword,persistant);
if (result == NULL) RETURN_FALSE;
FB_SQL_G(linkIndex) = result->index;
return_value->value.lval = result->index;
return_value->type = IS_LONG;
}
2001-03-21 19:56:33 +00:00
/* {{{ proto int fbsql_connect([string hostname [, string username [, string [password]]]);
*/
PHP_FUNCTION(fbsql_connect)
{
phpfbDoConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
}
/* }}} */
2001-03-21 19:56:33 +00:00
/* {{{ proto int fbsql_pconnect([string hostname [, string username [, string [password]]]);
*/
PHP_FUNCTION(fbsql_pconnect)
{
phpfbDoConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
}
/* }}} */
PHPFBLink* phpfbGetLink(int id)
{
int type;
PHPFBLink* phpLink = NULL;
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if (id == 0)
{
php_error(E_WARNING,"FrontBase has no default connection");
}
2001-03-21 19:56:33 +00:00
else if ((!(phpLink = (PHPFBLink*) zend_list_find (id,&type))) || ((type != le_link)))
{
php_error(E_WARNING,"%d is not a FBSQL link index",id);
phpLink = NULL;
}
return phpLink;
}
PHPFBResult* phpfbGetResult(int id)
{
int type;
PHPFBResult* result = NULL;
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if (id == 0) {
php_error(E_WARNING,"FBSQL no default result");
}
2001-03-21 19:56:33 +00:00
else if ((!(result = (PHPFBResult*) zend_list_find (id,&type))) || ((type != le_result))) {
php_error(E_WARNING,"%d is not a FBSQL result index",id);
result = NULL;
}
return result;
}
/* {{{ proto int fbsql_close([int link_identifier])
*/
PHP_FUNCTION(fbsql_close)
{
int argc = ARG_COUNT(ht);
unsigned i,j;
char name[1024];
PHPFBLink* phpLink = NULL;
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
if (argc == 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
phpLink = phpfbGetLink((*argv[0])->value.lval);
}
else if (FB_SQL_G(linkIndex) != 0)
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
for (i=0; i < phpLink->databaseCount; i++)
{
PHPFBDatabase* database = phpLink->databases[i];
if (database)
{
for (j=0; j < database->resultCount; j++) if (database->results[j])
{
zend_list_delete (database->results[j]->index);
FB_SQL_G(resultCount)--;
}
zend_list_delete (database->index);
FB_SQL_G(databaseCount)--;
}
}
sprintf(name,"fbsql_%s_%s",phpLink->hostName,phpLink->userName);
FB_SQL_G(linkCount)--;
if (phpLink->persistant)FB_SQL_G(persistantCount)--;
zend_hash_del (&EG(regular_list),name,strlen(name));
zend_list_delete(phpLink->index);
RETURN_TRUE;
}
/* }}} */
PHPFBDatabase* phpfbSelectDB
( INTERNAL_FUNCTION_PARAMETERS,
char* databaseName,
PHPFBLink* link
2001-03-21 19:56:33 +00:00
)
{
PHPFBDatabase* result = NULL;
list_entry *lep;
unsigned i;
char name[1024];
FBSQLLS_FETCH();
sprintf(name,"fbsql_%s@%s:%s",databaseName,link->hostName,link->userName);
if(zend_hash_find(&EG(persistent_list),name,strlen(name),(void **)&lep) == SUCCESS)
{
PHPFBDatabase* dba;
int type;
result = lep->ptr;
dba = zend_list_find(result->index,&type);
if (dba != result) result->index = zend_list_insert(result, le_dba);
}
else if(zend_hash_find(&EG(regular_list),name,strlen(name),(void **)&lep) == SUCCESS)
{
result = lep->ptr;
}
else if (FB_SQL_G(databaseCount) == FB_SQL_G(maxConnections))
{
php_error(E_WARNING,"FrontBase connection limit %d exceeded", FB_SQL_G(maxConnections));
return NULL;
}
else
{
list_entry le;
FBCDatabaseConnection* c = fbcdcConnectToDatabase(databaseName,link->hostName,FB_SQL_G(databasePassword));
FBCMetaData* md;
if (c == NULL)
{
php_error(E_WARNING, fbcdcClassErrorMessage());
return NULL;
}
md = fbcdcCreateSession(c,"PHP",link->userName,link->userPassword,link->userName);
if (fbcmdErrorsFound(md))
{
FBCErrorMetaData* emd = fbcdcErrorMetaData(c,md);
char* emg = fbcemdAllErrorMessages(emd);
if (emg)
php_error(E_WARNING, emg);
else
php_error(E_WARNING,"No message");
free(emg);
fbcemdRelease(emd);
fbcmdRelease(md);
fbcdcClose(c);
fbcdcRelease(c);
return NULL;
}
fbcmdRelease(md);
if (c)
{
if (link->autoCommit)
md = fbcdcExecuteDirectSQL(c,"SET COMMIT TRUE;");
else
md = fbcdcExecuteDirectSQL(c,"SET COMMIT FALSE;");
fbcmdRelease(md);
}
fbcdcSetOutputCharacterSet(c,FBC_ISO8859_1);
fbcdcSetInputCharacterSet(c,FBC_ISO8859_1);
le.type = le_dba;
le.ptr = result = malloc(sizeof(PHPFBDatabase));
if (zend_hash_update(link->persistant?&EG(persistent_list):&EG(regular_list), name, strlen(name), &le, sizeof(le), NULL)==FAILURE)
{
fbcdcClose(c);
fbcdcRelease(c);
free(result);
return NULL;
}
result->retainCount = 2;
result->index = zend_list_insert((PHPFBDatabase*)(le.ptr), le_dba);
result->link = phpfbRetainLink(link);
result->databaseName = strdup(databaseName);
result->databasePassword = strdup(FB_SQL_G(databasePassword));
result->connection = c;
result->errorNo = 0;
result->errorText = NULL;
result->resultCount = 0;
result->rowIndex = 0;
result->results = NULL;
for (i=0; i < link->databaseCount; i++) if ((link->databases[i]) == NULL) break;
if (i==link->databaseCount)
{
unsigned j;
link->databaseCount += 5;
link->databases = realloc(link->databases,sizeof(PHPFBDatabase*)*link->databaseCount);
for (j=i; j < link->databaseCount; j++) link->databases[j] = NULL;
}
link->databases[i] = result;
FB_SQL_G(databaseCount)++;
}
link->currentDatabase = result;
return_value->value.lval = result->index;
return_value->type = IS_LONG;
FB_SQL_G(databaseIndex) = result->index;
return result;
}
/* }}} */
2001-03-21 19:56:33 +00:00
void phpfbestrdup (const char * s, int* length, char** value)
{
int l = s?strlen(s):0;
if (value)
{
char* r = emalloc(l+1);
if (s)
strcpy(r,s);
else
r[0] = 0;
*value = r;
}
*length = l;
}
/* {{{ proto bool fbsql_list_autocommit(int link_identifier [, bool OnOff])
*/
PHP_FUNCTION(fbsql_autocommit)
{
2001-03-21 19:56:33 +00:00
int argc = ARG_COUNT(ht);
zval **argv[2];
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
zend_bool OnOff;
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
phpLink = phpfbGetLink((*argv[0])->value.lval);
2001-03-21 19:56:33 +00:00
if (argc == 2)
{
2001-03-21 19:56:33 +00:00
convert_to_boolean_ex(argv[1]);
OnOff = Z_BVAL_PP(argv[1]);
if (OnOff)
2001-03-21 19:56:33 +00:00
md = fbcdcExecuteDirectSQL(phpLink->currentDatabase->connection, "SET COMMIT TRUE;");
else
md = fbcdcExecuteDirectSQL(phpLink->currentDatabase->connection, "SET COMMIT FALSE;");
fbcmdRelease(md);
RETURN_TRUE;
}
else {
RETURN_BOOL(phpLink->autoCommit);
}
}
/* }}} */
/* {{{ proto int fbsql_list_commit([int link_identifier])
*/
PHP_FUNCTION(fbsql_commit)
{
2001-03-21 19:56:33 +00:00
int argc = ARG_COUNT(ht);
zval **argv[1];
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
int link;
FBSQLLS_FETCH();
link = FB_SQL_G(linkIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc == 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
link = (*argv[0])->value.lval;
}
phpLink = phpfbGetLink(link);
if (phpLink == NULL) RETURN_FALSE;
md = fbcdcCommit(phpLink->currentDatabase->connection);
if (md) {
fbcmdRelease(md);
RETURN_TRUE;
}
else
RETURN_FALSE;
}
/* }}} */
/* {{{ proto int fbsql_list_rollback([int link_identifier])
*/
PHP_FUNCTION(fbsql_rollback)
{
2001-03-21 19:56:33 +00:00
int argc = ARG_COUNT(ht);
zval **argv[1];
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
int link;
FBSQLLS_FETCH();
link = FB_SQL_G(linkIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc == 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
link = (*argv[0])->value.lval;
}
phpLink = phpfbGetLink(link);
if (phpLink == NULL) RETURN_FALSE;
md = fbcdcRollback(phpLink->currentDatabase->connection);
if (md) {
fbcmdRelease(md);
RETURN_TRUE;
}
else
RETURN_FALSE;
}
/* }}} */
/* {{{ proto string fbsql_hostname([string host_name])
*/
PHP_FUNCTION(fbsql_hostname)
{
2001-03-21 19:56:33 +00:00
int argc = ARG_COUNT(ht);
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
phpfbestrdup(FB_SQL_G(hostName), &return_value->value.str.len, &return_value->value.str.val);
return_value->type = IS_STRING;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
free(FB_SQL_G(hostName));
2001-03-21 19:56:33 +00:00
FB_SQL_G(hostName) = strdup((*argv[0])->value.str.val);
}
}
/* }}} */
/* {{{ proto string fbsql_database([string database])
*/
PHP_FUNCTION(fbsql_database)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
phpfbestrdup(FB_SQL_G(databaseName), &return_value->value.str.len, &return_value->value.str.val);
return_value->type = IS_STRING;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
free(FB_SQL_G(databaseName));
2001-03-21 19:56:33 +00:00
FB_SQL_G(databaseName) = strdup((*argv[0])->value.str.val);
}
}
/* }}} */
/* {{{ proto string fbsql_database_password([string database_password])
*/
PHP_FUNCTION(fbsql_database_password)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
free(FB_SQL_G(databasePassword));
2001-03-21 19:56:33 +00:00
FB_SQL_G(databasePassword) = strdup((*argv[0])->value.str.val);
}
}
/* }}} */
/* {{{ proto string fbsql_username([string username])
*/
PHP_FUNCTION(fbsql_username)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
phpfbestrdup(FB_SQL_G(userName), &return_value->value.str.len, &return_value->value.str.val);
return_value->type = IS_STRING;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
free(FB_SQL_G(userName));
2001-03-21 19:56:33 +00:00
FB_SQL_G(userName) = strdup((*argv[0])->value.str.val);
}
}
/* }}} */
/* {{{ proto string fbsql_username([string password])
*/
PHP_FUNCTION(fbsql_password)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
free(FB_SQL_G(userPassword));
2001-03-21 19:56:33 +00:00
FB_SQL_G(userPassword) = strdup((*argv[0])->value.str.val);
}
}
/* }}} */
/* {{{ proto int fbsql_select_db([string database_name [, int link_identifier]])
*/
PHP_FUNCTION(fbsql_select_db)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
char* name;
PHPFBLink* phpLink = NULL;
PHPFBDatabase* database = NULL;
FBSQLLS_FETCH();
name = FB_SQL_G(databaseName);
2001-03-21 19:56:33 +00:00
if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0],&argv[1])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
name = (*argv[0])->value.str.val;
}
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
phpLink = phpfbGetLink((*argv[1])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
/* printf("Select db at link %s@%s\n",phpLink->hostName,phpLink->userName); */
database = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU,name,phpLink);
if (database == NULL) RETURN_FALSE;
phpLink->currentDatabase = database;
FB_SQL_G(linkIndex) = phpLink->index;
return_value->value.lval = database->index;
return_value->type = IS_LONG;
}
/* }}} */
2001-03-21 19:56:33 +00:00
/* {{{ proto int fbsql_change_user(string user, string password, string [database] , int [link_identifier]);
*/
PHP_FUNCTION(fbsql_change_user)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval ** argv[4];
int link;
PHPFBLink* phpLink;
PHPFBDatabase * phpDatabase;
char* userName;
char* userPassword;
char* databaseName;
FBSQLLS_FETCH();
link = FB_SQL_G(linkIndex);
databaseName = FB_SQL_G(databaseName);
if ((argc < 2) || (argc > 4)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1],&argv[2],&argv[3])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
userName = (*argv[0])->value.str.val;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[1]);
userPassword = (*argv[1])->value.str.val;
if (argc >= 3)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[2]);
databaseName = (*argv[2])->value.str.val;
}
if (argc >= 4)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[3]);
link = (*argv[3])->value.lval;
}
if ((phpLink = phpfbGetLink(link))==NULL) RETURN_FALSE;
if ((phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU,databaseName,phpLink)) == NULL) RETURN_FALSE;
{
char buffer[1024];
sprintf(buffer,"SET AUTHORIZATION %s;",userName);
phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,buffer, phpDatabase);
if (return_value->value.lval)
{
free(phpLink->userName);
phpLink->userName = strdup(userName);
}
}
}
/* }}} */
/* {{{ proto int fbsql_create_db([string database_name [, int link_identifier]])
*/
PHP_FUNCTION(fbsql_create_db)
{
PHPFBLink* phpLink = NULL;
int i;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int link;
char* databaseName;
char* hostName;
FBDatabaseStatus status;
FBSQLLS_FETCH();
link = FB_SQL_G(linkIndex);
hostName = FB_SQL_G(hostName);
if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
2001-03-21 19:56:33 +00:00
if (argc == 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
link = (*argv[1])->value.lval;
phpLink = phpfbGetLink(link);
if (phpLink == NULL) RETURN_FALSE;
}
if (phpLink == NULL)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
if (phpLink == NULL) RETURN_FALSE;
}
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
if (status != FBUnknownStatus)
{
char* txt = "Unknown status";
2001-03-21 19:56:33 +00:00
if (status == FBStopped ) txt = "stopped";
else if (status == FBStarting) txt = "starting";
else if (status == FBRunning ) txt = "running";
else if (status == FBStopping) txt = "stopping";
else if (status == FBNoExec ) txt = "no exec";
php_error(E_WARNING, "Could not create %s@%s, database is %s",databaseName,hostName,txt);
RETURN_FALSE;
}
if (!fbcehCreateDatabaseNamedWithOptions(phpLink->execHandler, databaseName, ""))
{
char* error = fbechErrorMessage(phpLink->execHandler);
php_error(E_WARNING, "Could not create %s@%s. %s.",databaseName,hostName,error);
RETURN_FALSE;
}
for (i=0; i < 20; i++)
{
#ifdef PHP_WIN32
Sleep(1000);
#else
sleep(1);
#endif
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
if (status == FBRunning) break;
}
FB_SQL_G(linkIndex) = phpLink->index;
if (status != FBRunning)
{
php_error(E_WARNING, "Database %s@%s created -- status unknown",databaseName,hostName);
RETURN_FALSE;
}
RETURN_TRUE;
}
/* }}} */
/* {{{ proto int fbsql_drop_db(string database_name [, int link_identifier])
*/
PHP_FUNCTION(fbsql_drop_db)
{
char* databaseName;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
PHPFBLink* phpLink;
FBDatabaseStatus status;
int i;
FBSQLLS_FETCH();
if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
if (argc == 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
phpLink = phpfbGetLink((*argv[1])->value.lval);
if (phpLink == NULL) RETURN_FALSE;
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
if (phpLink) RETURN_FALSE;
}
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
if (status != FBStopped)
{
char* txt = "Unknown status";
2001-03-21 19:56:33 +00:00
if (status == FBStopped ) txt = "stopped";
else if (status == FBUnknownStatus) txt = "nonexisting";
else if (status == FBStarting ) txt = "starting";
else if (status == FBRunning ) txt = "running";
else if (status == FBStopping ) txt = "stopping";
else if (status == FBNoExec ) txt = "no exec";
php_error(E_WARNING, "Could not drop %s@%s, database is %s.",databaseName,phpLink->hostName,txt);
RETURN_FALSE;
}
if (! fbcehDeleteDatabaseNamed (phpLink->execHandler, databaseName))
{
char* error = fbechErrorMessage(phpLink->execHandler);
php_error(E_WARNING, "Could not drop %s@%s. %s.",databaseName,phpLink->hostName,error);
RETURN_FALSE;
}
for (i=0; i < 20; i++)
{
#ifdef PHP_WIN32
Sleep(1000);
#else
sleep(1);
#endif
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
if (status == FBUnknownStatus) break;
}
if (status != FBUnknownStatus)
{
php_error(E_WARNING, "Database %s@%s dropped -- status unknown",databaseName,phpLink->hostName);
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto int fbsql_stop_db(string database_name [, int link_identifier])
*/
PHP_FUNCTION(fbsql_stop_db)
{
PHPFBDatabase* phpDatabase;
PHPFBLink* phpLink = NULL;
FBDatabaseStatus status;
char* databaseName;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int link;
unsigned i;
char name[1024];
FBSQLLS_FETCH();
link = FB_SQL_G(linkIndex);
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
if (argc == 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
link = (*argv[1])->value.lval;
phpLink = phpfbGetLink(link);
if (phpLink == NULL) RETURN_FALSE;
}
if (phpLink == NULL)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
if (phpLink == NULL) RETURN_FALSE;
}
phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,phpLink);
if (phpDatabase == NULL) RETURN_FALSE;
/* printf("Stop db %x\n",phpDatabase->connection); */
if (!fbcdcStopDatabase(phpDatabase->connection))
{
php_error(E_WARNING, "Cannot stop database %s@%s",databaseName,phpLink->hostName);
RETURN_FALSE;
}
for (i=0; i < 20; i++)
{
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
if (status == FBStopped) break;
#ifdef PHP_WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
for (i=0; i < phpLink->databaseCount; i++) if (phpLink->databases[i] == phpDatabase) phpLink->databases[i] = NULL;
for (i=0; i < phpDatabase->resultCount; i++) if (phpDatabase->results[i])
{
FB_SQL_G(resultCount)--;
zend_list_delete(phpDatabase->results[i]->index);
}
/* printf("Database %X %d %d\n",phpDatabase,phpDatabase->index,phpDatabase->retainCount); */
sprintf(name,"fbsql_%s@%s:%s",databaseName,phpLink->hostName, phpLink->userName);
zend_list_delete(phpDatabase->index);
FB_SQL_G(databaseCount)--;
zend_hash_del(&EG(regular_list),name,strlen(name));
/* printf("After list delete\n"); */
RETURN_TRUE;
}
/* }}} */
/* {{{ proto int fbsql_start_db(string database_name [, int link_identifier])
*/
PHP_FUNCTION(fbsql_start_db)
{
PHPFBLink* phpLink = NULL;
int i;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
char* databaseName;
char* hostName;
FBDatabaseStatus status;
FBSQLLS_FETCH();
hostName = FB_SQL_G(hostName);
if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
phpLink = phpfbGetLink((*argv[1])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
/* printf("Start db at link %s@%s\n",phpLink->hostName,phpLink->userName); */
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
2001-03-21 19:56:33 +00:00
if ((status != FBStopped) && (status != FBRunning) && (status != FBStarting))
{
char* txt = "Unknown status";
2001-03-21 19:56:33 +00:00
if (status == FBStopped ) txt = "stopped";
else if (status == FBStarting) txt = "starting";
else if (status == FBRunning ) txt = "running";
else if (status == FBStopping) txt = "stopping";
else if (status == FBNoExec ) txt = "no exec";
php_error(E_WARNING, "Could not start %s@%s, as database is %s.",databaseName,hostName,txt);
RETURN_FALSE;
}
if (status == FBStopped)
{
if (!fbcehStartDatabaseNamed (phpLink->execHandler, databaseName))
{
char* error = fbechErrorMessage(phpLink->execHandler);
php_error(E_WARNING, "Could not start %s@%s. %s.",databaseName,hostName,error);
RETURN_FALSE;
}
}
for (i=0; i < 20; i++)
{
#ifdef PHP_WIN32
Sleep(1000);
#else
sleep(1);
#endif
status = fbcehStatusForDatabaseNamed(phpLink->execHandler,databaseName);
if (status == FBRunning) break;
}
if (status != FBRunning)
{
php_error(E_WARNING, "Database %s@%s started -- status unknown",databaseName,hostName);
RETURN_FALSE;
}
RETURN_TRUE;
}
/* }}} */
2001-03-21 19:56:33 +00:00
int mdOk(PHPFBDatabase* database, FBCMetaData* md)
{
FBCDatabaseConnection* c = database->connection;
int result = 1;
FBSQLLS_FETCH();
database->errorNo = 0;
if (database->errorText)
{
free(database->errorText);
database->errorText = NULL;
}
if (md == NULL)
{
database->errorNo = 1;
database->errorText = strdup("Connection was database server was lost");
if (FB_SQL_G(generateWarnings)) php_error(E_WARNING, database->errorText);
result = 0;
}
else if (fbcmdErrorsFound(md))
{
FBCErrorMetaData* emd = fbcdcErrorMetaData(c,md);
char* emg = fbcemdAllErrorMessages(emd);
if (FB_SQL_G(generateWarnings))
{
if (emg)
php_error(E_WARNING, emg);
else
php_error(E_WARNING,"No message");
}
database->errorText = emg;
database->errorNo = 1;
fbcemdRelease(emd);
result = 0;
}
return result;
}
2001-03-21 19:56:33 +00:00
PHPFBResult* phpfbQuery(INTERNAL_FUNCTION_PARAMETERS, char* sql, PHPFBDatabase* database)
{
PHPFBLink* link = database->link;
PHPFBResult* result = NULL;
FBCMetaData* md, *meta;
int ok;
char* tp;
char* fh;
unsigned int sR = 1, cR = 0;
FBSQLLS_FETCH();
meta = fbcdcExecuteDirectSQL(database->connection,sql);
if (fbcmdHasMetaDataArray(meta)) {
sR = fbcmdMetaDataArrayCount(meta);
md = (FBCMetaData*)fbcmdMetaDataAtIndex(meta, cR);
}
else
md = meta;
2001-03-23 00:58:59 +00:00
ok = mdOk(database, md);
tp = fbcmdStatementType(md);
return_value->value.lval = ok?-1:0;
return_value->type = IS_LONG;
/* printf("Result kind %s\n",tp); */
if (!ok || (tp[0] == 'C') || (tp[0] == 'R'))
{
unsigned i;
for (i=0; i < database->resultCount; i++)
{
PHPFBResult* result = database->results[i];
if (result)
{
/* printf("Delete from list %d %x",i,database->results[i],database->results[i]->index); */
zend_list_delete(database->results[i]->index);
FB_SQL_G(databaseCount)--;
database->results[i] = NULL;
}
}
}
else if (tp[0] == 'I')
{
database->rowIndex = fbcmdRowIndex(md);
}
else if ((fh = fbcmdFetchHandle(md)) && (FB_SQL_G(resultCount) == FB_SQL_G(maxResults)))
{
fbcdcCancelFetch(database->connection,fh);
php_error(E_WARNING,"FrontBase result set limit %d exceeded",FB_SQL_G(maxResults));
}
else if (fh || (tp[0] == 'E'))
{
unsigned i;
result = malloc(sizeof(PHPFBResult));
result->retainCount = 1;
result->index = zend_list_insert(result,le_result);
result->link = NULL;
result->database = phpfbRetainDatabase(database);
result->connection = database->connection;
result->fetchHandle = fh;
result->ResultmetaData = meta;
result->metaData = md;
result->rowHandler = NULL;
result->batchSize = FB_SQL_G(batchSize);
result->rowCount = 0x7fffffff;
result->columnCount = 0;
result->rowIndex = 0;
result->columnIndex = 0;
result->row = NULL;
result->array = NULL;
result->list = NULL;
result->selectResults = sR;
result->currentResult = cR;
FB_SQL_G(resultCount)++;
for (i=0; i < database->resultCount; i++) if (database->results[i] == NULL) break;
2001-03-21 19:56:33 +00:00
if (i == database->resultCount)
{
unsigned j;
database->resultCount += 5;
database->results = realloc(database->results,sizeof(PHPFBResult*)*database->resultCount);
for (j=i; j < database->resultCount; j++) database->results[j] = NULL;
}
database->results[i] = result;
return_value->value.lval = result->index;
if (tp[0] != 'E')
{
result->rowCount = 0x7fffffff;
result->columnCount = fbcmdColumnCount(md);
result->fetchHandle = fh;
result->batchSize = FB_SQL_G(batchSize);
}
else
{
char* r = fbcmdMessage(result->metaData);
2001-03-21 19:56:33 +00:00
if ((result->list = fbcplParse(r)))
{
result->rowCount = fbcplCount(result->list);
result->columnCount = 7;
}
}
}
if (link) link->affectedRows = fbcmdRowCount(md);
if (result == NULL) fbcmdRelease(md);
return result;
}
/* {{{ proto int fbsql_query(string query [, int link_identifier])
*/
PHP_FUNCTION(fbsql_query)
{
PHPFBDatabase* phpDatabase;
PHPFBLink* phpLink = NULL;
PHPFBResult* phpResult;
char* sql;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
FBSQLLS_FETCH();
if ((argc < 1) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
sql = (*argv[0])->value.str.val;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
phpLink = phpfbGetLink((*argv[1])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
/* printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName); */
phpDatabase = phpLink->currentDatabase;
if (phpDatabase == NULL) RETURN_FALSE;
phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
if (return_value->value.lval)
{
FB_SQL_G(linkIndex) = phpLink->index;
if (phpResult) FB_SQL_G(resultIndex) = phpResult->index;
}
}
/* }}} */
/* {{{ proto int fbsql_db_query(string database_name, string query [, int link_identifier])
*/
PHP_FUNCTION(fbsql_db_query)
{
PHPFBDatabase* phpDatabase;
PHPFBLink* phpLink;
PHPFBResult* phpResult;
char* sql;
char* databaseName;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[3];
FBSQLLS_FETCH();
if ((argc < 2) || (argc > 3)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[1]);
sql = (*argv[1])->value.str.val;
2001-03-21 19:56:33 +00:00
if (argc >= 3)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[2]);
phpLink = phpfbGetLink((*argv[2])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
/* printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName); */
phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,phpLink);
2001-03-21 19:56:33 +00:00
if (phpDatabase == NULL) RETURN_FALSE;
phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
if (return_value->value.lval)
{
FB_SQL_G(linkIndex) = phpLink->index;
if (phpResult) FB_SQL_G(resultIndex) = phpResult->index;
}
}
/* }}} */
/* {{{ proto int fbsql_list_dbs([int link_identifier])
*/
PHP_FUNCTION(fbsql_list_dbs)
{
PHPFBLink* phpLink = NULL;
PHPFBResult* phpResult;
unsigned i;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc == 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
phpLink = phpfbGetLink((*argv[0])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
if (FB_SQL_G(resultCount) == FB_SQL_G(maxResults))
{
php_error(E_WARNING,"FrontBase result set limit %d exceeded",FB_SQL_G(maxResults));
RETURN_FALSE
}
phpResult = malloc(sizeof(PHPFBResult));
phpResult->retainCount = 1;
phpResult->index = zend_list_insert(phpResult, le_result);
phpResult->link = phpfbRetainLink(phpLink);
phpResult->database = NULL;
phpResult->connection = NULL;
phpResult->fetchHandle = NULL;
phpResult->rowHandler = NULL;
phpResult->ResultmetaData = NULL;
phpResult->metaData = NULL;
phpResult->batchSize = FB_SQL_G(batchSize);
phpResult->columnCount = 1;
phpResult->rowIndex = 0;
phpResult->columnIndex = 0;
phpResult->row = NULL;
phpResult->array = fbcehAvailableDatabases(phpLink->execHandler);
phpResult->rowCount = fbaCount(phpResult->array);
phpResult->list = NULL;
FB_SQL_G(resultCount)++;
for (i=0; i < phpLink->resultCount; i++) if (phpLink->results[i] == NULL) break;
2001-03-21 19:56:33 +00:00
if (i == phpLink->resultCount)
{
unsigned j;
phpLink->resultCount += 5;
2001-03-21 19:56:33 +00:00
phpLink->results = realloc(phpLink->results,sizeof(PHPFBResult*)* phpLink->resultCount);
for (j=i; j < phpLink->resultCount ; j++)phpLink->results[j] = NULL;
}
phpLink->results[i] = phpResult;
return_value->value.lval = phpResult->index;
return_value->type = IS_LONG;
FB_SQL_G(resultIndex) = phpResult->index;
FB_SQL_G(linkIndex) = phpLink->index;
}
/* }}} */
2001-03-21 19:56:33 +00:00
/* {{{ proto int fbsql_list_tables(string database, int [link_identifier]);
*/
PHP_FUNCTION(fbsql_list_tables)
{
PHPFBDatabase* phpDatabase;
PHPFBLink* phpLink;
PHPFBResult* phpResult;
char* sql = "select t0.\"table_name\"from information_schema.tables t0, information_schema.SCHEMATA t1 where t0.schema_pk = t1.schema_pk and t1.\"schema_name\" = current_schema;";
char* databaseName = NULL;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
FBSQLLS_FETCH();
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
}
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
phpLink = phpfbGetLink((*argv[1])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (databaseName == NULL)
{
phpLink->currentDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, FB_SQL_G(databaseName),phpLink);
}
else
{
phpLink->currentDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,phpLink);
}
phpDatabase = phpLink->currentDatabase;
if (phpDatabase == NULL) RETURN_FALSE;
phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
if (return_value->value.lval)
{
FB_SQL_G(linkIndex) = phpLink->index;
if (phpResult) FB_SQL_G(resultIndex) = phpResult->index;
}
}
/* }}} */
/* {{{ proto int fbsql_list_fields(string database_name, string table_name [, int link_identifier])
*/
PHP_FUNCTION(fbsql_list_fields)
{
PHPFBDatabase* phpDatabase;
PHPFBLink* phpLink;
PHPFBResult* phpResult;
char sql[1024];
char* databaseName = NULL;
char* tableName = NULL;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
FBSQLLS_FETCH();
if ((argc < 2) || (argc > 3)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
databaseName = (*argv[0])->value.str.val;
}
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[1]);
tableName = (*argv[1])->value.str.val;
}
2001-03-21 19:56:33 +00:00
if (argc >= 3)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[2]);
phpLink = phpfbGetLink((*argv[2])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
phpDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, databaseName,phpLink);
phpLink->currentDatabase = phpDatabase;
if (phpDatabase == NULL) RETURN_FALSE;
sprintf(sql,"EXTRACT TABLE %s;",tableName);
phpResult = phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU,sql,phpDatabase);
if (return_value->value.lval)
{
FB_SQL_G(linkIndex) = phpLink->index;
if (phpResult) FB_SQL_G(resultIndex) = phpResult->index;
}
}
/* }}} */
/* {{{ proto string fbsql_error([int link_identifier])
*/
PHP_FUNCTION(fbsql_error)
{
PHPFBLink* phpLink = NULL;
PHPFBDatabase* phpDatabase;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
phpLink = phpfbGetLink((*argv[0])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) != 0)
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
/* printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName); */
phpDatabase = phpLink->currentDatabase;
if ((phpDatabase == NULL) || (phpDatabase->errorText == NULL)) RETURN_FALSE;
phpfbestrdup(phpDatabase->errorText,&return_value->value.str.len,&return_value->value.str.val);
return_value->type = IS_STRING;
}
/* }}} */
/* {{{ proto int fbsql_errno([int link_identifier])
*/
PHP_FUNCTION(fbsql_errno)
{
PHPFBLink* phpLink = NULL;
PHPFBDatabase* phpDatabase;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
phpLink = phpfbGetLink((*argv[0])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) != 0)
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
/* printf("Query db at link %s@%s\n",phpLink->hostName,phpLink->userName); */
phpDatabase = phpLink->currentDatabase;
if (phpDatabase == NULL) RETURN_FALSE;
return_value->value.lval = phpDatabase->errorNo;
return_value->type = IS_LONG;
}
/* }}} */
2001-03-21 19:56:33 +00:00
/* {{{ proto int fbsql_generate_warnings([int flag]);
*/
PHP_FUNCTION(fbsql_warnings)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
return_value->value.lval = FB_SQL_G(generateWarnings);
return_value->type = IS_LONG;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
FB_SQL_G(generateWarnings) = (*argv[0])->value.lval != 0;
}
}
/* }}} */
/* {{{ proto int fbsql_affected_rows([int link_identifier])
*/
PHP_FUNCTION(fbsql_affected_rows)
{
PHPFBLink* phpLink;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
int link;
FBSQLLS_FETCH();
link = FB_SQL_G(linkIndex);
if (argc > 1) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc == 1)
{
2001-03-21 19:56:33 +00:00
convert_to_string_ex(argv[0]);
link = (*argv[0])->value.lval;
}
phpLink = phpfbGetLink(link);
if (phpLink == NULL) RETURN_FALSE;
return_value->value.lval = phpLink->affectedRows;
return_value->type = IS_LONG;
}
/* }}} */
/* {{{ proto int fbsql_insert_id([int link_identifier])
*/
PHP_FUNCTION(fbsql_insert_id)
{
PHPFBLink* phpLink;
PHPFBDatabase* phpDatabase;
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc == 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
phpLink = phpfbGetLink((*argv[0])->value.lval);
}
2001-03-21 19:56:33 +00:00
else if (FB_SQL_G(linkIndex) == 0)
{
phpLink = phpfbConnect(INTERNAL_FUNCTION_PARAM_PASSTHRU,NULL,NULL,NULL,0);
}
else
{
phpLink = phpfbGetLink(FB_SQL_G(linkIndex));
}
if (phpLink == NULL) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (phpLink->currentDatabase == NULL)
{
phpLink->currentDatabase = phpfbSelectDB(INTERNAL_FUNCTION_PARAM_PASSTHRU, FB_SQL_G(databaseName),phpLink);
}
phpDatabase = phpLink->currentDatabase;
if (phpDatabase == NULL) RETURN_FALSE;
return_value->value.lval = phpDatabase->rowIndex;
return_value->type = IS_LONG;
FB_SQL_G(linkIndex) = phpLink->index;
}
/* }}} */
2001-03-21 19:56:33 +00:00
int phpSizeOfInt (int i)
{
int s = 1;
2001-03-21 19:56:33 +00:00
if (i < 0)
{
s++;
i = -i;
}
while ((i = i / 10)) s++;
return s;
}
2001-03-21 19:56:33 +00:00
void phpfbColumnAsString (PHPFBResult* result, int column, void* data ,int* length, char** value)
{
FBCMetaData* md = result->metaData;
const FBCDatatypeMetaData* dtmd = fbcmdDatatypeMetaDataAtIndex(md, column);
unsigned dtc = fbcdmdDatatypeCode(dtmd);
switch (dtc)
{
case FB_Boolean:
{
unsigned char v = *((unsigned char*)(data));
if (v == 255)
phpfbestrdup("Unknown",length,value);
2001-03-21 19:56:33 +00:00
else if (v == 0)
phpfbestrdup("False",length,value);
else
phpfbestrdup("True",length,value);
}
break;
case FB_PrimaryKey:
case FB_Integer:
{
int v = *((int*)data);
char b[128];
sprintf(b,"%d",v);
phpfbestrdup(b,length,value);
}
break;
case FB_SmallInteger:
{
short v = *((short*)data);
char b[128];
sprintf(b,"%d",v);
phpfbestrdup(b,length,value);
}
break;
case FB_Float:
case FB_Real:
case FB_Double:
case FB_Numeric:
case FB_Decimal:
{
double v = *((double*)data);
char b[128];
sprintf(b,"%f",v);
phpfbestrdup(b,length,value);
}
break;
case FB_Character:
case FB_VCharacter:
{
char* v = (char*)data;
phpfbestrdup(v,length,value);
}
break;
case FB_Bit:
case FB_VBit:
{
const FBCColumnMetaData* clmd = fbcmdColumnMetaDataAtIndex(md,column);
struct bitValue
{
unsigned int nBytes;
unsigned char* bytes;
};
struct bitValue* ptr = data;
unsigned nBits = ptr->nBytes * 8;
if (dtc == FB_Bit) nBits = fbcdmdLength(fbccmdDatatype(clmd));
2001-03-21 19:56:33 +00:00
if (nBits %8 == 0)
{
unsigned i;
unsigned int l = nBits / 8;
*length = l + 5;
if (value)
{
char* r = emalloc(l*2+3+1);
r[0] = 'X';
r[1] = '\'';
2001-03-21 19:56:33 +00:00
for (i = 0; i < nBits / 8; i++)
{
char c[4];
sprintf(c,"%02x",ptr->bytes[i]);
r[i*2+2] = c[0];
r[i*2+3] = c[1];
}
r[i*2+2] = '\'';
r[i*2+3] = 0;
*value = r;
}
}
else
{
unsigned i;
unsigned int l = nBits;
*length = l + 5;
if (value)
{
char* r = emalloc(l*2+3+1);
r[0] = 'B';
r[1] = '\'';
2001-03-21 19:56:33 +00:00
for (i = 0; i < nBits; i++)
{
int bit = 0;
if (i/8 < ptr->nBytes) bit = ptr->bytes[i/8] & (1<<(7-(i%8)));
r[i*2+2] = bit?'1':'0';
}
r[i*2+2] = '\'';
r[i*2+3] = 0;
*value = r;
}
}
}
break;
case FB_Date:
case FB_Time:
case FB_TimeTZ:
case FB_Timestamp:
case FB_TimestampTZ:
{
char* v = (char*)data;
phpfbestrdup(v,length,value);
}
break;
case FB_YearMonth:
{
char b[128];
int v = *((unsigned int*)data);
sprintf(b,"%d",v);
phpfbestrdup(b,length,value);
}
break;
case FB_DayTime:
{
char b[128];
double seconds = *((double*)data);
sprintf(b,"%f",seconds);
phpfbestrdup(b,length,value);
}
break;
case FB_CLOB:
case FB_BLOB:
/* {
unsigned char* bytes = (unsigned char*)data;
if (*bytes == '\1')
{ /* Direct
unsigned int l = *((unsigned int*)(bytes+1));
unsigned char* ptr = *((unsigned char**)(bytes+5));
unsigned int i;
mf(file,"%4d:",l);
for (i=0; i < l; i++)
{
if (i)
{
if ((i % 32) == 0)
mf(file,"\n %*d:",lw+4,i);
else if ((i % 4) == 0)
mf(file," ");
}
mf(file,"%02x",*ptr++);
}
}
else
{
mf(file,"%s",bytes+1);
}
}
break;
*/
default:
php_error(E_WARNING,"Unimplemented type");
break;
}
}
2001-03-21 19:56:33 +00:00
void phpfbSqlResult (INTERNAL_FUNCTION_PARAMETERS, PHPFBResult* result, int rowIndex, int columnIndex)
{
void** row;
if (result->list)
{
FBCPList* columns = (FBCPList*)fbcplValueForKey(result->list,"COLUMNS");
FBCPList* column = (FBCPList*)fbcplValueAtIndex(columns,result->rowIndex);
2001-03-21 19:56:33 +00:00
if (columnIndex == 0)
{ /* Name */
FBCPList* name = (FBCPList*)fbcplValueForKey(column,"NAME");
return_value->type = IS_STRING;
2001-03-21 19:56:33 +00:00
phpfbestrdup(fbcplString((FBCPList*)name), &return_value->value.str.len, &return_value->value.str.val);
}
2001-03-21 19:56:33 +00:00
else if (columnIndex == 2)
{ /* Length */
FBCPList* name = (FBCPList*)fbcplValueForKey(column,"WIDTH");
return_value->type = IS_STRING;
phpfbestrdup((const char*)fbcplString(name), &return_value->value.str.len, &return_value->value.str.val);
}
2001-03-21 19:56:33 +00:00
else if (columnIndex == 1)
{ /* Type */
FBCPList* name = (FBCPList*)fbcplValueForKey(column,"DATATYPE");
return_value->type = IS_STRING;
phpfbestrdup((const char*)fbcplString(name), &return_value->value.str.len, &return_value->value.str.val);
}
2001-03-21 19:56:33 +00:00
else if (columnIndex == 3)
{ /* Flags */
return_value->type = IS_STRING;
phpfbestrdup("", &return_value->value.str.len, &return_value->value.str.val);
}
else
{
return_value->type = IS_STRING;
phpfbestrdup("", &return_value->value.str.len, &return_value->value.str.val);
}
}
else if (result->array)
{ /* Special case for get dbs */
phpfbestrdup((char*)fbaObjectAtIndex(result->array,rowIndex), &return_value->value.str.len, &return_value->value.str.val);
return_value->type = IS_STRING;
}
else if (!phpfbFetchRow(result,rowIndex))
{
/* php_error(E_WARNING,"No such row %d in result set %d",resultIndex+1,rowIndex); */
RETURN_FALSE;
}
else if (columnIndex >= result->columnCount)
{
php_error(E_WARNING,"No such column %d in result set %d",columnIndex,rowIndex);
RETURN_FALSE;
}
else
{
row = fbcrhRowAtIndex(result->rowHandler,rowIndex);
if (row == NULL)
{
RETURN_FALSE;
}
else if (row[columnIndex])
{
phpfbColumnAsString(result,columnIndex,row[columnIndex],&return_value->value.str.len,&return_value->value.str.val);
return_value->type = IS_STRING;
}
else
{
return_value->type = IS_NULL;
}
}
}
/* {{{ proto int fbsql_result(int result, int row [, mixed field])
*/
PHP_FUNCTION(fbsql_result)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[3];
PHPFBResult* result;
int resultIndex;
int rowIndex;
int columnIndex;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 3)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1],&argv[2])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
rowIndex = result->rowIndex;
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
rowIndex = (*argv[1])->value.lval;
}
columnIndex = result->columnIndex;
if (argc == 3)
{
2001-03-21 19:56:33 +00:00
if (((*argv[2])->type == IS_STRING) && (result->metaData))
{
for (columnIndex =0; columnIndex < result->columnCount; columnIndex ++)
{
const FBCColumnMetaData* cmd = fbcmdColumnMetaDataAtIndex(result->metaData, columnIndex);
const char* lbl = fbccmdLabelName(cmd);
2001-03-21 19:56:33 +00:00
if (strcmp((char*)lbl, (*argv[2])->value.str.val) == 0) break;
}
if (columnIndex == result->columnCount) RETURN_FALSE;
}
else
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[2]);
columnIndex = (*argv[2])->value.lval;
if (columnIndex < 0)
{
php_error(E_WARNING,"Illegal column index - %d",columnIndex);
RETURN_FALSE;
}
}
}
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,rowIndex,columnIndex);
FB_SQL_G(resultIndex) = resultIndex;
result->columnIndex++;
if (result->columnIndex == result->columnCount)
{
result->rowIndex++;
result->columnIndex = 0;
}
}
/* }}} */
/* {{{ proto int fbsql_next_result(int result)
*/
PHP_FUNCTION(fbsql_next_result)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
PHPFBResult* result;
int resultIndex;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
result = phpfbGetResult((*argv[0])->value.lval);
if (result == NULL) RETURN_FALSE;
result->currentResult++;
if (result->currentResult < result->selectResults) {
if (result->fetchHandle) fbcdcCancelFetch(result->connection, result->fetchHandle);
if (result->rowHandler) fbcrhRelease(result->rowHandler);
result->metaData = (FBCMetaData*)fbcmdMetaDataAtIndex(result->ResultmetaData, result->currentResult);
result->fetchHandle = fbcmdFetchHandle(result->metaData);
result->rowHandler = NULL;
result->batchSize = FB_SQL_G(batchSize);
result->rowCount = 0x7fffffff;
result->columnCount = fbcmdColumnCount(result->metaData);;
result->rowIndex = 0;
result->columnIndex = 0;
result->row = NULL;
result->array = NULL;
result->list = NULL;
if (result->database->link)
result->database->link->affectedRows = fbcmdRowCount(result->metaData);
RETURN_TRUE;
}
else {
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto int fbsql_num_rows(int result)
*/
PHP_FUNCTION(fbsql_num_rows)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
int resultIndex;
PHPFBResult* result;
int rowCount;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
if (result->array)
rowCount = result->rowCount;
else {
rowCount = fbcmdRowCount(result->metaData);
if (rowCount == -1)
{
phpfbFetchRow(result,0x7fffffff);
rowCount = result->rowCount;
}
}
return_value->value.lval = rowCount;
return_value->type = IS_LONG;
}
/* }}} */
/* {{{ proto int fbsql_num_fields(int result)
*/
PHP_FUNCTION(fbsql_num_fields)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
int resultIndex;
PHPFBResult* result;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
return_value->value.lval = result->columnCount;
return_value->type = IS_LONG;
FB_SQL_G(resultIndex) = resultIndex;
}
/* }}} */
/* {{{ proto object fbsql_fetch_object(int result [, int result_typ])
*/
PHP_FUNCTION(fbsql_fetch_object)
{
PHP_FN(fbsql_fetch_array)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
if (return_value->type==IS_ARRAY)
{
return_value->type=IS_OBJECT;
return_value->value.obj.properties = return_value->value.ht;
return_value->value.obj.ce = &zend_standard_class_def;
}
}
/* }}} */
/* {{{ proto array fbsql_fetch_row(int result)
*/
PHP_FUNCTION(fbsql_fetch_row)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int i;
int resultIndex;
PHPFBResult* result;
int rowIndex ;
void** row;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1) {
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
rowIndex = result->rowIndex;
if (result->fetchHandle == NULL) {
RETURN_FALSE;
}
if (result->rowCount == 0) {
RETURN_FALSE;
}
if (result->rowCount == 0x7fffffff) {
if (!phpfbFetchRow(result,rowIndex)) {
RETURN_FALSE;
}
}
if (!(row = fbcrhRowAtIndex(result->rowHandler,rowIndex))) {
RETURN_FALSE;
}
if (array_init(return_value)==FAILURE) {
RETURN_FALSE;
}
result->row = row;
for (i=0; i < result->columnCount; i++) {
char* value;
unsigned int length;
if (row[i]) {
phpfbColumnAsString(result,i,row[i],&length,&value);
add_index_stringl(return_value,i,value,length,0);
}
else {
add_index_unset(return_value,i);
}
}
result->rowIndex = rowIndex+1;
result->columnIndex = 0;
FB_SQL_G(resultIndex) = resultIndex;
}
/* }}} */
/* {{{ proto array fbsql_fetch_array(int result [, int result_typ])
*/
PHP_FUNCTION(fbsql_fetch_array)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int i;
int resultIndex;
PHPFBResult* result;
int rowIndex;
int result_type = FBSQL_BOTH;
void** row;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
rowIndex = result->rowIndex;
2001-03-21 19:56:33 +00:00
if (argc == 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
result_type = (*argv[1])->value.lval;
if (((result_type & FBSQL_NUM) != FBSQL_NUM) && ((result_type & FBSQL_ASSOC) != FBSQL_ASSOC))
{
php_error(E_WARNING,"Illegal result type use FBSQL_NUM, FBSQL_ASSOC, or FBSQL_BOTH.");
RETURN_FALSE;
}
}
if (result->fetchHandle == NULL)
{
RETURN_FALSE;
}
if (result->rowCount == 0) {
RETURN_FALSE;
}
if (result->rowCount == 0x7fffffff)
{
if (!phpfbFetchRow(result,result->rowIndex)) {
RETURN_FALSE;
}
}
row = fbcrhRowAtIndex(result->rowHandler,rowIndex);
if (row == NULL)
{
RETURN_FALSE;
}
if (array_init(return_value)==FAILURE)
{
RETURN_FALSE;
}
for (i=0; i < result->columnCount; i++)
{
if (row[i])
{
char* value;
unsigned int length;
unsigned int c = 0;
phpfbColumnAsString(result,i,row[i],&length,&value);
if (result_type & FBSQL_NUM)
{
add_index_stringl(return_value,i,value,length,c);
c = 1;
}
if (result_type & FBSQL_ASSOC)
{
char* key = (char*)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, i));
add_assoc_stringl(return_value,key, value, length, c);
}
}
else
{
if (result_type & FBSQL_NUM)
{
add_index_unset(return_value,i);
}
if (result_type & FBSQL_ASSOC)
{
char* key = (char*)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, i));
add_assoc_unset(return_value,key);
}
}
}
result->rowIndex = result->rowIndex+1;
result->columnIndex = 0;
}
/* }}} */
/* {{{ proto int fbsql_data_seek(int result, int row_number)
*/
PHP_FUNCTION(fbsql_data_seek)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int rowIndex;
FBSQLLS_FETCH();
2001-03-21 19:56:33 +00:00
if (argc != 2) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
rowIndex = (*argv[1])->value.lval;
if (rowIndex < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (result->rowCount == 0x7fffffff) phpfbFetchRow(result,rowIndex);
if (rowIndex > result->rowCount) RETURN_FALSE;
result->rowIndex = rowIndex;
RETURN_TRUE;
}
/* }}} */
/* {{{ proto array fbsql_fetch_lengths(int result)
*/
PHP_FUNCTION(fbsql_fetch_lengths)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int i;
int resultIndex;
PHPFBResult* result;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
if (result->row == NULL) RETURN_FALSE;
if (array_init(return_value)==FAILURE) RETURN_FALSE;
for (i=0; i < result->columnCount; i++)
{
unsigned length = 0;
if (result->row[i]) phpfbColumnAsString(result,i, result->row[i],&length,NULL);
add_index_long(return_value, i, length);
}
FB_SQL_G(resultIndex) = resultIndex;
}
/* }}} */
/* {{{ proto object fbsql_fetch_field(int result [, int field_offset])
*/
PHP_FUNCTION(fbsql_fetch_field)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
if (column < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"%d no such column in result",column);
RETURN_FALSE;
}
}
if (object_init(return_value)==FAILURE)
{
RETURN_FALSE;
}
add_property_string(return_value, "name", (char*)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, column)),1);
add_property_string(return_value, "table", (char*)fbccmdTableName(fbcmdColumnMetaDataAtIndex(result->metaData,column)),1);
add_property_long(return_value, "max_length", fbcdmdLength(fbccmdDatatype(fbcmdColumnMetaDataAtIndex(result->metaData,column))));
add_property_string(return_value, "type", (char*)fbcdmdDatatypeString (fbcmdDatatypeMetaDataAtIndex(result->metaData, column)),1);
/* Remember to add the rest */
/* add_property_long(return_value, "not_null",IS_NOT_NULL(mysql_field->flags)?1:0); */
/* add_property_long(return_value, "primary_key",IS_PRI_KEY(mysql_field->flags)?1:0); */
/* add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0)); */
/* add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0)); */
/* add_property_long(return_value, "numeric",IS_NUM(mysql_field->type)?1:0); */
/* add_property_long(return_value, "blob",IS_BLOB(mysql_field->flags)?1:0); */
/* add_property_string(return_value, "type",php_mysql_get_field_name(mysql_field->type), 1); */
/* add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0)); */
/* add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0)); */
}
/* }}} */
/* {{{ proto int fbsql_field_seek(int result, int field_offset)
*/
PHP_FUNCTION(fbsql_field_seek)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
if (argc>=2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
}
2001-03-21 19:56:33 +00:00
if (column < 0)
{
php_error(E_WARNING,"Illegal column index %d",column);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"No such column %d in result %d",column,resultIndex);
RETURN_FALSE;
}
FB_SQL_G(resultIndex) = resultIndex;
result->columnIndex = column;
RETURN_TRUE;
}
/* }}} */
/* {{{ proto string mysql_field_name(int result, int field_index)
*/
PHP_FUNCTION(fbsql_field_name)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
if (column < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"%d no such row in result",column);
RETURN_FALSE;
}
}
if (result->list)
{
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,result->rowIndex,0);
}
else if (result->metaData)
{
phpfbestrdup(fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, column)),
&return_value->value.str.len,
&return_value->value.str.val);
return_value->type = IS_STRING;
FB_SQL_G(resultIndex) = resultIndex;
result->columnIndex = column;
}
}
/* }}} */
/* {{{ proto string fbsql_field_table(int result, int field_index)
*/
PHP_FUNCTION(fbsql_field_table)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
if (column < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"%d no such row in result",column);
RETURN_FALSE;
}
}
phpfbestrdup(fbccmdTableName(fbcmdColumnMetaDataAtIndex(result->metaData,column)),
&return_value->value.str.len,
&return_value->value.str.val);
return_value->type = IS_STRING;
}
/* }}} */
/* {{{ proto string fbsql_field_lene(int result, int field_index)
*/
PHP_FUNCTION(fbsql_field_len)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
if (column < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"%d no such row in result",column);
RETURN_FALSE;
}
}
if (result->list)
{
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,result->rowIndex,2);
}
else if (result->metaData)
{
unsigned int length = fbcdmdLength(fbccmdDatatype(fbcmdColumnMetaDataAtIndex(result->metaData,column)));
char buffer[50];
sprintf(buffer,"%d",length);
phpfbestrdup(buffer,
&return_value->value.str.len,
&return_value->value.str.val);
return_value->type = IS_STRING;
}
else
{
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto string fbsql_field_type(int result, int field_index)
*/
PHP_FUNCTION(fbsql_field_type)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
if (column < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"%d no such column in result",column);
RETURN_FALSE;
}
}
if (result->list)
{
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU,result,result->rowIndex,1);
}
else if (result->metaData)
{
phpfbestrdup(fbcdmdDatatypeString (fbcmdDatatypeMetaDataAtIndex(result->metaData, column)),
&return_value->value.str.len,
&return_value->value.str.val);
return_value->type = IS_STRING;
}
else
{
RETURN_FALSE;
}
}
/* }}} */
/* {{{ proto string fbsql_field_flags(int result, int field_index)
*/
PHP_FUNCTION(fbsql_field_flags)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[2];
int resultIndex;
PHPFBResult* result;
int column;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
2001-03-21 19:56:33 +00:00
if ((argc < 0) || (argc > 2)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0],&argv[1])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
column = result->columnIndex;
2001-03-21 19:56:33 +00:00
if (argc >= 2)
{
2001-03-21 19:56:33 +00:00
convert_to_long_ex(argv[1]);
column = (*argv[1])->value.lval;
if (column < 0)
{
php_error(E_WARNING,"Illegal index",resultIndex+1);
RETURN_FALSE;
}
if (column >= result->columnCount)
{
php_error(E_WARNING,"%d no such column in result",column);
RETURN_FALSE;
}
}
if (array_init(return_value)==FAILURE)
{
RETURN_FALSE;
}
/* We should create the result -- currently empty */
}
/* }}} */
/* {{{ proto int fbsql_free_result(int result)
*/
PHP_FUNCTION(fbsql_free_result)
{
int argc = ARG_COUNT(ht);
2001-03-21 19:56:33 +00:00
zval **argv[1];
int resultIndex;
PHPFBResult* result;
FBSQLLS_FETCH();
resultIndex = FB_SQL_G(resultIndex);
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc,&argv[0])==FAILURE) RETURN_FALSE;
2001-03-21 19:56:33 +00:00
if (argc >= 1) {
convert_to_long_ex(argv[0]);
resultIndex = (*argv[0])->value.lval;
}
result = phpfbGetResult(resultIndex);
if (result == NULL) RETURN_FALSE;
zend_list_delete(result->index);
FB_SQL_G(resultCount)--;
FB_SQL_G(resultIndex) = 0;
RETURN_TRUE;
}
/* }}} */
#endif