📄 php_fbsql.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http:/*www.php.net/license/2_02.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Frank M. Kromann <frank@kromann.info> | +----------------------------------------------------------------------+ *//* $Id: php_fbsql.c,v 1.86.2.14.2.2 2007/01/01 09:46:41 sebastian Exp $ *//* TODO: * * ? Safe mode implementation *//* SB's list: - API for a more natural FB connect semantic - Connect & set session - Autoreconnect when disconnected - Comments and cleanup BUGS - Select db with no arguments - Query with everything defaulted*/#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 <winsock.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#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;/* The PHPFBLink structure represents a fbsql link. The lion is used for a connection to a machine, it may be persistent and is reference counted. The reason for refcounting is mostly to avoid to think, it work independent of any wierd and unforseen allocation deallocation order. The PHPFBDatabse structure implements to actual connection to a FrontBase server ot may be persistent is the link it is connected to is persistent, and refcounted for the same reasons as above. The PHPFBResult structure implements a result from the FrontBase server, and does all required buffereing from of results. In the PHP code the 3 above a data structures are referenced by means of integers in the range from 1 to som configurable maximum. You can put a limit to the number of links, databases and results. The integer identifications is implemented by insertion in the list, which is passed as an argument to all the functions, please note the list is polymorph. Database objects and link objects are all reused, base on the host name user name, host name database name user name. So connecting twice to the same database as the same user will return the same database id. We use the same coding for that as fbsql does, explioiting the underlying implementation of the lists. Persistent objects are put in the persistent list as well, but only by name, if you connect to a persistent object and it is not in the list it is simply added and get a new index, and refcounted. Tricky, tricky ...*//* Some functions which should be exported from FBCAccess */void* fbaObjectAtIndex();void fbaRelease();unsigned int fbaCount();struct FBCAutoStartInfo { FBArray* infoLines;};struct PHPFBResult{ PHPFBLink* link; /* The link for the result, may be NULL if no link */ char* fetchHandle; /* The fetch handle, the id used by the server. */ FBCMetaData* metaData; /* The metadata describing the result */ FBCMetaData* ResultmetaData; /* The metadata describing the result */ FBCRowHandler* rowHandler; /* The row handler, the Frontbase structure used for accessing rows in the result */ unsigned int batchSize; /* The number of row to fetch when expanding the number of rows in the row handler */ unsigned int rowCount; /* The number of rows in the results set. The number of row is not in */ /* general known when the select is done, one typically needs to fetch all the row to figure out how many row you got. When the rowCount is unknown the value is 0x7ffffffff */ int columnCount; /* Number of columns in the row set. */ unsigned int rowIndex; /* The current row index. */ int columnIndex; /* The current column index */ void** row; /* The last row accessed */ FBArray* array; /* The link may return a result set, the database list, we implement that by the */ /* FBArray, just a list of strings. */ FBCPList* list; /* The same special kind result just for property list from extract, schema info. */ unsigned int selectResults; /* number of results in select */ unsigned int currentResult; /* current result number */ int lobMode; /* 0=Fetch data (default); 1=Fetch handle */};struct PHPFBLink{ int persistent; /* persistent ? */ char* hostName; /* Host name */ char* userName; /* User name */ char* userPassword; /* User password */ char* databasePassword; /* Database password */ char* databaseName; /* The name of the database */ FBCExecHandler* execHandler; /* The exechandler, can be used for database operations */ FBCDatabaseConnection* connection; /* The connection to the database */ unsigned int affectedRows; /* Number of rows affected by the last SQL statement */ long autoCommit; /* Enable or disable autoCommit */ unsigned int errorNo; /* The latest error on the connection, 0 is ok. */ char* errorText; /* The error text */ unsigned int insert_id; /* The row index of the latest row inserted into the database */};#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 /* default */#define FBSQL_ISO_READ_UNCOMMITTED 0#define FBSQL_ISO_READ_COMMITTED 1#define FBSQL_ISO_REPEATABLE_READ 2#define FBSQL_ISO_SERIALIZABLE 3 /* default */#define FBSQL_ISO_VERSIONED 4#define FBSQL_LOB_DIRECT 0 /* default */#define FBSQL_LOB_HANDLE 1 /* default *//* {{{ fbsql_functions[] */function_entry fbsql_functions[] = { PHP_FE(fbsql_connect, NULL) PHP_FE(fbsql_pconnect, NULL) PHP_FE(fbsql_close, NULL) PHP_FE(fbsql_select_db, NULL) PHP_FE(fbsql_create_db, NULL) PHP_FE(fbsql_drop_db, NULL) PHP_FE(fbsql_start_db, NULL) PHP_FE(fbsql_stop_db, NULL) PHP_FE(fbsql_db_status, NULL) PHP_FE(fbsql_query, NULL) PHP_FE(fbsql_db_query, NULL) PHP_FE(fbsql_list_dbs, NULL) PHP_FE(fbsql_list_tables, NULL) PHP_FE(fbsql_list_fields, NULL) PHP_FE(fbsql_error, NULL) PHP_FE(fbsql_errno, NULL) PHP_FE(fbsql_affected_rows, NULL) PHP_FE(fbsql_insert_id, NULL) PHP_FE(fbsql_result, NULL) PHP_FE(fbsql_next_result, NULL) PHP_FE(fbsql_num_rows, NULL) PHP_FE(fbsql_num_fields, NULL) PHP_FE(fbsql_fetch_row, NULL) PHP_FE(fbsql_fetch_array, NULL) PHP_FE(fbsql_fetch_assoc, NULL) PHP_FE(fbsql_fetch_object, NULL) PHP_FE(fbsql_data_seek, NULL) PHP_FE(fbsql_fetch_lengths, NULL) PHP_FE(fbsql_fetch_field, NULL) PHP_FE(fbsql_field_seek, NULL) PHP_FE(fbsql_free_result, NULL) PHP_FE(fbsql_field_name, NULL) PHP_FE(fbsql_field_table, NULL) PHP_FE(fbsql_field_len, NULL) PHP_FE(fbsql_field_type, NULL) PHP_FE(fbsql_field_flags, NULL) PHP_FE(fbsql_table_name, NULL) /* Fontbase additions: */ PHP_FE(fbsql_set_transaction, NULL) PHP_FE(fbsql_autocommit, NULL) PHP_FE(fbsql_commit, NULL) PHP_FE(fbsql_rollback, NULL) PHP_FE(fbsql_create_blob, NULL) PHP_FE(fbsql_create_clob, NULL) PHP_FE(fbsql_set_lob_mode, NULL) PHP_FE(fbsql_read_blob, NULL) PHP_FE(fbsql_read_clob, NULL) PHP_FE(fbsql_blob_size, NULL) PHP_FE(fbsql_clob_size, NULL) PHP_FE(fbsql_hostname, NULL) PHP_FE(fbsql_database, NULL) PHP_FE(fbsql_database_password, NULL) PHP_FE(fbsql_username, NULL) PHP_FE(fbsql_password, NULL) PHP_FE(fbsql_warnings, NULL) PHP_FE(fbsql_get_autostart_info, NULL)/* PHP_FE(fbsql_set_autostart_info, NULL) *//* Aliases: */ PHP_FALIAS(fbsql, fbsql_db_query, NULL) PHP_FALIAS(fbsql_tablename, fbsql_table_name, NULL) {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, STANDARD_MODULE_PROPERTIES};ZEND_DECLARE_MODULE_GLOBALS(fbsql)#ifdef COMPILE_DL_FBSQLZEND_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->ResultmetaData) fbcmdRelease(result->ResultmetaData); if (result->list) fbcplRelease(result->list); if (result->array) fbaRelease(result->array); 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) { /* no link opened yet, implicitly open one */ 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);/* {{{ PHP_INI */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_ENTRY_EX ("fbsql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateInt, maxPersistent, zend_fbsql_globals, fbsql_globals, display_link_numbers) STD_PHP_INI_ENTRY_EX ("fbsql.max_links", "128", PHP_INI_SYSTEM, OnUpdateInt, maxLinks, zend_fbsql_globals, fbsql_globals, display_link_numbers) STD_PHP_INI_ENTRY_EX ("fbsql.max_connections", "128", PHP_INI_SYSTEM, OnUpdateInt, maxConnections, zend_fbsql_globals, fbsql_globals, display_link_numbers) STD_PHP_INI_ENTRY_EX ("fbsql.max_results", "128", PHP_INI_SYSTEM, OnUpdateInt, maxResults, zend_fbsql_globals, fbsql_globals, display_link_numbers) STD_PHP_INI_ENTRY_EX ("fbsql.batchSize", "1000", PHP_INI_SYSTEM, OnUpdateInt, batchSize, zend_fbsql_globals, fbsql_globals, display_link_numbers) STD_PHP_INI_ENTRY ("fbsql.default_host", NULL, PHP_INI_SYSTEM, OnUpdateString, hostName, zend_fbsql_globals, fbsql_globals) STD_PHP_INI_ENTRY ("fbsql.default_user", "_SYSTEM", PHP_INI_SYSTEM, OnUpdateString, userName, zend_fbsql_globals, fbsql_globals) STD_PHP_INI_ENTRY ("fbsql.default_password", "", PHP_INI_SYSTEM, OnUpdateString, userPassword, zend_fbsql_globals, fbsql_globals) STD_PHP_INI_ENTRY ("fbsql.default_database", "", PHP_INI_SYSTEM, OnUpdateString, databaseName, zend_fbsql_globals, fbsql_globals) STD_PHP_INI_ENTRY ("fbsql.default_database_password", "", PHP_INI_SYSTEM, OnUpdateString, databasePassword, zend_fbsql_globals, fbsql_globals)PHP_INI_END()/* }}} */ static void php_fbsql_init_globals(zend_fbsql_globals *fbsql_globals){ fbsql_globals->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){ ZEND_INIT_MODULE_GLOBALS(fbsql, php_fbsql_init_globals, NULL); 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 Transaction constants */ 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 Status constants */ 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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -