#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_globals.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#ifdef PHP_WIN32
#include <winsock2.h>
#else
#include <php_config.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
#ifndef min
# define min(a,b) ((a)<(b)?(a):(b))
#endif
#if HAVE_FBSQL
#include "php_fbsql.h"
#include <signal.h>
static int le_result, le_link, le_plink;
struct PHPFBResult;
typedef struct PHPFBResult PHPFBResult;
struct PHPFBLink;
typedef struct PHPFBLink PHPFBLink;
void* fbaObjectAtIndex();
void fbaRelease();
unsigned int fbaCount();
struct FBCAutoStartInfo {
FBArray* infoLines;
};
struct PHPFBResult
{
PHPFBLink* link;
char* fetchHandle;
FBCMetaData* metaData;
FBCMetaData* ResultmetaData;
FBCRowHandler* rowHandler;
unsigned int batchSize;
unsigned int rowCount;
int columnCount;
unsigned int rowIndex;
int columnIndex;
void** row;
FBArray* array;
FBCPList* list;
unsigned int selectResults;
unsigned int currentResult;
int lobMode;
};
struct PHPFBLink
{
int persistent;
char* hostName;
char* userName;
char* userPassword;
char* databasePassword;
char* databaseName;
FBCExecHandler* execHandler;
FBCDatabaseConnection* connection;
unsigned int affectedRows;
long autoCommit;
unsigned int errorNo;
char* errorText;
unsigned int insert_id;
};
#define FBSQL_ASSOC 1<<0
#define FBSQL_NUM 1<<1
#define FBSQL_BOTH (FBSQL_ASSOC|FBSQL_NUM)
#define FBSQL_LOCK_DEFERRED 0
#define FBSQL_LOCK_OPTIMISTIC 1
#define FBSQL_LOCK_PESSIMISTIC 2
#define FBSQL_ISO_READ_UNCOMMITTED 0
#define FBSQL_ISO_READ_COMMITTED 1
#define FBSQL_ISO_REPEATABLE_READ 2
#define FBSQL_ISO_SERIALIZABLE 3
#define FBSQL_ISO_VERSIONED 4
#define FBSQL_LOB_DIRECT 0
#define FBSQL_LOB_HANDLE 1
#define DIGEST_BUFFER_SIZE 17
ZEND_DECLARE_MODULE_GLOBALS(fbsql)
static PHP_GINIT_FUNCTION(fbsql);
int mdOk(PHPFBLink* link, FBCMetaData* md, char* sql);
char *DigestPassword(char *user, char *password)
{
char *digest = NULL;
if (user && strlen(user) && password && strlen(password)) {
char *user_upper = estrdup(user);
digest = emalloc(DIGEST_BUFFER_SIZE);
digest[0] = '\0';
(void)fbcDigestPassword(php_strtoupper(user_upper, strlen(user_upper)), password, digest);
efree(user_upper);
}
return digest;
}
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_connect, 0, 0, 0)
ZEND_ARG_INFO(0, hostname)
ZEND_ARG_INFO(0, username)
ZEND_ARG_INFO(0, password)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_pconnect, 0, 0, 0)
ZEND_ARG_INFO(0, username)
ZEND_ARG_INFO(0, hostname)
ZEND_ARG_INFO(0, password)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_close, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_set_transaction, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, locking)
ZEND_ARG_INFO(0, isolation)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_autocommit, 0, 0, 1)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, OnOff)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_commit, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_rollback, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_create_blob, 0, 0, 1)
ZEND_ARG_INFO(0, blob_data)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_create_clob, 0, 0, 1)
ZEND_ARG_INFO(0, clob_data)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_set_lob_mode, 0)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, lob_mode)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_read_blob, 0, 0, 1)
ZEND_ARG_INFO(0, blob_handle)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_read_clob, 0, 0, 1)
ZEND_ARG_INFO(0, clob_handle)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_blob_size, 0, 0, 1)
ZEND_ARG_INFO(0, blob_handle)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_clob_size, 0, 0, 1)
ZEND_ARG_INFO(0, clob_handle)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_hostname, 0, 0, 1)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, host_name)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_database, 0, 0, 1)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, database)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_database_password, 0, 0, 1)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, database_password)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_username, 0, 0, 1)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, username)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_password, 0, 0, 1)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, password)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_set_password, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, user)
ZEND_ARG_INFO(0, password)
ZEND_ARG_INFO(0, old_password)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_select_db, 0, 0, 0)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_set_characterset, 0, 0, 2)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, charcterset)
ZEND_ARG_INFO(0, in_out_both)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_change_user, 0, 0, 2)
ZEND_ARG_INFO(0, user)
ZEND_ARG_INFO(0, password)
ZEND_ARG_INFO(0, database)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_create_db, 0, 0, 1)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, database_options)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_drop_db, 0, 0, 1)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_start_db, 0, 0, 1)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, database_options)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_stop_db, 0, 0, 1)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_db_status, 0, 0, 1)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_query, 0, 0, 1)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, batch_size)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_db_query, 0, 0, 2)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, query)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_list_dbs, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_list_tables, 0, 0, 1)
ZEND_ARG_INFO(0, database)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_list_fields, 0, 0, 2)
ZEND_ARG_INFO(0, database_name)
ZEND_ARG_INFO(0, table_name)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_error, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_errno, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_warnings, 0, 0, 0)
ZEND_ARG_INFO(0, flag)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_affected_rows, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_rows_fetched, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_insert_id, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_result, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, row)
ZEND_ARG_INFO(0, field)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_next_result, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_num_rows, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_num_fields, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_fetch_row, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_fetch_assoc, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_fetch_object, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, result_type)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_fetch_array, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, result_type)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_data_seek, 0)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, row_number)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_fetch_lengths, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_fetch_field, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_field_seek, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_field_name, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_field_table, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_field_len, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_field_type, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_field_flags, 0, 0, 1)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, field_index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_table_name, 0)
ZEND_ARG_INFO(0, result)
ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO(arginfo_fbsql_free_result, 0)
ZEND_ARG_INFO(0, result)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_fbsql_get_autostart_info, 0, 0, 0)
ZEND_ARG_INFO(0, link_identifier)
ZEND_END_ARG_INFO()
zend_function_entry fbsql_functions[] = {
PHP_FE(fbsql_connect, arginfo_fbsql_connect)
PHP_FE(fbsql_pconnect, arginfo_fbsql_pconnect)
PHP_FE(fbsql_close, arginfo_fbsql_close)
PHP_FE(fbsql_select_db, arginfo_fbsql_select_db)
PHP_FE(fbsql_set_characterset, arginfo_fbsql_set_characterset)
PHP_FE(fbsql_create_db, arginfo_fbsql_create_db)
PHP_FE(fbsql_drop_db, arginfo_fbsql_drop_db)
PHP_FE(fbsql_start_db, arginfo_fbsql_start_db)
PHP_FE(fbsql_stop_db, arginfo_fbsql_stop_db)
PHP_FE(fbsql_db_status, arginfo_fbsql_db_status)
PHP_FE(fbsql_query, arginfo_fbsql_query)
PHP_FE(fbsql_db_query, arginfo_fbsql_db_query)
PHP_FE(fbsql_list_dbs, arginfo_fbsql_list_dbs)
PHP_FE(fbsql_list_tables, arginfo_fbsql_list_tables)
PHP_FE(fbsql_list_fields, arginfo_fbsql_list_fields)
PHP_FE(fbsql_error, arginfo_fbsql_error)
PHP_FE(fbsql_errno, arginfo_fbsql_errno)
PHP_FE(fbsql_affected_rows, arginfo_fbsql_affected_rows)
PHP_FE(fbsql_rows_fetched, arginfo_fbsql_rows_fetched)
PHP_FE(fbsql_insert_id, arginfo_fbsql_insert_id)
PHP_FE(fbsql_result, arginfo_fbsql_result)
PHP_FE(fbsql_next_result, arginfo_fbsql_next_result)
PHP_FE(fbsql_num_rows, arginfo_fbsql_num_rows)
PHP_FE(fbsql_num_fields, arginfo_fbsql_num_fields)
PHP_FE(fbsql_fetch_row, arginfo_fbsql_fetch_row)
PHP_FE(fbsql_fetch_array, arginfo_fbsql_fetch_array)
PHP_FE(fbsql_fetch_assoc, arginfo_fbsql_fetch_assoc)
PHP_FE(fbsql_fetch_object, arginfo_fbsql_fetch_object)
PHP_FE(fbsql_data_seek, arginfo_fbsql_data_seek)
PHP_FE(fbsql_fetch_lengths, arginfo_fbsql_fetch_lengths)
PHP_FE(fbsql_fetch_field, arginfo_fbsql_fetch_field)
PHP_FE(fbsql_field_seek, arginfo_fbsql_field_seek)
PHP_FE(fbsql_free_result, arginfo_fbsql_free_result)
PHP_FE(fbsql_field_name, arginfo_fbsql_field_name)
PHP_FE(fbsql_field_table, arginfo_fbsql_field_table)
PHP_FE(fbsql_field_len, arginfo_fbsql_field_len)
PHP_FE(fbsql_field_type, arginfo_fbsql_field_type)
PHP_FE(fbsql_field_flags, arginfo_fbsql_field_flags)
PHP_FE(fbsql_table_name, arginfo_fbsql_table_name)
PHP_FE(fbsql_set_transaction, arginfo_fbsql_set_transaction)
PHP_FE(fbsql_autocommit, arginfo_fbsql_autocommit)
PHP_FE(fbsql_commit, arginfo_fbsql_commit)
PHP_FE(fbsql_rollback, arginfo_fbsql_rollback)
PHP_FE(fbsql_create_blob, arginfo_fbsql_create_blob)
PHP_FE(fbsql_create_clob, arginfo_fbsql_create_clob)
PHP_FE(fbsql_set_lob_mode, arginfo_fbsql_set_lob_mode)
PHP_FE(fbsql_read_blob, arginfo_fbsql_read_blob)
PHP_FE(fbsql_read_clob, arginfo_fbsql_read_clob)
PHP_FE(fbsql_blob_size, arginfo_fbsql_blob_size)
PHP_FE(fbsql_clob_size, arginfo_fbsql_clob_size)
PHP_FE(fbsql_hostname, arginfo_fbsql_hostname)
PHP_FE(fbsql_database, arginfo_fbsql_database)
PHP_FE(fbsql_database_password, arginfo_fbsql_database_password)
PHP_FE(fbsql_username, arginfo_fbsql_username)
PHP_FE(fbsql_password, arginfo_fbsql_password)
PHP_FE(fbsql_warnings, arginfo_fbsql_warnings)
PHP_FE(fbsql_set_password, arginfo_fbsql_set_password)
PHP_FE(fbsql_get_autostart_info, arginfo_fbsql_get_autostart_info)
PHP_FALIAS(fbsql, fbsql_db_query, arginfo_fbsql_db_query)
PHP_FALIAS(fbsql_tablename, fbsql_table_name, arginfo_fbsql_table_name)
{NULL, NULL, NULL}
};
zend_module_entry fbsql_module_entry = {
STANDARD_MODULE_HEADER,
"fbsql",
fbsql_functions,
PHP_MINIT(fbsql),
PHP_MSHUTDOWN(fbsql),
PHP_RINIT(fbsql),
PHP_RSHUTDOWN(fbsql),
PHP_MINFO(fbsql),
NO_VERSION_YET,
PHP_MODULE_GLOBALS(fbsql),
PHP_GINIT(fbsql),
NULL,
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
#ifdef COMPILE_DL_FBSQL
ZEND_GET_MODULE(fbsql)
#endif
#define CHECK_LINK(link) { \
if (link==-1) { \
if (FB_SQL_G(generateWarnings)) \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); \
RETURN_FALSE; \
} \
}
static void phpfbReleaseResult(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static void phpfbReleaseLink(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static void phpfbReleasePLink(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static void phpfbReleaseResult(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
PHPFBResult* result = (PHPFBResult *)rsrc->ptr;
if (result)
{
if (result->fetchHandle) {
FBCMetaData *md = fbcdcCancelFetch(result->link->connection, result->fetchHandle);
fbcmdRelease(md);
}
if (result->rowHandler) fbcrhRelease(result->rowHandler);
if (result->list) fbcplRelease(result->list);
if (result->array) fbaRelease(result->array);
if (result->ResultmetaData) fbcmdRelease(result->ResultmetaData);
efree(result);
}
}
static void phpfbReleaseLink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
PHPFBLink* link = (PHPFBLink *)rsrc->ptr;
if (link)
{
if (link->hostName) free(link->hostName);
if (link->userName) free(link->userName);
if (link->userPassword) free(link->userPassword);
if (link->databasePassword) free(link->databasePassword);
if (link->databaseName) free(link->databaseName);
if (link->errorText) free(link->errorText);
if (link->connection) {
fbcdcClose(link->connection);
fbcdcRelease(link->connection);
}
if (link->execHandler) fbcehRelease(link->execHandler);
efree(link);
FB_SQL_G(linkCount)--;
}
}
static void phpfbReleasePLink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
PHPFBLink* link = (PHPFBLink *)rsrc->ptr;
if (link)
{
if (link->hostName) free(link->hostName);
if (link->userName) free(link->userName);
if (link->userPassword) free(link->userPassword);
if (link->databasePassword) free(link->databasePassword);
if (link->databaseName) free(link->databaseName);
if (link->errorText) free(link->errorText);
if (link->connection) {
fbcdcClose(link->connection);
fbcdcRelease(link->connection);
}
if (link->execHandler) fbcehRelease(link->execHandler);
free(link);
FB_SQL_G(linkCount)--;
FB_SQL_G(persistentCount)--;
}
}
static void php_fbsql_set_default_link(int id TSRMLS_DC)
{
if (FB_SQL_G(linkIndex)!=-1) {
zend_list_delete(FB_SQL_G(linkIndex));
}
FB_SQL_G(linkIndex) = id;
zend_list_addref(id);
}
static int php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
{
if (FB_SQL_G(linkIndex)==-1) {
ht = 0;
php_fbsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
return FB_SQL_G(linkIndex);
}
static void phpfbQuery(INTERNAL_FUNCTION_PARAMETERS, char* sql, PHPFBLink* link, long batch_size);
PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN ("fbsql.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateBool, allowPersistent, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_BOOLEAN ("fbsql.generate_warnings", "0", PHP_INI_SYSTEM, OnUpdateBool, generateWarnings, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_BOOLEAN ("fbsql.autocommit", "1", PHP_INI_SYSTEM, OnUpdateBool, autoCommit, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_BOOLEAN ("fbsql.show_timestamp_decimals", "0", PHP_INI_SYSTEM, OnUpdateBool, showTimestampDecimals, zend_fbsql_globals, fbsql_globals)
STD_PHP_INI_ENTRY_EX ("fbsql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, maxPersistent, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.max_links", "128", PHP_INI_SYSTEM, OnUpdateLong, maxLinks, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.max_connections", "128", PHP_INI_SYSTEM, OnUpdateLong, maxConnections, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.max_results", "128", PHP_INI_SYSTEM, OnUpdateLong, maxResults, zend_fbsql_globals, fbsql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX ("fbsql.batchsize", "1000", PHP_INI_ALL, OnUpdateLong, 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 PHP_GINIT_FUNCTION(fbsql)
{
fbsql_globals->persistentCount = 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->persistentCount = 0;
fbsql_globals->linkCount = 0;
}
PHP_MINIT_FUNCTION(fbsql)
{
REGISTER_INI_ENTRIES();
fbcInitialize();
fbcehSetMultiThreaded(True);
le_result = zend_register_list_destructors_ex(phpfbReleaseResult, NULL, "fbsql result", module_number);
le_link = zend_register_list_destructors_ex(phpfbReleaseLink, NULL, "fbsql link", module_number);
le_plink = zend_register_list_destructors_ex(NULL, phpfbReleasePLink, "fbsql plink", module_number);
Z_TYPE(fbsql_module_entry) = type;
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);
REGISTER_LONG_CONSTANT("FBSQL_LOCK_DEFERRED", FBSQL_LOCK_DEFERRED, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_LOCK_OPTIMISTIC", FBSQL_LOCK_OPTIMISTIC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_LOCK_PESSIMISTIC", FBSQL_LOCK_PESSIMISTIC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_ISO_READ_UNCOMMITTED", FBSQL_ISO_READ_UNCOMMITTED, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_ISO_READ_COMMITTED", FBSQL_ISO_READ_COMMITTED, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_ISO_REPEATABLE_READ", FBSQL_ISO_REPEATABLE_READ, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_ISO_SERIALIZABLE", FBSQL_ISO_SERIALIZABLE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_ISO_VERSIONED", FBSQL_ISO_VERSIONED, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_UTF8", 0, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_ISO8859_1", FBC_ISO8859_1, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_UNKNOWN", FBUnknownStatus, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_STOPPED", FBStopped, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_STARTING", FBStarting, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_RUNNING", FBRunning, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_STOPPING", FBStopping, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_NOEXEC", FBNoExec, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_LOB_DIRECT", FBSQL_LOB_DIRECT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FBSQL_LOB_HANDLE", FBSQL_LOB_HANDLE, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(fbsql)
{
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
PHP_RINIT_FUNCTION(fbsql)
{
FB_SQL_G(linkIndex) = -1;
FB_SQL_G(linkCount) = FB_SQL_G(persistentCount);
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(fbsql)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(fbsql)
{
char buf[32];
php_info_print_table_start();
php_info_print_table_header(2, "FrontBase support", "enabled");
php_info_print_table_row(2, "Client API version", "2.24");
if (FB_SQL_G(allowPersistent))
{
snprintf(buf, sizeof(buf), "%ld", FB_SQL_G(persistentCount));
php_info_print_table_row(2, "Active Persistent Links", buf);
}
snprintf(buf, sizeof(buf), "%ld", FB_SQL_G(linkCount));
php_info_print_table_row(2, "Active Links", buf);
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
static void php_fbsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
{
PHPFBLink* phpLink;
zend_rsrc_list_entry *lep;
char name[1024];
char *hostName = NULL, *userName = NULL, *userPassword = NULL;
int argc = ZEND_NUM_ARGS(), create_new = 0;
zval **argv[3];
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)
{
convert_to_string_ex(argv[0]);
hostName = Z_STRVAL_PP(argv[0]);
}
if (argc >= 2)
{
convert_to_string_ex(argv[1]);
userName = Z_STRVAL_PP(argv[1]);
}
if (argc == 3)
{
convert_to_string_ex(argv[2]);
userPassword = Z_STRVAL_PP(argv[2]);
}
if (hostName == NULL) hostName = FB_SQL_G(hostName);
if (userName == NULL) userName = FB_SQL_G(userName);
if (userPassword == NULL) userPassword = FB_SQL_G(userPassword);
if (snprintf(name, sizeof(name), "fbsql_%s_%s_%s", hostName, userName, userPassword) < 0) {
RETURN_FALSE;
}
if (!FB_SQL_G(allowPersistent)) {
persistent=0;
}
if (persistent) {
if (zend_hash_find(&EG(persistent_list), name, strlen(name) + 1, (void **)&lep) == SUCCESS)
{
FBCMetaData *md;
phpLink = (PHPFBLink*)lep->ptr;
md = fbcdcRollback(phpLink->connection);
if ( !mdOk(phpLink, md, "Rollback;") ) {
if (FB_SQL_G(generateWarnings)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "FrontBase link is not connected, ty to reconnect.");
}
fbcmdRelease(md);
fbcdcClose(phpLink->connection);
fbcdcRelease(phpLink->connection);
free(phpLink->connection);
phpLink->connection = NULL;
if (phpLink->databaseName) free(phpLink->databaseName);
phpLink->databaseName = NULL;
}
else {
fbcmdRelease(md);
}
}
else {
zend_rsrc_list_entry le;
if ((FB_SQL_G(maxLinks) != -1 && FB_SQL_G(linkCount) == FB_SQL_G(maxLinks)))
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "FrontBase link limit %d exceeded", FB_SQL_G(maxLinks));
RETURN_FALSE;
}
if ((FB_SQL_G(maxPersistent) != -1 && FB_SQL_G(persistentCount) == FB_SQL_G(maxPersistent)))
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "FrontBase persistent link limit %d exceeded", FB_SQL_G(maxPersistent));
RETURN_FALSE;
}
phpLink = malloc(sizeof(PHPFBLink));
phpLink->persistent = persistent;
phpLink->hostName = strdup(hostName);
phpLink->userName = strdup(userName);
phpLink->userPassword = strdup(userPassword);
phpLink->databasePassword = strdup(FB_SQL_G(databasePassword));
phpLink->databaseName = NULL;
phpLink->execHandler = NULL;
phpLink->affectedRows = 0;
phpLink->autoCommit = FB_SQL_G(autoCommit);
phpLink->errorNo = 0;
phpLink->errorText = NULL;
phpLink->connection = NULL;
le.ptr = phpLink;
Z_TYPE(le) = le_plink;
if (zend_hash_update(&EG(persistent_list), name, strlen(name) + 1, &le, sizeof(le), NULL)==FAILURE)
{
free(phpLink->hostName);
free(phpLink->userName);
free(phpLink->userPassword);
free(phpLink->databasePassword);
free(phpLink);
RETURN_FALSE;
}
FB_SQL_G(linkCount)++;
FB_SQL_G(persistentCount)++;
}
ZEND_REGISTER_RESOURCE(return_value, phpLink, le_plink);
}
else
{
zend_rsrc_list_entry le;
if ((FB_SQL_G(maxLinks) != -1 && FB_SQL_G(linkCount) == FB_SQL_G(maxLinks)))
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "FrontBase link limit %d exceeded", FB_SQL_G(maxLinks));
RETURN_FALSE;
}
if (zend_hash_find(&EG(regular_list), name, strlen(name) + 1, (void **)&lep) == SUCCESS)
{
int type, link;
void *ptr;
link = (int) lep->ptr;
ptr = zend_list_find(link, &type);
if (ptr && (type==le_link || type==le_plink)) {
zend_list_addref(link);
Z_LVAL_P(return_value) = link;
php_fbsql_set_default_link(link TSRMLS_CC);
Z_TYPE_P(return_value) = IS_RESOURCE;
return;
} else {
zend_hash_del(&EG(regular_list), name, strlen(name) + 1);
}
phpLink = (PHPFBLink*)lep->ptr;
}
phpLink = emalloc(sizeof(PHPFBLink));
phpLink->persistent = persistent;
phpLink->hostName = strdup(hostName);
phpLink->userName = strdup(userName);
phpLink->userPassword = strdup(userPassword);
phpLink->databasePassword = strdup(FB_SQL_G(databasePassword));
phpLink->databaseName = NULL;
phpLink->execHandler = NULL;
phpLink->affectedRows = 0;
phpLink->autoCommit = FB_SQL_G(autoCommit);
phpLink->errorNo = 0;
phpLink->errorText = NULL;
phpLink->connection = NULL;
ZEND_REGISTER_RESOURCE(return_value, phpLink, le_link);
le.ptr = (void *)Z_LVAL_P(return_value);
Z_TYPE(le) = le_index_ptr;
if (zend_hash_update(&EG(regular_list), name, strlen(name) + 1, &le, sizeof(le), NULL)==FAILURE)
{
free(phpLink->hostName);
free(phpLink->userName);
free(phpLink->userPassword);
free(phpLink->databasePassword);
efree(phpLink);
RETURN_FALSE;
}
FB_SQL_G(linkCount)++;
}
php_fbsql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
}
int phpfbFetchRow(PHPFBResult* result, unsigned int row)
{
if (result->rowHandler == NULL)
{
void *rawData = fbcdcFetch(result->link->connection, result->batchSize, result->fetchHandle);
if (rawData == NULL) {
result->rowCount = 0;
}
else
result->rowHandler = fbcrhInitWith(rawData, result->metaData);
}
for (;;)
{
void *rawData;
if (row >= result->rowCount && result->rowCount != 0x7fffffff) return 0;
if (fbcrhRowCount(result->rowHandler) > (unsigned int)row) return 1;
rawData = fbcdcFetch(result->link->connection, result->batchSize, result->fetchHandle);
if (!fbcrhAddBatch(result->rowHandler, rawData)) result->rowCount = fbcrhRowCount(result->rowHandler);
}
}
PHP_FUNCTION(fbsql_connect)
{
php_fbsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
PHP_FUNCTION(fbsql_pconnect)
{
php_fbsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
PHP_FUNCTION(fbsql_close)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id, i, nument, type;
void *ptr;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
nument = zend_hash_next_free_element(&EG(regular_list));
for (i = 1; i < nument; i++) {
ptr = zend_list_find(i, &type);
if (ptr && (type == le_result)) {
PHPFBResult *result;
result = (PHPFBResult *)ptr;
if (result->link == phpLink) {
zend_list_delete(i);
}
}
}
if (id==-1) {
zend_list_delete(Z_RESVAL_PP(fbsql_link_index));
}
if (id!=-1
|| (fbsql_link_index && Z_RESVAL_PP(fbsql_link_index)==FB_SQL_G(linkIndex))) {
zend_list_delete(FB_SQL_G(linkIndex));
FB_SQL_G(linkIndex) = -1;
}
RETURN_TRUE;
}
static int php_fbsql_select_db(char *databaseName, PHPFBLink *link TSRMLS_DC)
{
unsigned port;
FBCDatabaseConnection* c;
FBCMetaData* md;
if (!link->databaseName || strcmp(link->databaseName, databaseName))
{
port = atoi(databaseName);
if (port>0 && port<65535)
c = fbcdcConnectToDatabaseUsingPort(link->hostName, port, link->databasePassword);
else
c = fbcdcConnectToDatabase(databaseName, link->hostName, link->databasePassword);
if (c == NULL)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", fbcdcClassErrorMessage());
return 0;
}
md = fbcdcCreateSession(c, "PHP", link->userName, link->userPassword, link->userName);
if (fbcmdErrorsFound(md))
{
FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
char* emg = fbcemdAllErrorMessages(emd);
if (FB_SQL_G(generateWarnings))
{
if (emg)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", emg);
else
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message");
}
link->errorText = strdup(emg);
link->errorNo = fbcemdErrorCodeAtIndex(emd, 0);
free(emg);
fbcemdRelease(emd);
fbcmdRelease(md);
fbcdcClose(c);
fbcdcRelease(c);
return 0;
}
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);
if (link->connection)
{
fbcdcClose(link->connection);
fbcdcRelease(link->connection);
}
link->connection = c;
if (link->databaseName) free(link->databaseName);
link->databaseName = strdup(databaseName);
}
return 1;
}
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;
}
PHP_FUNCTION(fbsql_set_transaction)
{
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
zval **fbsql_link_index = NULL, **Locking = NULL, **Isolation = NULL;
char strSQL[1024];
char *strLocking[] = {"DEFERRED", "OPTIMISTIC", "PESSIMISTIC"};
char *strIsolation[] = {"READ UNCOMMITTED", "READ NCOMMITTED", "REPEATABLE READ", "SERIALIZABLE", "VERSIONED"};
switch (ZEND_NUM_ARGS()) {
case 3:
if (zend_get_parameters_ex(3, &fbsql_link_index, &Locking, &Isolation)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
if (Z_LVAL_PP(Locking) < 0 || Z_LVAL_PP(Locking) > 2) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locking type.");
RETURN_FALSE;
}
if (Z_LVAL_PP(Isolation) < 0 || Z_LVAL_PP(Isolation) > 4) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid isolation type.");
RETURN_FALSE;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (snprintf(strSQL, sizeof(strSQL) , "SET TRANSACTION LOCKING %s, ISOLATION %s;", strLocking[Z_LVAL_PP(Locking)], strIsolation[Z_LVAL_PP(Isolation)]) < 0) {
RETURN_FALSE;
}
md = fbcdcExecuteDirectSQL(phpLink->connection, strSQL);
fbcmdRelease(md);
}
PHP_FUNCTION(fbsql_autocommit)
{
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
zval **fbsql_link_index = NULL, **onoff = NULL;
zend_bool OnOff;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &onoff)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (onoff)
{
convert_to_boolean_ex(onoff);
OnOff = Z_BVAL_PP(onoff);
phpLink->autoCommit = OnOff;
if (OnOff)
md = fbcdcExecuteDirectSQL(phpLink->connection, "SET COMMIT TRUE;");
else
md = fbcdcExecuteDirectSQL(phpLink->connection, "SET COMMIT FALSE;");
fbcmdRelease(md);
}
RETURN_BOOL(phpLink->autoCommit);
}
PHP_FUNCTION(fbsql_commit)
{
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
md = fbcdcCommit(phpLink->connection);
if (md) {
fbcmdRelease(md);
RETURN_TRUE;
}
else
RETURN_FALSE;
}
PHP_FUNCTION(fbsql_rollback)
{
PHPFBLink* phpLink = NULL;
FBCMetaData* md;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
md = fbcdcRollback(phpLink->connection);
if (md) {
fbcmdRelease(md);
RETURN_TRUE;
}
else
RETURN_FALSE;
}
static void php_fbsql_create_lob(INTERNAL_FUNCTION_PARAMETERS, int lob_type)
{
PHPFBLink* phpLink = NULL;
FBCBlobHandle *lobHandle;
zval **lob_data, **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &lob_data)==FAILURE) {
RETURN_FALSE;
}
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 2:
if (zend_get_parameters_ex(2, &lob_data, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(lob_data);
switch (lob_type) {
case 0 :
lobHandle = fbcdcWriteBLOB(phpLink->connection, Z_STRVAL_PP(lob_data), Z_STRLEN_PP(lob_data));
break;
case 1 :
lobHandle = fbcdcWriteCLOB(phpLink->connection, Z_STRVAL_PP(lob_data));
break;
}
if (lobHandle) {
RETURN_STRING(fbcbhDescription(lobHandle), 1);
fbcbhRelease(lobHandle);
}
else
RETURN_FALSE;
}
PHP_FUNCTION(fbsql_create_blob)
{
php_fbsql_create_lob(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
PHP_FUNCTION(fbsql_create_clob)
{
php_fbsql_create_lob(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
PHP_FUNCTION(fbsql_set_lob_mode)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **lob_mode = NULL;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &lob_mode)==FAILURE) {
RETURN_FALSE;
}
convert_to_long_ex(lob_mode);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
result->lobMode = Z_LVAL_PP(lob_mode);
RETURN_TRUE;
}
static void php_fbsql_read_lob(INTERNAL_FUNCTION_PARAMETERS, int lob_type)
{
PHPFBLink* phpLink = NULL;
zval **lob_handle, **fbsql_link_index = NULL;
int id;
long length = 0;
char* value = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &lob_handle)==FAILURE) {
RETURN_FALSE;
}
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 2:
if (zend_get_parameters_ex(2, &lob_handle, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(lob_handle);
if (Z_STRLEN_PP(lob_handle) != 27 || Z_STRVAL_PP(lob_handle)[0] != '@') {
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The handle is invalid");
RETURN_FALSE;
}
length = fbcbhBlobSize((FBCBlobHandle *)Z_STRVAL_PP(lob_handle));
if (lob_type == 0)
value = estrndup((char *)fbcdcReadBLOB(phpLink->connection, (FBCBlobHandle *)Z_STRVAL_PP(lob_handle)), length);
else
value = estrndup((char *)fbcdcReadCLOB(phpLink->connection, (FBCBlobHandle *)Z_STRVAL_PP(lob_handle)), length);
if (value) {
RETURN_STRINGL(value, length, 0);
}
else {
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_read_blob)
{
php_fbsql_read_lob(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
PHP_FUNCTION(fbsql_read_clob)
{
php_fbsql_read_lob(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
static void php_fbsql_lob_size(INTERNAL_FUNCTION_PARAMETERS, int lob_type)
{
PHPFBLink* phpLink = NULL;
zval **lob_handle, **fbsql_link_index = NULL;
int id;
char* value = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &lob_handle)==FAILURE) {
RETURN_FALSE;
}
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 2:
if (zend_get_parameters_ex(2, &lob_handle, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(lob_handle);
if (Z_STRLEN_PP(lob_handle) != 27 || Z_STRVAL_PP(lob_handle)[0] != '@') {
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The handle is invalid");
RETURN_FALSE;
}
RETURN_LONG(fbcbhBlobSize((FBCBlobHandle *)Z_STRVAL_PP(lob_handle)));
}
PHP_FUNCTION(fbsql_blob_size)
{
php_fbsql_lob_size(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
PHP_FUNCTION(fbsql_clob_size)
{
php_fbsql_lob_size(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
}
PHP_FUNCTION(fbsql_hostname)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **host_name = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &host_name)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (host_name)
{
convert_to_string_ex(host_name);
if (phpLink->hostName) free(phpLink->hostName);
phpLink->hostName = strdup(Z_STRVAL_PP(host_name));
}
RETURN_STRING(phpLink->hostName, 1);
}
PHP_FUNCTION(fbsql_database)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **dbname = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &dbname)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (dbname)
{
convert_to_string_ex(dbname);
if (phpLink->databaseName) free(phpLink->databaseName);
phpLink->databaseName = strdup(Z_STRVAL_PP(dbname));
}
if (phpLink->databaseName) {
RETURN_STRING(phpLink->databaseName, 1);
}
else {
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_database_password)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **db_password = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &db_password)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (db_password)
{
convert_to_string_ex(db_password);
if (phpLink->databasePassword) free(phpLink->databasePassword);
phpLink->databasePassword = strdup(Z_STRVAL_PP(db_password));
}
RETURN_STRING(phpLink->databasePassword, 1);
}
PHP_FUNCTION(fbsql_username)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **username = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &username)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (username)
{
convert_to_string_ex(username);
if (phpLink->userName) free(phpLink->userName);
phpLink->userName = strdup(Z_STRVAL_PP(username));
}
RETURN_STRING(phpLink->userName, 1);
}
PHP_FUNCTION(fbsql_password)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **password = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &password)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
if (password)
{
convert_to_string_ex(password);
if (phpLink->userPassword) free(phpLink->userPassword);
phpLink->userPassword = strdup(Z_STRVAL_PP(password));
}
RETURN_STRING(phpLink->userPassword, 1);
}
PHP_FUNCTION(fbsql_set_password)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **user, **password, **old_password;
char *digest_password, *digest_old_password;
FBCMetaData *md;
switch (ZEND_NUM_ARGS()) {
case 4:
if (zend_get_parameters_ex(4, &fbsql_link_index, &user, &password, &old_password)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(user);
convert_to_string_ex(password);
convert_to_string_ex(old_password);
digest_password = DigestPassword(Z_STRVAL_PP(user), Z_STRVAL_PP(password));
digest_old_password = DigestPassword(Z_STRVAL_PP(user), Z_STRVAL_PP(old_password));
md = fbcdcSetPasswordForUser(phpLink->connection, Z_STRVAL_PP(user), digest_password, digest_old_password);
if (mdOk(phpLink, md, "Change password")) {
ZVAL_BOOL(return_value, 1);
}
else {
ZVAL_BOOL(return_value, 0);
}
fbcmdRelease(md);
if (digest_old_password) efree(digest_old_password);
if (digest_password) efree(digest_password);
}
PHP_FUNCTION(fbsql_select_db)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **dbname;
int id;
char* name = NULL;
switch (ZEND_NUM_ARGS()) {
case 0:
name = FB_SQL_G(databaseName);
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &dbname)==FAILURE) {
RETURN_FALSE;
}
convert_to_string_ex(dbname);
name = Z_STRVAL_PP(dbname);
break;
case 2:
if (zend_get_parameters_ex(2, &dbname, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
convert_to_string_ex(dbname);
name = Z_STRVAL_PP(dbname);
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
if (!php_fbsql_select_db(name, phpLink TSRMLS_CC)) {
RETURN_FALSE;
}
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_set_characterset)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index, **zcharset, **zin_out;
int id = -1;
int charset = -1, in_out_both = 3;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &fbsql_link_index, &zcharset)==FAILURE) {
RETURN_FALSE;
}
break;
case 3:
if (zend_get_parameters_ex(3, &fbsql_link_index, &zcharset, &zin_out)==FAILURE) {
RETURN_FALSE;
}
in_out_both = Z_LVAL_PP(zin_out);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
charset = Z_LVAL_PP(zcharset);
if (in_out_both & 1) {
fbcdcSetInputCharacterSet(phpLink->connection, charset);
}
if (in_out_both & 2) {
fbcdcSetOutputCharacterSet(phpLink->connection, charset);
}
}
PHP_FUNCTION(fbsql_change_user)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **user, **password, **database;
int id;
char *name = NULL, *userName, *userPassword;
char buffer[1024];
switch (ZEND_NUM_ARGS()) {
case 2:
name = FB_SQL_G(databaseName);
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(2, &user, &password)==FAILURE) {
RETURN_FALSE;
}
break;
case 3:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(3, &user, &password, &database)==FAILURE) {
RETURN_FALSE;
}
convert_to_string_ex(database);
name = Z_STRVAL_PP(database);
break;
case 4:
if (zend_get_parameters_ex(4, &user, &password, &database, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
convert_to_string_ex(database);
name = Z_STRVAL_PP(database);
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(user);
userName = Z_STRVAL_PP(user);
convert_to_string_ex(password);
userPassword = Z_STRVAL_PP(password);
if (snprintf(buffer, sizeof(buffer), "SET AUTHORIZATION %s;", userName) < 0) {
RETURN_FALSE;
}
phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, buffer, phpLink, 0);
if (Z_LVAL_P(return_value))
{
free(phpLink->userName);
phpLink->userName = strdup(userName);
}
}
PHP_FUNCTION(fbsql_create_db)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name, **database_options = NULL;
int id;
int i, status;
char *databaseName, *databaseOptions = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &database_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &database_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
case 3:
if (zend_get_parameters_ex(3, &database_name, &fbsql_link_index, &database_options)==FAILURE) {
RETURN_FALSE;
}
id = -1;
convert_to_string_ex(database_options);
databaseOptions = Z_STRVAL_PP(database_options);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
if (phpLink->execHandler == NULL) phpLink->execHandler = fbcehHandlerForHost(phpLink->hostName, 128);
status = fbcehStatusForDatabaseNamed(phpLink->execHandler, databaseName);
if (status != FBUnknownStatus)
{
char* txt = "Unknown status";
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";
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create %s@%s, database is %s", databaseName, phpLink->hostName, txt);
RETURN_FALSE;
}
if (!fbcehCreateDatabaseNamedWithOptions(phpLink->execHandler, databaseName, databaseOptions))
{
char* error = fbechErrorMessage(phpLink->execHandler);
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create %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 == FBRunning) break;
}
if (status != FBRunning)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database %s@%s created -- status unknown", databaseName, phpLink->hostName);
RETURN_FALSE;
}
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_drop_db)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name;
int id;
int i, status;
char *databaseName;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &database_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &database_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
if (phpLink->execHandler == NULL) phpLink->execHandler = fbcehHandlerForHost(phpLink->hostName, 128);
status = fbcehStatusForDatabaseNamed(phpLink->execHandler, databaseName);
if (status != FBStopped)
{
char* txt = "Unknown status";
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";
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, 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);
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, 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)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database %s@%s dropped -- status unknown", databaseName, phpLink->hostName);
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_start_db)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name, **database_options;
int id;
int i, status;
char *databaseName, *databaseOptions = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &database_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &database_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
case 3:
if (zend_get_parameters_ex(3, &database_name, &fbsql_link_index, &database_options)==FAILURE) {
RETURN_FALSE;
}
id = -1;
convert_to_string_ex(database_options);
databaseOptions = Z_STRVAL_PP(database_options);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
if (phpLink->execHandler == NULL) phpLink->execHandler = fbcehHandlerForHost(phpLink->hostName, 128);
status = fbcehStatusForDatabaseNamed(phpLink->execHandler, databaseName);
if ((status != FBStopped) && (status != FBRunning) && (status != FBStarting))
{
char* txt = "Unknown status";
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";
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not start %s@%s, as database is %s", databaseName, phpLink->hostName, txt);
RETURN_FALSE;
}
if (status == FBStopped)
{
int dbstarted;
if (databaseOptions != NULL)
{
dbstarted = fbcehStartDatabaseNamedWithOptions(phpLink->execHandler, databaseName, databaseOptions);
}
else
{
dbstarted = fbcehStartDatabaseNamed(phpLink->execHandler, databaseName);
}
if (!dbstarted)
{
char* error = fbechErrorMessage(phpLink->execHandler);
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not start %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 == FBRunning) break;
}
if (status != FBRunning)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database %s@%s started -- status unknown", databaseName, phpLink->hostName);
RETURN_FALSE;
}
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_stop_db)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name;
int id;
int i, status;
char *databaseName;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &database_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &database_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
if (!php_fbsql_select_db(databaseName, phpLink TSRMLS_CC)) {
RETURN_FALSE;
}
if (!fbcdcStopDatabase(phpLink->connection))
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, 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
}
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_db_status)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name;
int id;
char *databaseName;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &database_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &database_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
if (phpLink->execHandler == NULL) phpLink->execHandler = fbcehHandlerForHost(phpLink->hostName, 128);
if (phpLink->execHandler) {
RETURN_LONG(fbcehStatusForDatabaseNamed(phpLink->execHandler, databaseName));
}
else {
RETURN_FALSE;
}
}
int mdOk(PHPFBLink* link, FBCMetaData* md, char* sql)
{
FBCDatabaseConnection* c = link->connection;
int result = 1;
TSRMLS_FETCH();
link->errorNo = 0;
if (link->errorText)
{
free(link->errorText);
link->errorText = NULL;
}
if (md == NULL)
{
link->errorNo = 1;
link->errorText = strdup("Connection to database server was lost");
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", link->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_docref(NULL TSRMLS_CC, E_WARNING, "Error in statement: '%s' %s", sql, emg);
else
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message");
}
link->errorText = strdup(emg);
link->errorNo = fbcemdErrorCodeAtIndex(emd, 0);
free(emg);
fbcemdRelease(emd);
result = 0;
}
else if (fbcmdWarningsFound(md))
{
FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
char* emg = fbcemdAllErrorMessages(emd);
if (FB_SQL_G(generateWarnings))
{
if (emg)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Warning in statement: '%s' %s", sql, emg);
else
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message");
}
link->errorText = strdup(emg);
link->errorNo = fbcemdErrorCodeAtIndex(emd, 0);
free(emg);
fbcemdRelease(emd);
result = 1;
}
return result;
}
static void phpfbQuery(INTERNAL_FUNCTION_PARAMETERS, char* sql, PHPFBLink* link, long batch_size)
{
PHPFBResult* result = NULL;
FBCMetaData* md, *meta;
char* tp;
char* fh = NULL;
unsigned int sR = 1, cR = 0;
meta = fbcdcExecuteDirectSQL(link->connection, sql);
if (!mdOk(link, meta, sql))
{
fbcmdRelease(meta);
ZVAL_BOOL(return_value, 0)
}
else {
if (fbcmdHasMetaDataArray(meta)) {
sR = fbcmdMetaDataArrayCount(meta);
md = (FBCMetaData*)fbcmdMetaDataAtIndex(meta, cR);
}
else
md = meta;
tp = fbcmdStatementType(md);
if (tp == NULL) {
fbcmdRelease(meta);
ZVAL_BOOL(return_value, 1)
}
else if ((tp[0] == 'C') || (tp[0] == 'R'))
{
if (sR == 1 && md) fbcmdRelease(md);
ZVAL_BOOL(return_value, 1)
}
else if ((fh = fbcmdFetchHandle(md)) || tp[0] == 'E' || (tp[0] == 'U' && fh))
{
result = (PHPFBResult *)emalloc(sizeof(PHPFBResult));
result->link = link;
result->rowHandler = NULL;
result->fetchHandle = NULL;
result->ResultmetaData = meta;
result->metaData = md;
result->batchSize = batch_size > 0 ? batch_size : 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;
result->lobMode = FBSQL_LOB_DIRECT;
if (tp[0] != 'E')
{
result->columnCount = fbcmdColumnCount(md);
result->fetchHandle = fh;
}
else
{
char* r = fbcmdMessage(result->metaData);
fbcrhConvertToOutputCharSet(fbcdcOutputCharacterSet(link->connection), (unsigned char *)r);
if ((result->list = fbcplParse(r)))
{
result->rowCount = fbcplCount(result->list);
result->columnCount = 7;
}
}
ZEND_REGISTER_RESOURCE(return_value, result, le_result);
}
else if (tp[0] == 'I' || tp[0] == 'U')
{
if (tp[0] == 'I') link->insert_id = fbcmdRowIndex(md);
if (sR == 1 && md) fbcmdRelease(md);
ZVAL_BOOL(return_value, 1)
}
else if(tp[0] == 'A' || tp[0] == 'D')
{
if (sR == 1 && md) fbcmdRelease(md);
ZVAL_BOOL(return_value, 1)
}
if (link) link->affectedRows = fbcmdRowCount(md);
}
}
PHP_FUNCTION(fbsql_query)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **query, **batch_size;
int id, bs = 0;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &query)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &query, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
case 3:
if (zend_get_parameters_ex(3, &query, &fbsql_link_index, &batch_size)==FAILURE) {
RETURN_FALSE;
}
id = -1;
convert_to_long_ex(batch_size);
bs = Z_LVAL_PP(batch_size);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(query);
phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_STRVAL_PP(query), phpLink, bs);
}
PHP_FUNCTION(fbsql_db_query)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **dbname, **query;
int id;
switch (ZEND_NUM_ARGS()) {
case 2:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(2, &dbname, &query)==FAILURE) {
RETURN_FALSE;
}
break;
case 3:
if (zend_get_parameters_ex(3, &dbname, &query, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(query);
convert_to_string_ex(dbname);
if (php_fbsql_select_db(Z_STRVAL_PP(dbname), phpLink TSRMLS_CC)) {
phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, Z_STRVAL_PP(query), phpLink, 0);
} else {
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_list_dbs)
{
PHPFBResult* phpResult;
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
if (phpLink->execHandler == NULL) phpLink->execHandler = fbcehHandlerForHost(phpLink->hostName, 128);
phpResult = emalloc(sizeof(PHPFBResult));
phpResult->link = phpLink;
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;
ZEND_REGISTER_RESOURCE(return_value, phpResult, le_result);
}
PHP_FUNCTION(fbsql_list_tables)
{
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 order by \"table_name\";";
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name;
int id;
char *databaseName;
switch (ZEND_NUM_ARGS()) {
case 1:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(1, &database_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &database_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
if (databaseName == NULL) {
php_fbsql_select_db(FB_SQL_G(databaseName), phpLink TSRMLS_CC);
} else {
php_fbsql_select_db(databaseName, phpLink TSRMLS_CC);
}
phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, sql, phpLink, 0);
}
PHP_FUNCTION(fbsql_list_fields)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL, **database_name, **table_name;
int id;
char *databaseName, *tableName;
char sql[1024];
switch (ZEND_NUM_ARGS()) {
case 2:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
if (zend_get_parameters_ex(2, &database_name, &table_name)==FAILURE) {
RETURN_FALSE;
}
break;
case 3:
if (zend_get_parameters_ex(3, &database_name, &table_name, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
convert_to_string_ex(database_name);
databaseName = Z_STRVAL_PP(database_name);
convert_to_string_ex(table_name);
tableName = Z_STRVAL_PP(table_name);
if (!php_fbsql_select_db(databaseName, phpLink TSRMLS_CC)) {
RETURN_FALSE;
}
if (snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE 1=0;", tableName) < 0) {
RETURN_FALSE;
}
phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, sql, phpLink, 0);
}
PHP_FUNCTION(fbsql_error)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
if (phpLink->errorText == NULL) {
RETURN_FALSE;
}
else {
RETURN_STRING(phpLink->errorText, 1);
}
}
PHP_FUNCTION(fbsql_errno)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
RETURN_LONG(phpLink->errorNo);
}
PHP_FUNCTION(fbsql_warnings)
{
int argc = ZEND_NUM_ARGS();
zval **argv[1];
if ((argc < 0) || (argc > 1)) WRONG_PARAM_COUNT;
if (zend_get_parameters_ex(argc, &argv[0])==FAILURE) RETURN_FALSE;
if (argc >= 1)
{
convert_to_long_ex(argv[0]);
FB_SQL_G(generateWarnings) = Z_LVAL_PP(argv[0]) != 0;
}
RETURN_BOOL(FB_SQL_G(generateWarnings));
}
PHP_FUNCTION(fbsql_affected_rows)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
RETURN_LONG(phpLink->affectedRows);
}
PHP_FUNCTION(fbsql_rows_fetched)
{
PHPFBResult* phpResult = NULL;
zval **result = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &result)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(phpResult, PHPFBResult *, result, id, "FrontBase-Result", le_result);
if (!phpResult->rowHandler) {
RETURN_FALSE;
}
else {
RETURN_LONG(fbcrhRowCount(phpResult->rowHandler));
}
}
PHP_FUNCTION(fbsql_insert_id)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
RETURN_LONG(phpLink->insert_id);
}
int phpSizeOfInt (int i)
{
int s = 1;
if (i < 0)
{
s++;
i = -i;
}
while ((i = i / 10)) s++;
return s;
}
void phpfbColumnAsString(PHPFBResult* result, int column, void* data , int* length, char** value TSRMLS_DC)
{
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);
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];
snprintf(b, sizeof(b), "%d", v);
phpfbestrdup(b, length, value);
}
break;
#ifdef FB_TinyInteger
case FB_TinyInteger:
{
short int v = *((FBTinyInteger*)data);
char b[128];
snprintf(b, sizeof(b), "%d", v);
phpfbestrdup(b, length, value);
}
break;
#endif
#ifdef FB_LongInteger
case FB_LongInteger:
{
FBLongInteger v = *((FBLongInteger*)data);
char b[128];
#ifdef PHP_WIN32
snprintf(b, sizeof(b), "%I64i", v);
#else
snprintf(b, sizeof(b), "%ll", v);
#endif
phpfbestrdup(b, length, value);
}
break;
#endif
case FB_SmallInteger:
{
short v = *((short*)data);
char b[128];
snprintf(b, sizeof(b), "%d", v);
phpfbestrdup(b, length, value);
}
break;
case FB_Float:
case FB_Real:
case FB_Double:
{
double v = *((double*)data);
char b[128];
snprintf(b, sizeof(b), "%F", v);
phpfbestrdup(b, length, value);
}
break;
case FB_Numeric:
case FB_Decimal:
{
unsigned precision = fbcdmdPrecision(dtmd);
unsigned scale = fbcdmdScale(dtmd);
double v = *((double*)data);
char b[128];
snprintf(b, sizeof(b), "%.*F", scale, 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));
if (nBits %8 == 0)
{
unsigned i;
unsigned int l = nBits / 8;
*length = l*2+3+1;
if (value)
{
char* r = safe_emalloc(l, 2, 4);
r[0] = 'X';
r[1] = '\'';
for (i = 0; i < nBits / 8; i++)
{
char c[4];
snprintf(c, sizeof(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*2+3+1;
if (value)
{
char* r = safe_emalloc(l, 2, 4);
r[0] = 'B';
r[1] = '\'';
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_TimestampTZ:
{
char* v = (char*)data;
phpfbestrdup(v, length, value);
}
break;
case FB_Timestamp:
{
char* v = (char*)data;
if (FB_SQL_G(showTimestampDecimals)) {
phpfbestrdup(v, length, value);
}
else {
int stringLength = strlen(v);
stringLength = min(stringLength, 19);
if (value) {
char* r = emalloc(stringLength+1);
memcpy(r, v, stringLength);
r[stringLength] = 0;
*value = r;
}
*length = stringLength;
}
}
break;
case FB_YearMonth:
{
char b[128];
int v = *((unsigned int*)data);
snprintf(b, sizeof(b), "%d", v);
phpfbestrdup(b, length, value);
}
break;
case FB_DayTime:
{
char b[128];
double seconds = *((double*)data);
snprintf(b, sizeof(b), "%F", seconds);
phpfbestrdup(b, length, value);
}
break;
case FB_CLOB:
case FB_BLOB:
{
if (*((unsigned char*) data) == '\1')
{
*length = ((FBCBlobDirect *)data)->blobSize;
*value = estrndup((char *)((FBCBlobDirect *)data)->blobData, *length);
}
else
{
FBCBlobHandle *lobHandle;
unsigned char *bytes = (unsigned char *)data;
char *handle = (char *)(&bytes[1]);
lobHandle = fbcbhInitWithHandle(handle);
*length = fbcbhBlobSize(lobHandle);
if (result->lobMode == FBSQL_LOB_HANDLE) {
phpfbestrdup(fbcbhDescription(lobHandle), length, value);
}
else {
if (dtc == FB_BLOB)
*value = estrndup((char *)fbcdcReadBLOB(result->link->connection, lobHandle), *length);
else
*value = estrndup((char *)fbcdcReadCLOB(result->link->connection, lobHandle), *length);
}
fbcbhRelease(lobHandle);
}
}
break;
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unimplemented type (%d)", dtc);
break;
}
}
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);
if (columnIndex == 0)
{
FBCPList* name = (FBCPList*)fbcplValueForKey(column, "NAME");
RETURN_STRING((char *)fbcplString((FBCPList*)name), 1);
}
else if (columnIndex == 2)
{
FBCPList* name = (FBCPList*)fbcplValueForKey(column, "WIDTH");
RETURN_STRING((char *)fbcplString((FBCPList*)name), 1);
}
else if (columnIndex == 1)
{
FBCPList* name = (FBCPList*)fbcplValueForKey(column, "DATATYPE");
RETURN_STRING((char *)fbcplString((FBCPList*)name), 1);
}
else if (columnIndex == 3)
{
RETURN_STRING("", 1);
}
else
{
RETURN_STRING("", 1);
}
}
else if (result->array)
{
RETURN_STRING(fbaObjectAtIndex(result->array, rowIndex), 1);
}
else if (!phpfbFetchRow(result, rowIndex))
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such row %d in result set %d", rowIndex, rowIndex);
RETURN_FALSE;
}
else if (columnIndex >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, 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], &Z_STRLEN_P(return_value), &Z_STRVAL_P(return_value) TSRMLS_CC);
Z_TYPE_P(return_value) = IS_STRING;
}
else
{
RETURN_NULL();
}
}
}
PHP_FUNCTION(fbsql_result)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **row = NULL, **field = NULL;
int rowIndex;
int columnIndex;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &row)==FAILURE) {
RETURN_FALSE;
}
break;
case 3:
if (zend_get_parameters_ex(3, &fbsql_result_index, &row, &field)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
rowIndex = result->rowIndex;
if (row)
{
convert_to_long_ex(row);
rowIndex = Z_LVAL_PP(row);
}
columnIndex = result->columnIndex;
if (field)
{
if ((Z_TYPE_PP(field) == IS_STRING) && (result->metaData))
{
for (columnIndex =0; columnIndex < result->columnCount; columnIndex ++)
{
const FBCColumnMetaData* cmd = fbcmdColumnMetaDataAtIndex(result->metaData, columnIndex);
const char* lbl = fbccmdLabelName(cmd);
if (strcmp((char*)lbl, Z_STRVAL_PP(field)) == 0) break;
}
if (columnIndex == result->columnCount) RETURN_FALSE;
}
else
{
convert_to_long_ex(field);
columnIndex = Z_LVAL_PP(field);
if (columnIndex < 0)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal column index - %d", columnIndex);
RETURN_FALSE;
}
}
}
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU, result, rowIndex, columnIndex);
result->columnIndex++;
if (result->columnIndex == result->columnCount)
{
result->rowIndex++;
result->columnIndex = 0;
}
}
PHP_FUNCTION(fbsql_next_result)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
result->currentResult++;
if (result->currentResult < result->selectResults) {
if (result->fetchHandle) {
FBCMetaData *md = fbcdcCancelFetch(result->link->connection, result->fetchHandle);
fbcmdRelease(md);
}
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->link)
result->link->affectedRows = fbcmdRowCount(result->metaData);
RETURN_TRUE;
}
else {
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_num_rows)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL;
int rowCount;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
if (result->array)
rowCount = result->rowCount;
else {
rowCount = fbcmdRowCount(result->metaData);
if (rowCount == -1)
{
phpfbFetchRow(result, 0x7fffffff);
rowCount = result->rowCount;
}
}
RETURN_LONG(rowCount);
}
PHP_FUNCTION(fbsql_num_fields)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
RETURN_LONG(result->columnCount);
}
PHP_FUNCTION(fbsql_fetch_row)
{
php_fbsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FBSQL_NUM, 1);
}
PHP_FUNCTION(fbsql_fetch_assoc)
{
php_fbsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FBSQL_ASSOC, 1);
}
PHP_FUNCTION(fbsql_fetch_object)
{
php_fbsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FBSQL_ASSOC, 2);
if (Z_TYPE_P(return_value)==IS_ARRAY) {
object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
}
}
PHP_FUNCTION(fbsql_fetch_array)
{
php_fbsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, FBSQL_BOTH, 2);
}
static void _parse_list(zval** return_value, FBCPList* list)
{
int count = fbcplCount(list);
int i,j;
for (i=0; i<count; i++)
{
char* key = (char*)fbcplKeyAtIndex(list, i);
FBCPList* value = (FBCPList*)fbcplValueForKey(list, key);
if (fbcplIsDictionary(value))
{
zval *value_array;
MAKE_STD_ZVAL(value_array);
array_init(value_array);
_parse_list(&value_array, value);
add_assoc_zval(*return_value, key, value_array);
}
else if (fbcplIsArray(value))
{
zval *value_array;
int valcount = fbcplCount(value);
MAKE_STD_ZVAL(value_array);
array_init(value_array);
for (j=0; j<valcount; j++)
{
FBCPList* arrayValue = (FBCPList*)fbcplValueAtIndex(value, j);
if (fbcplIsString(arrayValue))
add_index_string(value_array, j, (char*)fbcplString(arrayValue), 1);
else {
_parse_list(&value_array, arrayValue);
}
}
add_assoc_zval(*return_value, key, value_array);
}
else if (fbcplIsString(value)) {
add_assoc_string(*return_value, key, (char*)fbcplString(value), 1);
}
}
}
static void php_fbsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type, int expected_args)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **zresult_type = NULL;
int rowIndex;
int i;
void **row;
if (ZEND_NUM_ARGS() > expected_args) {
WRONG_PARAM_COUNT;
}
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &zresult_type)==FAILURE) {
RETURN_FALSE;
}
convert_to_long_ex(zresult_type);
result_type = Z_LVAL_PP(zresult_type);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
rowIndex = result->rowIndex;
if (((result_type & FBSQL_NUM) != FBSQL_NUM) && ((result_type & FBSQL_ASSOC) != FBSQL_ASSOC))
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal result type use FBSQL_NUM, FBSQL_ASSOC, or FBSQL_BOTH");
RETURN_FALSE;
}
array_init(return_value);
if (result->fetchHandle == NULL)
{
if (result->array == NULL && result->list == NULL)
{
RETURN_FALSE;
}
if (result->rowIndex >= result->rowCount)
{
RETURN_FALSE;
}
if (result->list) {
char* key;
FBCPList* value;
value = (FBCPList*)fbcplValueAtIndex(result->list, result->rowIndex);
key = (char*)fbcplKeyAtIndex(result->list, result->rowIndex);
if (key && key[0] == 2)
key = NULL;
if (fbcplIsDictionary(value)) {
zval *value_array;
MAKE_STD_ZVAL(value_array);
array_init(value_array);
_parse_list(&value_array, value);
if (result_type & FBSQL_NUM || key == NULL)
{
add_index_zval(return_value, 0, value_array);
}
if (result_type & FBSQL_ASSOC && key != NULL)
{
add_assoc_zval(return_value, key, value_array);
}
}
else if (fbcplIsArray(value)) {
zval *value_array;
int valcount = fbcplCount(value);
int j;
MAKE_STD_ZVAL(value_array);
array_init(value_array);
for (j=0; j<valcount; j++)
{
FBCPList* arrayValue = (FBCPList*)fbcplValueAtIndex(value, j);
if (fbcplIsString(arrayValue))
add_index_string(value_array, j, (char*)fbcplString(arrayValue), 1);
else {
_parse_list(&value_array, arrayValue);
}
}
if (result_type & FBSQL_NUM || key == NULL)
{
add_index_zval(return_value, 0, value_array);
}
if (result_type & FBSQL_ASSOC && key != NULL)
{
add_assoc_zval(return_value, key, value_array);
}
}
else if (fbcplIsString(value)) {
if (result_type & FBSQL_NUM)
{
add_index_string(return_value, 0, (char*)fbcplString(value), 1);
}
if (result_type & FBSQL_ASSOC)
{
add_assoc_string(return_value, key, (char*)fbcplString(value), 1);
}
}
}
else {
if (result_type & FBSQL_NUM)
{
add_index_string(return_value, 0, estrdup(fbaObjectAtIndex(result->array, result->rowIndex)), 0);
}
if (result_type & FBSQL_ASSOC)
{
add_assoc_string(return_value, "Database", estrdup(fbaObjectAtIndex(result->array, result->rowIndex)), 0);
}
}
}
else {
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;
}
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 TSRMLS_CC);
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->columnIndex = 0;
}
PHP_FUNCTION(fbsql_data_seek)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **row_number = NULL;
unsigned int rowIndex;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &row_number)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
convert_to_long_ex(row_number);
rowIndex = Z_LVAL_PP(row_number);
if (rowIndex < 0)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal row_index (%d)", rowIndex);
RETURN_FALSE;
}
if (result->rowCount == 0x7fffffff) phpfbFetchRow(result, rowIndex);
if (rowIndex > result->rowCount) RETURN_FALSE;
result->rowIndex = rowIndex;
result->columnIndex = 0;
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_fetch_lengths)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL;
int i;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
if (result->row == NULL) RETURN_FALSE;
array_init(return_value);
for (i=0; i < result->columnCount; i++)
{
unsigned length = 0;
if (result->row[i]) phpfbColumnAsString(result, i, result->row[i], &length, NULL TSRMLS_CC);
add_index_long(return_value, i, length);
}
}
PHP_FUNCTION(fbsql_fetch_field)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d no such column in result", column);
RETURN_FALSE;
}
}
object_init(return_value);
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);
add_property_long(return_value, "not_null", !fbccmdIsNullable(fbcmdColumnMetaDataAtIndex(result->metaData, column)));
}
PHP_FUNCTION(fbsql_field_seek)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d no such column in result", column);
RETURN_FALSE;
}
}
result->columnIndex = column;
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_field_name)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d no such column in result", column);
RETURN_FALSE;
}
}
if (result->list)
{
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU, result, result->rowIndex, 0);
}
else if (result->metaData)
{
RETURN_STRING((char *)fbccmdLabelName(fbcmdColumnMetaDataAtIndex(result->metaData, column)), 1);
result->columnIndex = column;
}
}
PHP_FUNCTION(fbsql_field_table)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d no such column in result", column);
RETURN_FALSE;
}
}
RETURN_STRING((char *)fbccmdTableName(fbcmdColumnMetaDataAtIndex(result->metaData, column)), 1);
}
PHP_FUNCTION(fbsql_field_len)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d no such column in result", column);
RETURN_FALSE;
}
}
if (result->list)
{
phpfbSqlResult(INTERNAL_FUNCTION_PARAM_PASSTHRU, result, result->rowIndex, 2);
}
else if (result->metaData)
{
RETURN_LONG(fbcdmdLength(fbccmdDatatype(fbcmdColumnMetaDataAtIndex(result->metaData, column))));
}
else
{
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_field_type)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, 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)
{
RETURN_STRING((char *)fbcdmdDatatypeString (fbcmdDatatypeMetaDataAtIndex(result->metaData, column)), 1);
}
else
{
RETURN_FALSE;
}
}
PHP_FUNCTION(fbsql_field_flags)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **field_index = NULL;
int column = -1;
char buf[512];
int len;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &field_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
column = result->columnIndex;
if (field_index)
{
convert_to_long_ex(field_index);
column = Z_LVAL_PP(field_index);
if (column < 0 || column >= result->columnCount)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d no such column in result", column);
RETURN_FALSE;
}
}
strcpy(buf, "");
if (!fbccmdIsNullable(fbcmdColumnMetaDataAtIndex(result->metaData, column))) {
strcat(buf, "not_null ");
}
#if 0
if (IS_PRI_KEY(fbsql_field->flags)) {
strcat(buf, "primary_key ");
}
if (fbsql_field->flags&UNIQUE_KEY_FLAG) {
strcat(buf, "unique_key ");
}
if (fbsql_field->flags&MULTIPLE_KEY_FLAG) {
strcat(buf, "multiple_key ");
}
if (IS_BLOB(fbsql_field->flags)) {
strcat(buf, "blob ");
}
if (fbsql_field->flags&UNSIGNED_FLAG) {
strcat(buf, "unsigned ");
}
if (fbsql_field->flags&ZEROFILL_FLAG) {
strcat(buf, "zerofill ");
}
if (fbsql_field->flags&BINARY_FLAG) {
strcat(buf, "binary ");
}
if (fbsql_field->flags&ENUM_FLAG) {
strcat(buf, "enum ");
}
if (fbsql_field->flags&AUTO_INCREMENT_FLAG) {
strcat(buf, "auto_increment ");
}
if (fbsql_field->flags&TIMESTAMP_FLAG) {
strcat(buf, "timestamp ");
}
#endif
len = strlen(buf);
if (len && buf[len-1] == ' ') {
buf[len-1] = 0;
len--;
}
RETURN_STRING(buf, 1);
}
PHP_FUNCTION(fbsql_table_name)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL, **table_index;
unsigned index;
char* value;
unsigned int length;
void** row;
switch (ZEND_NUM_ARGS()) {
case 2:
if (zend_get_parameters_ex(2, &fbsql_result_index, &table_index)==FAILURE) {
RETURN_FALSE;
}
convert_to_long_ex(table_index);
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
index = Z_LVAL_PP(table_index);
if (index < 0)
{
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal index (%i)", index);
RETURN_FALSE;
}
if (result->rowCount == 0x7fffffff) phpfbFetchRow(result, index);
if (index > result->rowCount) RETURN_FALSE;
result->rowIndex = index;
result->columnIndex = 0;
row = fbcrhRowAtIndex(result->rowHandler, index);
phpfbColumnAsString(result, 0, row[0], &length, &value TSRMLS_CC);
RETURN_STRINGL(value, length, 1);
}
PHP_FUNCTION(fbsql_free_result)
{
PHPFBResult* result = NULL;
zval **fbsql_result_index = NULL;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_get_parameters_ex(1, &fbsql_result_index)==FAILURE) {
RETURN_FALSE;
}
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE(result, PHPFBResult *, fbsql_result_index, -1, "FrontBase-Result", le_result);
zend_list_delete(Z_LVAL_PP(fbsql_result_index));
RETURN_TRUE;
}
PHP_FUNCTION(fbsql_get_autostart_info)
{
PHPFBLink* phpLink = NULL;
zval **fbsql_link_index = NULL;
int id;
FBCAutoStartInfo* asInfo;
switch (ZEND_NUM_ARGS()) {
case 0:
id = php_fbsql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
CHECK_LINK(id);
break;
case 1:
if (zend_get_parameters_ex(1, &fbsql_link_index)==FAILURE) {
RETURN_FALSE;
}
id = -1;
break;
default:
WRONG_PARAM_COUNT;
break;
}
ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, id, "FrontBase-Link", le_link, le_plink);
if (phpLink->execHandler == NULL) phpLink->execHandler = fbcehHandlerForHost(phpLink->hostName, 128);
if (phpLink->execHandler == NULL) {
if (FB_SQL_G(generateWarnings))
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No valid Exec handler available for this connection");
RETURN_FALSE;
}
else {
array_init(return_value);
asInfo = fbcehGetAutoStartInfo(phpLink->execHandler);
if (asInfo != NULL) {
unsigned i;
for (i=0; i<fbaCount(asInfo->infoLines); i++) {
FBArray* infoLine = fbaObjectAtIndex(asInfo->infoLines, i);
add_index_string(return_value, i, fbaObjectAtIndex(infoLine, 0), 1);
}
}
}
}
#endif