mirror of
https://github.com/php/php-src.git
synced 2024-11-26 11:23:47 +08:00
4713 lines
134 KiB
Plaintext
4713 lines
134 KiB
Plaintext
/*
|
|
+----------------------------------------------------------------------+
|
|
| PHP Version 5 |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 1997-2004 The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.0 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/3_0.txt. |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Authors: Danny Heijl <Danny.Heijl@cevi.be> : initial cut (ODS 7.2x) |
|
|
| PHP 4 port |
|
|
| Christian Cartus <chc@idgruppe.de> : blobs, and IUS 9 |
|
|
| Jouni Ahto <jouni.ahto@exdec.fi> : configuration stuff |
|
|
| Corne' Cornelius <cornec@reach.co.za> : input descriptors |
|
|
| Based on the MySQL code by: Zeev Suraski <zeev@php.net> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
/* $Id$ */
|
|
|
|
/* -------------------------------------------------------------------
|
|
* if you want a function reference : "grep '^\*\*' ifx.ec" will give
|
|
* you a very short one
|
|
* -------------------------------------------------------------------
|
|
*/
|
|
|
|
/* TODO:
|
|
*
|
|
* ? Safe mode implementation
|
|
*/
|
|
|
|
/* prevent mod_ssl.h's header file from being included. */
|
|
#define AP_HOOK_H
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "php.h"
|
|
#include "php_globals.h"
|
|
#include "ext/standard/php_standard.h"
|
|
#include "php_open_temporary_file.h"
|
|
#include "php_informix.h"
|
|
#include "php_informix_includes.h"
|
|
#include "php_globals.h"
|
|
#include "php_ini.h"
|
|
|
|
#ifdef PHP_WIN32
|
|
#include <winsock.h>
|
|
#endif
|
|
|
|
#ifdef ZTS
|
|
#define IFX_THRD_ID tsrm_thread_id()
|
|
#else
|
|
#define IFX_THRD_ID 0
|
|
#endif
|
|
|
|
#if HAVE_SYS_TYPES_H
|
|
#include <sys/types.h>
|
|
#endif
|
|
|
|
#if HAVE_NETDB_H
|
|
#include <netdb.h>
|
|
#endif
|
|
|
|
#if HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
#if HAVE_IFX
|
|
|
|
/* local function prototypes */
|
|
static void php_ifx_set_default_link(int id TSRMLS_DC);
|
|
static long php_intifx_getType(long id, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_create_blob(long type, long mode, char* param, long len, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_init_blob(loc_t *blob, long mode, long new TSRMLS_DC);
|
|
static long php_intifx_init_blob_inmem(loc_t *blob, long new TSRMLS_DC);
|
|
static long php_intifx_init_blob_infile(loc_t *blob, long new TSRMLS_DC);
|
|
static void php_intifx_release_blob(loc_t *blob TSRMLS_DC);
|
|
static long php_intifx_free_blob(long id, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_get_blob(long bid, HashTable *list, char** content TSRMLS_DC);
|
|
static long php_intifx_update_blob(long bid, char* param, long len, HashTable *list TSRMLS_DC);
|
|
static loc_t *php_intifx_get_blobloc(long bid, HashTable *list TSRMLS_DC);
|
|
static char* php_intifx_create_tmpfile(TSRMLS_D);
|
|
static long php_intifx_copy_blob(long bid, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_alloc_ibind(IFX_RES *Ifx_Result, int items TSRMLS_DC);
|
|
static long php_intifx_preparse(char *statement TSRMLS_DC);
|
|
static long php_intifx_count_descriptors(char *p_statemid TSRMLS_DC);
|
|
static char* php_intifx_null(TSRMLS_D);
|
|
static long php_intifx_create_char(char* param, long len, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_free_char(long id, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_update_char(long bid, char* param, long len, HashTable *list TSRMLS_DC);
|
|
static long php_intifx_get_char(long bid, HashTable *list, char** content TSRMLS_DC);
|
|
#if HAVE_IFX_IUS
|
|
static long php_intifxus_create_slob(long create_mode, HashTable *list TSRMLS_DC);
|
|
static long php_intifxus_free_slob(long bid, HashTable *list TSRMLS_DC);
|
|
static long php_intifxus_close_slob(long bid, HashTable *list TSRMLS_DC);
|
|
static long php_intifxus_open_slob(long bid, long create_mode, HashTable *list TSRMLS_DC);
|
|
static long php_intifxus_new_slob(HashTable *list TSRMLS_DC);
|
|
static ifx_lo_t *php_intifxus_get_slobloc(long bid, HashTable *list TSRMLS_DC);
|
|
#endif
|
|
|
|
/* 7.10 on (at least) AIX is missing this */
|
|
#ifndef CLIENT_SQLI_VER
|
|
#define CLIENT_SQLI_VER IFX_VERSION
|
|
#endif
|
|
|
|
#define TYPE_BLBYTE 0
|
|
#define TYPE_BLTEXT 1
|
|
#define TYPE_SLOB 2
|
|
#define TYPE_CHAR 3
|
|
|
|
#define BLMODE_INMEM 0
|
|
#define BLMODE_INFILE 1
|
|
|
|
#define IFX_SCROLL 1
|
|
#define IFX_HOLD 2
|
|
|
|
EXEC SQL include locator;
|
|
EXEC SQL include sqltypes;
|
|
EXEC SQL include sqlstype;
|
|
|
|
#include <errno.h>
|
|
|
|
typedef char IFX[128];
|
|
#define SAFE_STRING(s) ((s) ? (s) : "")
|
|
#define PHP_IFX_CHECK_CONNECTION(ifx) \
|
|
do { \
|
|
if (ifx_check() < 0) { \
|
|
char *ifx_err = ifx_error(ifx); \
|
|
IFXG(sv_sqlcode) = SQLCODE; \
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Set connection %s fails (%s)", ifx, ifx_err); \
|
|
efree(ifx_err); \
|
|
RETURN_FALSE; \
|
|
} \
|
|
} while (0)
|
|
|
|
function_entry ifx_functions[] = {
|
|
PHP_FE(ifx_connect, NULL)
|
|
PHP_FE(ifx_pconnect, NULL)
|
|
PHP_FE(ifx_close, NULL)
|
|
PHP_FE(ifx_query, NULL)
|
|
PHP_FE(ifx_prepare, NULL)
|
|
PHP_FE(ifx_do, NULL)
|
|
PHP_FE(ifx_error, NULL)
|
|
PHP_FE(ifx_errormsg, NULL)
|
|
PHP_FE(ifx_affected_rows, NULL)
|
|
PHP_FE(ifx_num_rows, NULL)
|
|
PHP_FE(ifx_num_fields, NULL)
|
|
PHP_FE(ifx_fetch_row, NULL)
|
|
PHP_FE(ifx_free_result, NULL)
|
|
PHP_FE(ifx_htmltbl_result, NULL)
|
|
PHP_FE(ifx_fieldtypes, NULL)
|
|
PHP_FE(ifx_fieldproperties, NULL)
|
|
PHP_FE(ifx_getsqlca, NULL)
|
|
|
|
PHP_FE(ifx_create_blob, NULL)
|
|
PHP_FE(ifx_free_blob, NULL)
|
|
PHP_FE(ifx_get_blob, NULL)
|
|
PHP_FE(ifx_update_blob, NULL)
|
|
PHP_FE(ifx_copy_blob, NULL)
|
|
PHP_FE(ifx_textasvarchar, NULL)
|
|
PHP_FE(ifx_byteasvarchar, NULL)
|
|
PHP_FE(ifx_nullformat, NULL)
|
|
PHP_FE(ifx_blobinfile_mode, NULL)
|
|
|
|
PHP_FE(ifx_create_char, NULL)
|
|
PHP_FE(ifx_free_char, NULL)
|
|
PHP_FE(ifx_get_char, NULL)
|
|
PHP_FE(ifx_update_char, NULL)
|
|
|
|
$ifdef HAVE_IFX_IUS;
|
|
PHP_FE(ifxus_create_slob, NULL)
|
|
PHP_FE(ifxus_close_slob, NULL)
|
|
PHP_FE(ifxus_open_slob, NULL)
|
|
PHP_FE(ifxus_free_slob, NULL)
|
|
PHP_FE(ifxus_read_slob, NULL)
|
|
PHP_FE(ifxus_write_slob, NULL)
|
|
PHP_FE(ifxus_seek_slob, NULL)
|
|
PHP_FE(ifxus_tell_slob, NULL)
|
|
$endif;
|
|
|
|
{NULL,NULL,NULL}
|
|
};
|
|
|
|
zend_module_entry ifx_module_entry = {
|
|
STANDARD_MODULE_HEADER,
|
|
"informix",
|
|
ifx_functions,
|
|
PHP_MINIT(ifx),
|
|
PHP_MSHUTDOWN(ifx),
|
|
PHP_RINIT(ifx),
|
|
NULL,
|
|
PHP_MINFO(ifx),
|
|
NO_VERSION_YET,
|
|
STANDARD_MODULE_PROPERTIES
|
|
};
|
|
|
|
ZEND_DECLARE_MODULE_GLOBALS(ifx)
|
|
|
|
#ifdef COMPILE_DL_INFORMIX
|
|
ZEND_GET_MODULE(ifx)
|
|
#endif
|
|
|
|
/* True globals, no need for thread safety */
|
|
static int le_link, le_plink, le_result, le_idresult;
|
|
|
|
#define DUP 1
|
|
|
|
EXEC SQL DEFINE IFX_SUCCESS 0;
|
|
EXEC SQL DEFINE IFX_WARNING 1;
|
|
EXEC SQL DEFINE IFX_ERROR -1;
|
|
EXEC SQL DEFINE IFX_NODATA 100;
|
|
|
|
static int ifx_check()
|
|
{
|
|
int _ifx_check;
|
|
|
|
_ifx_check = IFX_ERROR;
|
|
|
|
if (SQLSTATE[0] == '0') {
|
|
switch (SQLSTATE[1]) {
|
|
case '0':
|
|
_ifx_check = IFX_SUCCESS;
|
|
break;
|
|
case '1':
|
|
_ifx_check = IFX_WARNING;
|
|
break;
|
|
case '2':
|
|
_ifx_check = IFX_NODATA;
|
|
break;
|
|
default :
|
|
_ifx_check = IFX_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
return _ifx_check;
|
|
}
|
|
|
|
static char *ifx_error(ifx)
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
PARAMETER char *ifx;
|
|
EXEC SQL END DECLARE SECTION;
|
|
{
|
|
char *ifx_err_msg;
|
|
char c;
|
|
int errorcode;
|
|
TSRMLS_FETCH();
|
|
|
|
if (IFXG(sv_sqlcode) == 0) {
|
|
errorcode = SQLCODE;
|
|
} else {
|
|
errorcode = IFXG(sv_sqlcode);
|
|
}
|
|
|
|
switch (ifx_check()) {
|
|
case IFX_SUCCESS:
|
|
c = ' ';
|
|
break;
|
|
case IFX_WARNING:
|
|
c = 'W';
|
|
break;
|
|
case IFX_ERROR:
|
|
c = 'E';
|
|
break;
|
|
case IFX_NODATA:
|
|
c = 'N';
|
|
break;
|
|
default:
|
|
c = '?';
|
|
break;
|
|
}
|
|
|
|
ifx_err_msg = emalloc(64);
|
|
sprintf(ifx_err_msg, "%c [SQLSTATE=%c%c %c%c%c SQLCODE=%d]",
|
|
c,
|
|
SQLSTATE[0],
|
|
SQLSTATE[1],
|
|
SQLSTATE[2],
|
|
SQLSTATE[3],
|
|
SQLSTATE[4],
|
|
errorcode
|
|
);
|
|
|
|
return(ifx_err_msg);
|
|
}
|
|
|
|
static void ifx_do_close(link)
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
PARAMETER char *link;
|
|
EXEC SQL END DECLARE SECTION;
|
|
{
|
|
char *ifx_err = NULL;
|
|
TSRMLS_FETCH();
|
|
|
|
EXEC SQL SET CONNECTION :link;
|
|
|
|
if (ifx_check() >= 0) {
|
|
EXEC SQL DISCONNECT :link;
|
|
|
|
/* check if were in a transaction */
|
|
if (SQLCODE == -1800) {
|
|
EXEC SQL SET CONNECTION :link;
|
|
EXEC SQL ROLLBACK WORK;
|
|
if (ifx_check() == 0) {
|
|
/* DISCONNECT again, after rollback */
|
|
EXEC SQL DISCONNECT :link;
|
|
if (ifx_check() < 0) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Disconnect link %s after Automatic Rollback fails (%s)", link, (ifx_err = ifx_error(link)));
|
|
}
|
|
}
|
|
if (ifx_check() < 0) {
|
|
/* CLOSE database if rollback or disconnect fails */
|
|
EXEC SQL CLOSE DATABASE;
|
|
if (ifx_check() < 0) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Close database fails %s (%s)", link, (ifx_err = ifx_error(link)));
|
|
}
|
|
}
|
|
}
|
|
else if (SQLCODE < 0) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Disconnect link %s fails (%s)", link, (ifx_err = ifx_error(link)));
|
|
}
|
|
}
|
|
else {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Set connection %s fails (%s)", link, (ifx_err = ifx_error(link)));
|
|
}
|
|
|
|
if (ifx_err) {
|
|
efree(ifx_err);
|
|
}
|
|
}
|
|
|
|
static void _close_ifx_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|
{
|
|
char *link;
|
|
|
|
link=(char *)rsrc->ptr;
|
|
|
|
ifx_do_close(link);
|
|
|
|
efree(link);
|
|
IFXG(num_links)--;
|
|
}
|
|
|
|
static void _close_ifx_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|
{
|
|
char *link;
|
|
|
|
link = (char *)rsrc->ptr;
|
|
|
|
ifx_do_close(link);
|
|
|
|
free(link);
|
|
IFXG(num_persistent)--;
|
|
IFXG(num_links)--;
|
|
}
|
|
|
|
static void ifx_free_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|
{
|
|
IFX_RES *Ifx_Result = (IFX_RES *)rsrc->ptr;
|
|
efree(Ifx_Result);
|
|
}
|
|
|
|
static void ifx_free_blob(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob = (IFX_IDRES *)rsrc->ptr;
|
|
|
|
php_intifx_release_blob(&Ifx_blob->BLOB.blob_data TSRMLS_CC);
|
|
efree(Ifx_blob);
|
|
}
|
|
|
|
PHP_INI_BEGIN()
|
|
STD_PHP_INI_BOOLEAN("ifx.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY_EX("ifx.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_ifx_globals, ifx_globals, display_link_numbers)
|
|
STD_PHP_INI_ENTRY_EX("ifx.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_ifx_globals, ifx_globals, display_link_numbers)
|
|
STD_PHP_INI_ENTRY("ifx.default_host", NULL, PHP_INI_SYSTEM, OnUpdateString, default_host, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.default_user", NULL, PHP_INI_SYSTEM, OnUpdateString, default_user, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.default_password", NULL, PHP_INI_SYSTEM, OnUpdateString, default_password, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.blobinfile", "1", PHP_INI_ALL, OnUpdateLong, blobinfile, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.textasvarchar", "0", PHP_INI_ALL, OnUpdateLong, textasvarchar, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.byteasvarchar", "0", PHP_INI_ALL, OnUpdateLong, byteasvarchar, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.charasvarchar", "0", PHP_INI_ALL, OnUpdateLong, charasvarchar, zend_ifx_globals, ifx_globals)
|
|
STD_PHP_INI_ENTRY("ifx.nullformat", "0", PHP_INI_ALL, OnUpdateLong, nullformat, zend_ifx_globals, ifx_globals)
|
|
PHP_INI_END()
|
|
|
|
static void php_ifx_init_globals(zend_ifx_globals *ifx_globals)
|
|
{
|
|
ifx_globals->num_persistent = 0;
|
|
ifx_globals->nullvalue[0] = 0;
|
|
strcpy(ifx_globals->nullstring, "NULL");
|
|
ifx_globals->num_persistent = 0;
|
|
ifx_globals->sv_sqlcode = 0;
|
|
}
|
|
|
|
PHP_MINIT_FUNCTION(ifx)
|
|
{
|
|
ZEND_INIT_MODULE_GLOBALS(ifx, php_ifx_init_globals, NULL);
|
|
|
|
REGISTER_INI_ENTRIES();
|
|
|
|
le_result = zend_register_list_destructors_ex(ifx_free_result, NULL, "informix result", module_number);
|
|
le_idresult = zend_register_list_destructors_ex(ifx_free_blob, NULL, "informix id result", module_number);
|
|
le_link = zend_register_list_destructors_ex(_close_ifx_link, NULL, "informix link", module_number);
|
|
le_plink = zend_register_list_destructors_ex(NULL, _close_ifx_plink, "informix persistent link", module_number);
|
|
ifx_module_entry.type = type;
|
|
|
|
REGISTER_LONG_CONSTANT("IFX_SCROLL", IFX_SCROLL, CONST_CS | CONST_PERSISTENT);
|
|
REGISTER_LONG_CONSTANT("IFX_HOLD", IFX_HOLD, CONST_CS | CONST_PERSISTENT);
|
|
$ifdef HAVE_IFX_IUS;
|
|
REGISTER_LONG_CONSTANT("IFX_LO_RDONLY", LO_RDONLY, CONST_CS | CONST_PERSISTENT);
|
|
REGISTER_LONG_CONSTANT("IFX_LO_WRONLY", LO_WRONLY, CONST_CS | CONST_PERSISTENT);
|
|
REGISTER_LONG_CONSTANT("IFX_LO_APPEND", LO_APPEND, CONST_CS | CONST_PERSISTENT);
|
|
REGISTER_LONG_CONSTANT("IFX_LO_RDWR", LO_RDWR, CONST_CS | CONST_PERSISTENT);
|
|
REGISTER_LONG_CONSTANT("IFX_LO_BUFFER", LO_BUFFER, CONST_CS | CONST_PERSISTENT);
|
|
REGISTER_LONG_CONSTANT("IFX_LO_NOBUFFER", LO_NOBUFFER, CONST_CS | CONST_PERSISTENT);
|
|
$endif;
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
PHP_MSHUTDOWN_FUNCTION(ifx)
|
|
{
|
|
UNREGISTER_INI_ENTRIES();
|
|
return SUCCESS;
|
|
}
|
|
|
|
PHP_RINIT_FUNCTION(ifx)
|
|
{
|
|
IFXG(default_link) = -1;
|
|
IFXG(num_links) = IFXG(num_persistent);
|
|
return SUCCESS;
|
|
}
|
|
PHP_MINFO_FUNCTION(ifx)
|
|
{
|
|
char buf[32];
|
|
|
|
php_info_print_table_start();
|
|
php_info_print_table_header(2, "Informix support", "enabled");
|
|
sprintf(buf, "%ld", IFXG(num_persistent));
|
|
php_info_print_table_row(2, "Active Persistent links", buf);
|
|
sprintf(buf, "%ld", IFXG(num_links));
|
|
php_info_print_table_row(2, "Active links", buf);
|
|
sprintf(buf, "%02.2f", (double)(IFX_VERSION/100.0));
|
|
php_info_print_table_row(2, "ESQL/C Version", buf);
|
|
php_info_print_table_end();
|
|
|
|
DISPLAY_INI_ENTRIES();
|
|
}
|
|
|
|
static void php_ifx_set_default_link(int id TSRMLS_DC)
|
|
{
|
|
if (IFXG(default_link) != -1) {
|
|
zend_list_delete(IFXG(default_link));
|
|
}
|
|
IFXG(default_link) = id;
|
|
zend_list_addref(id);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_(p)connect(string database, string userid, string password)
|
|
**
|
|
** connects to $database (db@server syntax) using $userid and $password
|
|
**
|
|
** returns a connection id on success or FALSE one error
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
static void php_ifx_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
|
{
|
|
char *hashed_details;
|
|
int hashed_details_length;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *user,*passwd,*host;
|
|
char *ifx;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
if (PG(sql_safe_mode)) {
|
|
if (ZEND_NUM_ARGS() > 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
|
|
}
|
|
host = passwd = NULL;
|
|
user = php_get_current_user();
|
|
hashed_details_length = strlen(user) + 3 + 3;
|
|
hashed_details = (char *) emalloc(hashed_details_length + 1);
|
|
sprintf(hashed_details, "ifx__%s_", user);
|
|
} else {
|
|
int host_len = 0, user_len = 0, passwd_len = 0;
|
|
host = user = passwd = NULL;
|
|
|
|
/* set default values if any are avaliable */
|
|
if (IFXG(default_host)) {
|
|
host = IFXG(default_host);
|
|
host_len = strlen(host);
|
|
}
|
|
if (IFXG(default_user)) {
|
|
user = IFXG(default_user);
|
|
user_len = strlen(IFXG(default_user));
|
|
}
|
|
if (IFXG(default_password)) {
|
|
passwd = IFXG(default_password);
|
|
passwd_len = strlen(IFXG(default_password));
|
|
}
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &host, &host_len, &user, &user_len, &passwd, &passwd_len) == FAILURE) {
|
|
return;
|
|
}
|
|
|
|
hashed_details_length = sizeof("ifx___") - 1 + host_len + user_len + passwd_len;
|
|
hashed_details = (char *) emalloc(hashed_details_length + 1);
|
|
sprintf(hashed_details, "ifx_%s_%s_%s", SAFE_STRING(host), SAFE_STRING(user), SAFE_STRING(passwd));
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
if (!IFXG(allow_persistent)) {
|
|
persistent = 0;
|
|
}
|
|
|
|
if (persistent) {
|
|
list_entry *le;
|
|
|
|
/* try to find if we already have this link in our persistent list */
|
|
if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void **) &le) == FAILURE) { /* we don't */
|
|
list_entry new_le;
|
|
|
|
if (IFXG(max_links) != -1 && IFXG(num_links) >= IFXG(max_links)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%d)", IFXG(num_links));
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
if (IFXG(max_persistent) != -1 && IFXG(num_persistent) >= IFXG(max_persistent)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%d)", IFXG(num_persistent));
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* create the link */
|
|
ifx = (char *) malloc(sizeof(IFX));
|
|
IFXG(connectionid)++;
|
|
sprintf(ifx, "%s%x_%x", SAFE_STRING(user), IFX_THRD_ID,IFXG(connectionid));
|
|
|
|
EXEC SQL CONNECT TO :host AS :ifx USER :user USING :passwd WITH CONCURRENT TRANSACTION;
|
|
|
|
if (ifx_check() == IFX_ERROR) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ifx_err);
|
|
efree(ifx_err);
|
|
free(ifx);
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* hash it up */
|
|
new_le.type = le_plink;
|
|
new_le.ptr = ifx;
|
|
if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length + 1, (void *) &new_le, sizeof(list_entry), NULL) == FAILURE) {
|
|
free(ifx);
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
IFXG(num_persistent)++;
|
|
IFXG(num_links)++;
|
|
} else { /* we do */
|
|
if (le->type != le_plink) {
|
|
RETURN_FALSE;
|
|
}
|
|
/* ensure that the link did not die */
|
|
ifx = le->ptr;
|
|
EXEC SQL SET CONNECTION :ifx;
|
|
if (ifx_check() == IFX_ERROR) { /* the link died */
|
|
ifx = le->ptr; /* reconnect silently */
|
|
EXEC SQL CONNECT TO :host AS :ifx USER :user USING :passwd WITH CONCURRENT TRANSACTION;
|
|
|
|
if (ifx_check() == IFX_ERROR) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect (%s)", ifx_err);
|
|
zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length + 1);
|
|
efree(ifx_err);
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
}
|
|
ifx = le->ptr;
|
|
}
|
|
ZEND_REGISTER_RESOURCE(return_value, ifx, le_plink);
|
|
} else { /* non persistent */
|
|
list_entry *index_ptr,new_index_ptr;
|
|
|
|
/* first we check the hash for the hashed_details key. if it exists,
|
|
* it should point us to the right offset where the actual ifx link sits.
|
|
* if it doesn't, open a new ifx link, add it to the resource list,
|
|
* and add a pointer to it with hashed_details as the key.
|
|
*/
|
|
if (zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length + 1, (void **) &index_ptr) == SUCCESS)
|
|
{
|
|
int type,link;
|
|
void *ptr;
|
|
|
|
if (index_ptr->type != le_index_ptr) {
|
|
RETURN_FALSE;
|
|
}
|
|
link = (int) index_ptr->ptr;
|
|
ptr = zend_list_find(link, &type); /* check if the link is still there */
|
|
if (ptr && (type == le_link || type == le_plink)) {
|
|
/* ensure that the link is not closed */
|
|
ifx = ptr;
|
|
EXEC SQL SET CONNECTION :ifx;
|
|
if (ifx_check() == IFX_ERROR) {
|
|
/* the link is closed */
|
|
ifx = ptr; /* reconnect silently */
|
|
EXEC SQL CONNECT TO :host AS :ifx USER :user USING :passwd WITH CONCURRENT TRANSACTION;
|
|
|
|
if (ifx_check() == IFX_ERROR) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to connect (%s)", ifx_err);
|
|
zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length + 1);
|
|
efree(hashed_details);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
}
|
|
zend_list_addref(link);
|
|
return_value->value.lval = link;
|
|
php_ifx_set_default_link(link TSRMLS_CC);
|
|
return_value->type = IS_RESOURCE;
|
|
efree(hashed_details);
|
|
return;
|
|
} else {
|
|
zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length + 1);
|
|
}
|
|
}
|
|
if (IFXG(max_links) != -1 && IFXG(num_links) >= IFXG(max_links)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%d)", IFXG(num_links));
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ifx = (char *) emalloc(sizeof(IFX));
|
|
IFXG(connectionid)++;
|
|
sprintf(ifx, "connec%x_%x", IFX_THRD_ID, IFXG(connectionid));
|
|
|
|
EXEC SQL CONNECT TO :host AS :ifx USER :user USING :passwd WITH CONCURRENT TRANSACTION;
|
|
|
|
if (ifx_check() == IFX_ERROR) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", ifx_err);
|
|
efree(ifx_err);
|
|
efree(hashed_details);
|
|
efree(ifx);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* add it to the list */
|
|
ZEND_REGISTER_RESOURCE(return_value, ifx, le_link);
|
|
|
|
/* add it to the hash */
|
|
new_index_ptr.ptr = (void *) return_value->value.lval;
|
|
new_index_ptr.type = le_index_ptr;
|
|
if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length + 1, (void *) &new_index_ptr, sizeof(list_entry), NULL) == FAILURE) {
|
|
efree(hashed_details);
|
|
RETURN_FALSE;
|
|
}
|
|
IFXG(num_links)++;
|
|
}
|
|
efree(hashed_details);
|
|
php_ifx_set_default_link(return_value->value.lval TSRMLS_CC);
|
|
}
|
|
|
|
/* {{{ proto resource ifx_connect([string database [, string userid [, string password]]])
|
|
Connects to database using userid/password, returns connection id */
|
|
PHP_FUNCTION(ifx_connect)
|
|
{
|
|
php_ifx_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
|
|
}
|
|
/* }}} */
|
|
|
|
/* {{{ proto resource ifx_pconnect([string database [, string userid [, string password]]])
|
|
Connects to database using userid/password, returns connection id */
|
|
PHP_FUNCTION(ifx_pconnect)
|
|
{
|
|
php_ifx_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_close(int connid)
|
|
**
|
|
** closes connection connid
|
|
** always returns TRUE
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_close([resource connid])
|
|
Close informix connection */
|
|
PHP_FUNCTION(ifx_close)
|
|
{
|
|
zval **ifx_link = NULL;
|
|
int id;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
switch (ZEND_NUM_ARGS()) {
|
|
case 0:
|
|
id = IFXG(default_link);
|
|
break;
|
|
case 1:
|
|
if (zend_get_parameters_ex(1, &ifx_link) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
id=-1;
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE2(ifx, char *, ifx_link, id, "Informix link", le_link, le_plink);
|
|
|
|
if (id == -1) { /* explicit resource number */
|
|
zend_list_delete(Z_RESVAL_PP(ifx_link));
|
|
}
|
|
|
|
if (id != -1 || (ifx_link && Z_RESVAL_PP(ifx_link) == IFXG(default_link))) {
|
|
zend_list_delete(IFXG(default_link));
|
|
IFXG(default_link) = -1;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_query(string query, int connid
|
|
** [, int cursortype] [, array blobidarray])
|
|
** cursortype and blobidarray are optional
|
|
**
|
|
** executes query query on connection connid
|
|
** for select queries a cursor is declared and opened
|
|
** non-select queries are "execute immediate"
|
|
** select queries accept an optional cursortype param:
|
|
** IFX_SCROLL, IFX_HOLD (or'ed mask)
|
|
** non-select queries accept an optional "blobarryid" parameter
|
|
** blobsupport: mark the blob-column(s) with ? in the insert/update query
|
|
** and add a blob-id-array-functionparameter
|
|
** select queries return "blob-ids" for blob columns
|
|
** except if text/byteasvarchar is set
|
|
** example: ifx_query("insert into catalog (stock_num, manu_code,
|
|
** cat_descr,cat_picture) values(1,'HRO',?,?)",$cid,$bidarray);
|
|
**
|
|
** returns a "result id" on success or FALSE on error
|
|
** also sets "affected_rows for retrieval by ifx_affected_rows()
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto resource ifx_query(string query, resource connid [, int cursortype] [, array idarray])
|
|
Perform a query on a given connection */
|
|
PHP_FUNCTION(ifx_query)
|
|
{
|
|
zval **query, **ifx_link, **cursortype, **dummy;
|
|
int id=-1;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char cursorid[32]; /* query cursor id */
|
|
char statemid[32]; /* statement id */
|
|
char descrpid[32]; /* descriptor id */
|
|
char i_descrpid[32]; /* input descriptor binding */
|
|
char *statement; /* query text */
|
|
int fieldcount; /* field count */
|
|
int i; /* field index */
|
|
short fieldtype;
|
|
loc_t *locator=NULL;
|
|
int loc_t_type=CLOCATORTYPE; /* WORKAROUND:TYPE=CLOCATORTYPE doesn't work, */
|
|
int sqlchar_type=SQLCHAR; /* don't ask me, why. */
|
|
char *char_tmp;
|
|
long len;
|
|
int indicator;
|
|
int desc_count;
|
|
$ifdef HAVE_IFX_IUS;
|
|
fixed binary 'blob' ifx_lo_t *slocator;
|
|
$endif;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
int locind;
|
|
int ctype;
|
|
int affected_rows;
|
|
long sqlerrd[6];
|
|
int e;
|
|
int query_type;
|
|
int cursoryproc;
|
|
int argc=ZEND_NUM_ARGS();
|
|
long ifx_type;
|
|
int num_params;
|
|
|
|
if (argc < 2 || zend_get_parameters_ex(argc, &query, &ifx_link, &dummy, &dummy) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE2(ifx, char *, ifx_link, id, "Informix link", le_link, le_plink);
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
affected_rows = -1; /* invalid */
|
|
|
|
convert_to_string_ex(query);
|
|
statement = Z_STRVAL_PP(query);
|
|
|
|
IFXG(cursorid)++;
|
|
sprintf(statemid, "statem%x_%x", IFX_THRD_ID, IFXG(cursorid));
|
|
sprintf(cursorid, "cursor%x_%x", IFX_THRD_ID, IFXG(cursorid));
|
|
sprintf(descrpid, "descrp%x_%x", IFX_THRD_ID, IFXG(cursorid));
|
|
sprintf(i_descrpid, "i_descrp%x_%x", IFX_THRD_ID,IFXG(cursorid));
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
EXEC SQL PREPARE :statemid FROM :statement;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prepare fails (%s)", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
affected_rows = sqlca.sqlerrd[0]; /* save estimated affected rows */
|
|
for (e = 0; e < 6; e++) sqlerrd[e] = sqlca.sqlerrd[e];
|
|
|
|
num_params = php_intifx_preparse(statement TSRMLS_CC);
|
|
|
|
Ifx_Result = (IFX_RES *) emalloc(sizeof(IFX_RES));
|
|
if (Ifx_Result == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of memory allocating IFX_RES");
|
|
EXEC SQL free :statemid;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* initialize result data structure */
|
|
Ifx_Result->rowid = 0;
|
|
strcpy(Ifx_Result->connecid, ifx);
|
|
strcpy(Ifx_Result->cursorid, cursorid);
|
|
strcpy(Ifx_Result->descrpid, descrpid);
|
|
strcpy(Ifx_Result->i_descrpid, i_descrpid);
|
|
strcpy(Ifx_Result->statemid, statemid);
|
|
Ifx_Result->numcols = 0;
|
|
Ifx_Result->numicols = 0;
|
|
|
|
for (i = 0; i < MAX_RESID; ++i) {
|
|
Ifx_Result->res_id[i] = -1;
|
|
}
|
|
|
|
if (!php_intifx_alloc_ibind(Ifx_Result, num_params TSRMLS_CC)) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Allocate i_desciptor <%s> fails (%s)", i_descrpid, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
desc_count = php_intifx_count_descriptors(statemid TSRMLS_CC);
|
|
if (desc_count == 0) {
|
|
desc_count = 1;
|
|
}
|
|
|
|
EXEC SQL ALLOCATE DESCRIPTOR :descrpid WITH MAX :desc_count;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Allocate desciptor <%s> fails (%s)", descrpid, ifx_err);
|
|
EXEC SQL free :statemid;
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
EXEC SQL DESCRIBE :statemid USING SQL DESCRIPTOR :descrpid;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Describe fails (%s)", ifx_err);
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
query_type = sqlca.sqlcode;
|
|
|
|
cursoryproc = 0;
|
|
if (query_type == SQ_EXECPROC) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid :i = COUNT;
|
|
if (i > 0) {
|
|
cursoryproc = 1;
|
|
}
|
|
}
|
|
|
|
Ifx_Result->iscursory = -1; /* prevent ifx_do */
|
|
Ifx_Result->paramquery = 0;
|
|
|
|
if ((query_type != 0) && (!cursoryproc)) { /* NO RESULT SET */
|
|
/* ##
|
|
## NONSELECT-STATEMENT
|
|
##
|
|
*/
|
|
zval **pblobidarr, **tmp;
|
|
|
|
/* We don't need this descriptor anymore, NONSELECT-STATEMENT */
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
|
|
Ifx_Result->iscursory = 0;
|
|
|
|
if (argc > 3) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
|
|
if (Ifx_Result->numicols <= 0) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No placeholders (?) in Statement, but blob array param supplied");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (zend_get_parameters_ex(3, &dummy, &dummy, &pblobidarr) == FAILURE) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't get blob array param");
|
|
RETURN_FALSE;
|
|
}
|
|
if (Z_TYPE_PP(pblobidarr) != IS_ARRAY) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Blob-parameter is not an array");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
zend_hash_internal_pointer_reset((*pblobidarr)->value.ht);
|
|
for (i = 1; i <= Ifx_Result->numicols && (zend_hash_get_current_data((*pblobidarr)->value.ht, (void **) &tmp) == SUCCESS); ++i) {
|
|
convert_to_long(*tmp);
|
|
|
|
ifx_type = php_intifx_getType((int)(*tmp)->value.lval, &EG(regular_list) TSRMLS_CC);
|
|
switch (ifx_type) {
|
|
case TYPE_BLTEXT:
|
|
case TYPE_BLBYTE:
|
|
locator = php_intifx_get_blobloc((int)((*tmp)->value.lval), &EG(regular_list) TSRMLS_CC);
|
|
if (locator == NULL) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not an Informix blob-result index", (int)((*tmp)->value.lval));
|
|
RETURN_FALSE;
|
|
}
|
|
if (locator->loc_loctype == LOCFNAME) {
|
|
locator->loc_oflags=LOC_RONLY;
|
|
}
|
|
EXEC SQL SET DESCRIPTOR :i_descrpid VALUE :i DATA = :*locator, TYPE = :loc_t_type;
|
|
break;
|
|
|
|
case TYPE_CHAR:
|
|
len = php_intifx_get_char((int) ((*tmp)->value.lval), &EG(regular_list), &char_tmp TSRMLS_CC);
|
|
indicator = 0;
|
|
if (char_tmp == NULL || len < 0) {
|
|
indicator = -1;
|
|
}
|
|
len++;
|
|
|
|
EXEC SQL SET DESCRIPTOR :i_descrpid VALUE :i
|
|
DATA= :char_tmp,
|
|
LENGTH= :len,
|
|
INDICATOR= :indicator,
|
|
TYPE= :sqlchar_type;
|
|
break;
|
|
}
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Execute immediate fails : %s", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
zend_hash_move_forward((*pblobidarr)->value.ht);
|
|
}
|
|
Ifx_Result->paramquery=1;
|
|
|
|
if (i - 1 != Ifx_Result->numicols) {
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Execute immediate fails : number of created blobs doesn't match placeholders (?)");
|
|
RETURN_FALSE;
|
|
}
|
|
EXEC SQL EXECUTE :statemid USING SQL DESCRIPTOR :i_descrpid;
|
|
} else {
|
|
EXEC SQL EXECUTE :statemid;
|
|
}
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
if (Ifx_Result->numicols > 0) {
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
}
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Execute immediate fails : %s", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
Ifx_Result->affected_rows = sqlca.sqlerrd[2]; /* really affected */
|
|
for (e = 0; e < 6; e++) {
|
|
Ifx_Result->sqlerrd[e] = sqlca.sqlerrd[e];
|
|
}
|
|
} else {
|
|
/* ##
|
|
## SELECT-STATEMENT
|
|
##
|
|
*/
|
|
|
|
ctype = 0; /* preset */
|
|
|
|
switch(argc) {
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
if (zend_get_parameters_ex(3, &dummy, &dummy, &cursortype) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
convert_to_long_ex(cursortype);
|
|
ctype = Z_LVAL_PP(cursortype);
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
Ifx_Result->affected_rows = affected_rows; /* saved estimated from prepare */
|
|
for (e = 0; e < 6; e++) {
|
|
Ifx_Result->sqlerrd[e] = sqlerrd[e];
|
|
}
|
|
|
|
EXEC SQL GET DESCRIPTOR :descrpid :fieldcount = COUNT;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not get descriptor %s (%s)", descrpid, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
Ifx_Result->numcols = fieldcount;
|
|
Ifx_Result->isscroll = Ifx_Result->ishold = 0;
|
|
|
|
if (ctype & IFX_SCROLL) {
|
|
Ifx_Result->isscroll = 1;
|
|
}
|
|
if (ctype & IFX_HOLD) {
|
|
Ifx_Result->ishold = 1;
|
|
}
|
|
|
|
/*
|
|
* ifx_do() part
|
|
*/
|
|
|
|
if (Ifx_Result->isscroll) {
|
|
if (Ifx_Result->ishold) {
|
|
EXEC SQL DECLARE :cursorid SCROLL CURSOR WITH HOLD FOR :statemid;
|
|
} else {
|
|
EXEC SQL DECLARE :cursorid SCROLL CURSOR FOR :statemid;
|
|
}
|
|
} else {
|
|
if (Ifx_Result->ishold) {
|
|
EXEC SQL DECLARE :cursorid CURSOR WITH HOLD FOR :statemid;
|
|
} else {
|
|
EXEC SQL DECLARE :cursorid CURSOR FOR :statemid;
|
|
}
|
|
}
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Declare cursor fails (%s)", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
EXEC SQL OPEN :cursorid;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
EXEC SQL free :statemid;
|
|
EXEC SQL free :cursorid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Open cursor fails (%s)", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* check for text/blob columns */
|
|
locind = 0;
|
|
for (i = 1; i <= fieldcount; ++i) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :fieldtype = TYPE;
|
|
if ((fieldtype == SQLTEXT) || (fieldtype == SQLBYTES)
|
|
$ifdef HAVE_IFX_IUS;
|
|
|| (fieldtype == SQLUDTFIXED)
|
|
$endif;
|
|
) {
|
|
int bid = 0;
|
|
if (fieldtype == SQLTEXT) {
|
|
if (IFXG(blobinfile) == 0) {
|
|
bid = php_intifx_create_blob(TYPE_BLTEXT,BLMODE_INMEM, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
} else {
|
|
bid = php_intifx_create_blob(TYPE_BLTEXT,BLMODE_INFILE, "",-1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
}
|
|
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*locator;
|
|
} else if (fieldtype == SQLBYTES) {
|
|
if (IFXG(blobinfile) == 0) {
|
|
bid = php_intifx_create_blob(TYPE_BLBYTE, BLMODE_INMEM, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
} else {
|
|
bid = php_intifx_create_blob(TYPE_BLBYTE,BLMODE_INFILE, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
}
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*locator;
|
|
}
|
|
|
|
php_intifx_release_blob(locator TSRMLS_CC);
|
|
$ifdef HAVE_IFX_IUS;
|
|
if (fieldtype == SQLUDTFIXED) {
|
|
bid = php_intifxus_new_slob(&EG(regular_list) TSRMLS_CC);
|
|
slocator = php_intifxus_get_slobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*slocator;
|
|
}
|
|
$endif;
|
|
Ifx_Result->res_id[locind]=bid;
|
|
++locind;
|
|
}
|
|
}
|
|
}
|
|
ZEND_REGISTER_RESOURCE(return_value, Ifx_Result, le_result);
|
|
}
|
|
/* }}} */
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_prepare(string query, int connid,
|
|
** [, int cursortype] [, array blobidarry])
|
|
**
|
|
** $hold, $scroll are optional and valid only for select queries
|
|
** $blobidarray is optional, an array of blob id's
|
|
**
|
|
** prepares query $query on connection $connid
|
|
** select queries accept an optional cursortype param: IFX_SCROLL, IFX_HOLD (or'ed mask)
|
|
** blobsupport: mark the blob-column with ? and add a blob-id-functionparameter
|
|
** example: ifx_query("insert into catalog (stock_num, manu_code ,cat_descr,
|
|
** cat_picture) values(1,'HRO',?,?)",$cid,$bid1,$bid2);
|
|
**
|
|
** returns a "result id" on success or FALSE on error
|
|
** also sets "affected_rows for retrieval by ifx_affected_rows
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto resource ifx_prepare(string query, resource connid [, int cursortype] [, array idarray])
|
|
Prepare a query on a given connection */
|
|
PHP_FUNCTION(ifx_prepare)
|
|
{
|
|
zval **query, **ifx_link, **cursortype, **dummy;
|
|
int id=-1;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char cursorid[32]; /* query cursor id */
|
|
char statemid[32]; /* statement id */
|
|
char descrpid[32]; /* descriptor id */
|
|
char i_descrpid[32]; /* input descriptor binding */
|
|
char *statement; /* query text */
|
|
int fieldcount; /* field count */
|
|
int i; /* field index */
|
|
loc_t *locator;
|
|
int loc_t_type=CLOCATORTYPE; /* WORKAROUND: TYPE=CLOCATORTYPE doesn't work, */
|
|
int sqlchar_type=SQLCHAR; /* don't ask me, why. */
|
|
char *char_tmp;
|
|
long len;
|
|
int indicator;
|
|
long sqlerrd[6];
|
|
int e;
|
|
int desc_count;
|
|
EXEC SQL END DECLARE SECTION;
|
|
int ctype;
|
|
int affected_rows;
|
|
int query_type;
|
|
int cursoryproc;
|
|
int argc=ZEND_NUM_ARGS();
|
|
long ifx_type;
|
|
int num_params;
|
|
|
|
if (argc < 2 || zend_get_parameters_ex(argc, &query, &ifx_link, &dummy, &dummy) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE2(ifx, char *, ifx_link, id, "Informix link", le_link, le_plink);
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
affected_rows = -1; /* invalid */
|
|
|
|
convert_to_string_ex(query);
|
|
statement = Z_STRVAL_PP(query);
|
|
|
|
IFXG(cursorid)++;
|
|
sprintf(statemid, "statem%x_%x", IFX_THRD_ID, IFXG(cursorid));
|
|
sprintf(cursorid, "cursor%x_%x", IFX_THRD_ID, IFXG(cursorid));
|
|
sprintf(descrpid, "descrp%x_%x", IFX_THRD_ID, IFXG(cursorid));
|
|
sprintf(i_descrpid, "i_descrp%x_%x", IFX_THRD_ID,IFXG(cursorid));
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
EXEC SQL PREPARE :statemid FROM :statement;
|
|
if (ifx_check() < 0) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prepare fails (%s)", ifx_error(ifx));
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
affected_rows = sqlca.sqlerrd[0]; /* save estimated affected rows */
|
|
for (e = 0; e < 6; e++) {
|
|
sqlerrd[e] = sqlca.sqlerrd[e];
|
|
}
|
|
num_params = php_intifx_preparse(statement TSRMLS_CC);
|
|
|
|
Ifx_Result = (IFX_RES *) emalloc(sizeof(IFX_RES));
|
|
if (Ifx_Result == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of memory allocating IFX_RES");
|
|
EXEC SQL free :statemid;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* initialize result data structure */
|
|
|
|
Ifx_Result->rowid = 0;
|
|
strcpy(Ifx_Result->connecid, ifx);
|
|
strcpy(Ifx_Result->cursorid, cursorid);
|
|
strcpy(Ifx_Result->descrpid, descrpid);
|
|
strcpy(Ifx_Result->i_descrpid, i_descrpid);
|
|
strcpy(Ifx_Result->statemid, statemid);
|
|
Ifx_Result->numcols = 0;
|
|
Ifx_Result->numicols = 0;
|
|
|
|
for (i = 0; i < MAX_RESID; ++i) {
|
|
Ifx_Result->res_id[i] = -1;
|
|
}
|
|
|
|
if (!php_intifx_alloc_ibind(Ifx_Result, num_params TSRMLS_CC)) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Allocate i_desciptor <%s> fails (%s)", i_descrpid, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
desc_count = php_intifx_count_descriptors(statemid TSRMLS_CC);
|
|
if (desc_count == 0) {
|
|
desc_count = 1;
|
|
}
|
|
|
|
EXEC SQL ALLOCATE DESCRIPTOR :descrpid WITH MAX :desc_count;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Allocate desciptor <%s> fails (%s)", descrpid, ifx_err);
|
|
EXEC SQL free :statemid;
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
EXEC SQL DESCRIBE :statemid USING SQL DESCRIPTOR :descrpid;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Describe fails (%s)", ifx_err);
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
query_type = sqlca.sqlcode;
|
|
|
|
cursoryproc = 0;
|
|
if (query_type == SQ_EXECPROC) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid :i = COUNT;
|
|
if (i > 0) {
|
|
cursoryproc = 1;
|
|
}
|
|
}
|
|
|
|
Ifx_Result->iscursory = -1; /* prevent ifx_do */
|
|
Ifx_Result->paramquery=0;
|
|
|
|
if ((query_type != 0) && (!cursoryproc)) { /* NO RESULT SET */
|
|
/* ##
|
|
## NONSELECT-STATEMENT
|
|
##
|
|
*/
|
|
zval **pblobidarr, **tmp;
|
|
|
|
/* We don't need this descriptor anymore, NONSELECT-STATEMENT */
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
|
|
Ifx_Result->iscursory = 0;
|
|
|
|
if (argc > 3) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
if (argc == 3) {
|
|
Ifx_Result->paramquery = 1;
|
|
|
|
if (Ifx_Result->numicols <= 0) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No placeholders (?) in Statement, but blob array param supplied");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (zend_get_parameters_ex(3, &dummy, &dummy, &pblobidarr) == FAILURE) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't get blob array param");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if ((*pblobidarr)->type != IS_ARRAY) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Blob-parameter not an array");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
zend_hash_internal_pointer_reset((*pblobidarr)->value.ht);
|
|
for (i = 1; i <= num_params && (zend_hash_get_current_data((*pblobidarr)->value.ht, (void **) &tmp) == SUCCESS); ++i) {
|
|
convert_to_long(*tmp);
|
|
|
|
ifx_type = php_intifx_getType((int)(*tmp)->value.lval, &EG(regular_list) TSRMLS_CC);
|
|
switch (ifx_type) {
|
|
case TYPE_BLTEXT:
|
|
case TYPE_BLBYTE:
|
|
locator = php_intifx_get_blobloc((int)((*tmp)->value.lval), &EG(regular_list) TSRMLS_CC);
|
|
if (locator == NULL) {
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix blob-result index", (int)((*tmp)->value.lval));
|
|
RETURN_FALSE;
|
|
}
|
|
if (locator->loc_loctype == LOCFNAME) {
|
|
locator->loc_oflags=LOC_RONLY;
|
|
}
|
|
EXEC SQL SET DESCRIPTOR :i_descrpid VALUE :i DATA = :*locator, TYPE = :loc_t_type;
|
|
break;
|
|
case TYPE_CHAR:
|
|
len = php_intifx_get_char((int)((*tmp)->value.lval), &EG(regular_list), &char_tmp TSRMLS_CC);
|
|
|
|
indicator = 0;
|
|
if (char_tmp == NULL || len < 0) {
|
|
indicator = -1;
|
|
}
|
|
len++;
|
|
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i
|
|
DATA= :char_tmp,
|
|
LENGTH= :len,
|
|
INDICATOR= :indicator,
|
|
TYPE= :sqlchar_type;
|
|
break;
|
|
}
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prepare fails : %s", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
zend_hash_move_forward((*pblobidarr)->value.ht);
|
|
}
|
|
|
|
if (i - 1 != Ifx_Result->numicols) {
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prepare fails : number of created blobs doesn't match placeholders (?)");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
Ifx_Result->affected_rows = affected_rows; /* saved estimated from prepare */
|
|
for (e = 0; e < 6; e++) {
|
|
Ifx_Result->sqlerrd[e] = sqlerrd[e];
|
|
}
|
|
|
|
} else {
|
|
/* ##
|
|
## SELECT-STATEMENT
|
|
##
|
|
*/
|
|
ctype = 0; /* preset */
|
|
|
|
switch (argc) {
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
if (zend_get_parameters_ex(3, &dummy, &dummy, &cursortype) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
convert_to_long_ex(cursortype);
|
|
ctype = Z_LVAL_PP(cursortype);
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
Ifx_Result->iscursory = 1;
|
|
|
|
Ifx_Result->affected_rows = affected_rows; /* saved estimated from prepare */
|
|
for (e = 0; e < 6; e++) {
|
|
Ifx_Result->sqlerrd[e] = sqlerrd[e];
|
|
}
|
|
|
|
EXEC SQL GET DESCRIPTOR :descrpid :fieldcount = COUNT;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err;
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
EXEC SQL free :statemid;
|
|
efree(Ifx_Result);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not get descriptor %s (%s)", descrpid, (ifx_err = ifx_error(ifx)));
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
Ifx_Result->numcols = fieldcount;
|
|
Ifx_Result->isscroll = Ifx_Result->ishold = 0;
|
|
|
|
if (ctype & IFX_SCROLL) {
|
|
Ifx_Result->isscroll = 1;
|
|
}
|
|
if (ctype & IFX_HOLD) {
|
|
Ifx_Result->ishold = 1;
|
|
}
|
|
}
|
|
|
|
ZEND_REGISTER_RESOURCE(return_value, Ifx_Result, le_result);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_do(int resultid)
|
|
**
|
|
** executes a previously prepared query or opens a cursor for it
|
|
**
|
|
** returns TRUE on success, false on error
|
|
** does NOT free $resultid on error !!!
|
|
**
|
|
** also sets (real) affected_rows for non-select statements
|
|
** for retrieval by ifx_affected_rows
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_do(resource resultid)
|
|
Executes a previously prepared query or opens a cursor for it */
|
|
PHP_FUNCTION(ifx_do)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char *cursorid; /* query cursor id */
|
|
char *statemid; /* statement id */
|
|
char *descrpid; /* descriptor id */
|
|
char *i_descrpid; /* descriptor id */
|
|
int fieldcount; /* field count */
|
|
int i; /* field index */
|
|
short fieldtype;
|
|
loc_t *locator=NULL;
|
|
int e;
|
|
$ifdef HAVE_IFX_IUS;
|
|
fixed binary 'blob' ifx_lo_t *slocator;
|
|
$endif;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
int locind;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &result) == FAILURE)) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ifx = Ifx_Result->connecid;
|
|
cursorid = Ifx_Result->cursorid;
|
|
statemid = Ifx_Result->statemid;
|
|
descrpid = Ifx_Result->descrpid;
|
|
i_descrpid = Ifx_Result->i_descrpid;
|
|
fieldcount = Ifx_Result->numcols;
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
if (Ifx_Result->iscursory < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Resultindex %d is not a prepared query", Z_LVAL_PP(result));
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (Ifx_Result->iscursory == 0) { /* execute immediate */
|
|
if (Ifx_Result->paramquery != 0) {
|
|
EXEC SQL EXECUTE :statemid USING SQL DESCRIPTOR :i_descrpid;
|
|
} else {
|
|
EXEC SQL EXECUTE :statemid;
|
|
}
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Execute immediate fails: %s", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
Ifx_Result->affected_rows = sqlca.sqlerrd[2]; /* really affected */
|
|
for (e = 0; e < 6; e++) {
|
|
Ifx_Result->sqlerrd[e] = sqlca.sqlerrd[e];
|
|
}
|
|
} else { /* open cursor */
|
|
if (Ifx_Result->isscroll) {
|
|
if (Ifx_Result->ishold) {
|
|
EXEC SQL DECLARE :cursorid SCROLL CURSOR WITH HOLD FOR :statemid;
|
|
} else {
|
|
EXEC SQL DECLARE :cursorid SCROLL CURSOR FOR :statemid;
|
|
}
|
|
} else {
|
|
if (Ifx_Result->ishold) {
|
|
EXEC SQL DECLARE :cursorid CURSOR WITH HOLD FOR :statemid;
|
|
} else {
|
|
EXEC SQL DECLARE :cursorid CURSOR FOR :statemid;
|
|
}
|
|
}
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Declare cursor fails (%s)", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
EXEC SQL OPEN :cursorid;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Open cursor fails (%s)", ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* check for text/blob columns */
|
|
locind = 0;
|
|
for (i = 1; i <= fieldcount; ++i) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :fieldtype = TYPE;
|
|
if ((fieldtype == SQLTEXT) || (fieldtype == SQLBYTES)
|
|
$ifdef HAVE_IFX_IUS;
|
|
|| (fieldtype == SQLUDTFIXED)
|
|
$endif;
|
|
) {
|
|
|
|
int bid = 0;
|
|
if (fieldtype == SQLTEXT) {
|
|
if (IFXG(blobinfile) == 0) {
|
|
bid = php_intifx_create_blob(TYPE_BLTEXT,BLMODE_INMEM, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
} else {
|
|
bid = php_intifx_create_blob(TYPE_BLTEXT,BLMODE_INFILE, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
}
|
|
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*locator;
|
|
}
|
|
else if (fieldtype == SQLBYTES) {
|
|
if (IFXG(blobinfile) == 0) {
|
|
bid = php_intifx_create_blob(TYPE_BLBYTE,BLMODE_INMEM, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
} else {
|
|
bid = php_intifx_create_blob(TYPE_BLBYTE,BLMODE_INFILE, "", -1, &EG(regular_list) TSRMLS_CC);
|
|
locator = php_intifx_get_blobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
locator->loc_oflags = LOC_WONLY;
|
|
}
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*locator;
|
|
}
|
|
|
|
php_intifx_release_blob(locator TSRMLS_CC);
|
|
$ifdef HAVE_IFX_IUS;
|
|
if (fieldtype == SQLUDTFIXED) {
|
|
bid = php_intifxus_new_slob(&EG(regular_list) TSRMLS_CC);
|
|
slocator = php_intifxus_get_slobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*slocator;
|
|
}
|
|
$endif;
|
|
Ifx_Result->res_id[locind] = bid;
|
|
++locind;
|
|
}
|
|
}
|
|
} /* end open cursor */
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** string ifx_error([int connection_id]);
|
|
**
|
|
** returns the Informix error codes (SQLSTATE & SQLCODE)
|
|
**
|
|
** connection id is not checked, but remains for compatibility
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto string ifx_error([resource connection_id])
|
|
Returns the Informix error codes (SQLSTATE & SQLCODE) */
|
|
PHP_FUNCTION(ifx_error)
|
|
{
|
|
zval **ifx_link;
|
|
int id;
|
|
|
|
switch(ZEND_NUM_ARGS()) {
|
|
case 0:
|
|
id = IFXG(default_link);
|
|
break;
|
|
case 1:
|
|
if (zend_get_parameters_ex(1, &ifx_link) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
RETURN_STRING(ifx_error(0), 0); /* ifx_error returns emalloced string */
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** string ifx_errormsg([int errorcode])
|
|
**
|
|
** returns the Informix errormessage associated with
|
|
** the most recent Informix error if SQLCODE is nonzero, or,
|
|
** when the optional "errocode" param is present, the errormessage
|
|
** corresponding to "errorcode".
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto string ifx_errormsg([int errorcode])
|
|
Returns the Informix errormessage associated with */
|
|
PHP_FUNCTION(ifx_errormsg)
|
|
{
|
|
zval **errcode;
|
|
int ifx_errorcode;
|
|
int msglen, maxmsglen;
|
|
char *ifx_errmsg;
|
|
char * returnmsg;
|
|
|
|
switch(ZEND_NUM_ARGS()) {
|
|
case 0:
|
|
if (IFXG(sv_sqlcode) == 0) {
|
|
ifx_errorcode = SQLCODE;
|
|
} else {
|
|
ifx_errorcode = IFXG(sv_sqlcode);
|
|
}
|
|
break;
|
|
case 1:
|
|
if (zend_get_parameters_ex(1, &errcode) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
convert_to_long_ex(errcode);
|
|
ifx_errorcode = Z_LVAL_PP(errcode);
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
maxmsglen = 255;
|
|
msglen = maxmsglen; /* Some bug fix, rgetlmsg doesnt always set the value */
|
|
ifx_errmsg = (char *)emalloc(maxmsglen + 1);
|
|
if (ifx_errorcode != 0) {
|
|
rgetlmsg(ifx_errorcode, ifx_errmsg, maxmsglen, &msglen);
|
|
if (msglen > maxmsglen) {
|
|
maxmsglen = msglen;
|
|
ifx_errmsg = (char *)erealloc(ifx_errmsg, maxmsglen + 1);
|
|
rgetlmsg(ifx_errorcode, ifx_errmsg, maxmsglen, &msglen);
|
|
}
|
|
} else {
|
|
ifx_errmsg[0] = 0;
|
|
}
|
|
|
|
returnmsg = (char *) emalloc(strlen(ifx_errmsg) + 128);
|
|
sprintf(returnmsg, ifx_errmsg, sqlca.sqlerrm);
|
|
efree(ifx_errmsg);
|
|
RETURN_STRING(returnmsg,0);
|
|
}
|
|
/* }}} */
|
|
|
|
/* --------------------------------------------------------------
|
|
** int ifx_affected_rows(int resultid)
|
|
**
|
|
** returns the number of rows affected by query $resultid
|
|
**
|
|
** for selects : estimated number of rows (sqlerrd[0])
|
|
** for insert/update/delete : real number (sqlerrd[2])
|
|
** ---------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_affected_rows(resource resultid)
|
|
Returns the number of rows affected by query identified by resultid */
|
|
PHP_FUNCTION(ifx_affected_rows)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || (zend_get_parameters_ex(1, &result)) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
RETURN_LONG(Ifx_Result->affected_rows);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** array ifx_fetch_row(int resultid [, mixed $position])
|
|
**
|
|
** fetches the next row, or if using a scroll cursor, and position
|
|
** is present, the row as given in position, into an associative
|
|
** array with the fieldnames as key
|
|
**
|
|
** returns FALSE on error
|
|
**
|
|
** position can be : "FIRST", "NEXT", "LAST", "PREVIOUS", "CURRENT"
|
|
** or an absolute row number
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto array ifx_fetch_row(resource resultid [, mixed position])
|
|
Fetches the next row or <position> row if using a scroll cursor */
|
|
PHP_FUNCTION(ifx_fetch_row)
|
|
{
|
|
zval **result, **position;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char *cursorid; /* query cursor id */
|
|
char *statemid; /* statement id */
|
|
char *descrpid; /* descriptor id */
|
|
int fieldcount; /* field count */
|
|
int i; /* an index */
|
|
char fieldname[64]; /* fieldname */
|
|
short fieldtype; /* field type */
|
|
int fieldleng; /* field length */
|
|
$ifdef HAVE_IFX_IUS;
|
|
ifx_int8_t int8_var;
|
|
lvarchar *lvar_tmp;
|
|
$endif;
|
|
short indicator;
|
|
int int_data;
|
|
char *char_data;
|
|
long date_data;
|
|
interval intvl_data = {0};
|
|
datetime dt_data = {0};
|
|
decimal dec_data = {0};
|
|
short short_data;
|
|
loc_t *locator_b;
|
|
$ifdef HAVE_IFX_IUS;
|
|
fixed binary 'blob' ifx_lo_t *slocator;
|
|
$endif;
|
|
float float_data;
|
|
double double_data;
|
|
int fetch_row;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
int num_fields;
|
|
int locind,bid,bid_b;
|
|
char string_data[256];
|
|
long long_data;
|
|
char *p;
|
|
char *fetch_pos;
|
|
char *nullstr;
|
|
|
|
switch (ZEND_NUM_ARGS()) {
|
|
case 1:
|
|
if (zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
fetch_pos = NULL;
|
|
fetch_row = 0;
|
|
break;
|
|
case 2:
|
|
if (zend_get_parameters_ex(2, &result, &position) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
if (Z_TYPE_PP(position) != IS_STRING) {
|
|
fetch_pos = NULL;
|
|
fetch_row = Z_LVAL_PP(position);
|
|
} else {
|
|
fetch_pos = Z_STRVAL_PP(position);
|
|
fetch_row = 0;
|
|
}
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
nullstr = php_intifx_null(TSRMLS_C);
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
if (strcmp(Ifx_Result->cursorid, "") == 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a select cursor!");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ifx = Ifx_Result->connecid;
|
|
cursorid = Ifx_Result->cursorid;
|
|
statemid = Ifx_Result->statemid;
|
|
descrpid = Ifx_Result->descrpid;
|
|
fieldcount = Ifx_Result->numcols;
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
locind = 0;
|
|
for (i = 1; i <= Ifx_Result->numcols; i++) {
|
|
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :fieldtype = TYPE;
|
|
if (fieldtype == SQLBYTES || fieldtype == SQLTEXT) {
|
|
|
|
bid_b = Ifx_Result->res_id[locind];
|
|
|
|
if ((locator_b = php_intifx_get_blobloc(bid_b, &EG(regular_list) TSRMLS_CC)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cant get BLOB from Result Set!");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
locind++;
|
|
|
|
if (IFXG(blobinfile) == 0) {
|
|
php_intifx_init_blob(locator_b, BLMODE_INMEM, 1 TSRMLS_CC);
|
|
} else {
|
|
php_intifx_init_blob(locator_b, BLMODE_INFILE, 1 TSRMLS_CC);
|
|
}
|
|
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*locator_b;
|
|
|
|
}
|
|
}
|
|
|
|
if (!Ifx_Result->isscroll) {
|
|
EXEC SQL FETCH :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else {
|
|
if (fetch_pos == NULL) {
|
|
if (fetch_row != 0) {
|
|
EXEC SQL FETCH ABSOLUTE :fetch_row :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else {
|
|
EXEC SQL FETCH NEXT :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
}
|
|
} else {
|
|
if (!strcasecmp(fetch_pos, "NEXT")) {
|
|
EXEC SQL FETCH NEXT :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else if (!strcasecmp(fetch_pos, "PREVIOUS")) {
|
|
EXEC SQL FETCH PREVIOUS :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else if (!strcasecmp(fetch_pos, "FIRST")) {
|
|
EXEC SQL FETCH FIRST :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else if (!strcasecmp(fetch_pos, "LAST")) {
|
|
EXEC SQL FETCH LAST :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else if (!strcasecmp(fetch_pos, "CURRENT")) {
|
|
EXEC SQL FETCH CURRENT :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
} else {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid positioning arg on fetch");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SQLCODE != -451) {
|
|
switch (ifx_check()) {
|
|
case IFX_ERROR:
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
{
|
|
char *ifx_err = ifx_error(ifx);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not fetch row on cursor %s (%s)", ifx_err, cursorid);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
break;
|
|
case IFX_NODATA:
|
|
RETURN_FALSE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
Ifx_Result->rowid++;
|
|
|
|
array_init(return_value);
|
|
num_fields = fieldcount;
|
|
|
|
locind = 0;
|
|
for (i = 1; i <= num_fields; i++) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i
|
|
:fieldtype = TYPE,
|
|
:fieldname = NAME,
|
|
:fieldleng = LENGTH,
|
|
:indicator = INDICATOR;
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Get descriptor (field # %d) fails (%s)", i, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
p = fieldname; /* rtrim fieldname */
|
|
while ((*p != ' ') && (p < &fieldname[sizeof(fieldname) - 1])) ++p;
|
|
*p = 0;
|
|
if (strcmp("(expression)", fieldname) == 0) { /* stored proc */
|
|
sprintf(fieldname, "[Expr_%d]", i);
|
|
}
|
|
|
|
if (indicator == -1) { /* NULL */
|
|
if ((IFXG(textasvarchar) == 0 && fieldtype == SQLTEXT) ||
|
|
(IFXG(byteasvarchar) == 0 && fieldtype == SQLBYTES)) {
|
|
bid_b = Ifx_Result->res_id[locind];
|
|
/* call php_intifx_get_blobloc() to reset locator_b */
|
|
locator_b = php_intifx_get_blobloc(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
bid = php_intifx_copy_blob(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
php_intifx_update_blob(bid,nullstr, strlen(nullstr), &EG(regular_list) TSRMLS_CC);
|
|
add_assoc_long(return_value, fieldname, bid);
|
|
++locind;
|
|
php_intifx_release_blob(locator_b TSRMLS_CC);
|
|
continue;
|
|
}
|
|
if ((fieldtype == SQLTEXT) || (fieldtype == SQLBYTES)
|
|
$ifdef HAVE_IFX_IUS;
|
|
|| (fieldtype == SQLUDTFIXED)
|
|
$endif;
|
|
) {
|
|
/* call php_intifx_get_blobloc() to reset locator_b */
|
|
bid_b = Ifx_Result->res_id[locind];
|
|
locator_b = php_intifx_get_blobloc(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
++locind;
|
|
php_intifx_release_blob(locator_b TSRMLS_CC);
|
|
}
|
|
add_assoc_string(return_value, fieldname, nullstr, DUP);
|
|
continue;
|
|
} /* NULL */
|
|
|
|
switch (fieldtype) {
|
|
case SQLSERIAL:
|
|
case SQLINT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :int_data = DATA;
|
|
long_data = int_data;
|
|
sprintf(string_data, "%ld", long_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLSMINT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :short_data = DATA;
|
|
long_data = short_data;
|
|
sprintf(string_data, "%ld", long_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLDECIMAL:
|
|
case SQLMONEY:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :dec_data = DATA;
|
|
memset(string_data, 0x20, 64);
|
|
dectoasc(&dec_data, string_data, 63, -1);
|
|
for (p = string_data; *p != ' '; ++p) ;
|
|
*p = 0;
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLSMFLOAT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :float_data = DATA;
|
|
double_data = float_data;
|
|
sprintf(string_data, "%17.17g", double_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLFLOAT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :double_data = DATA;
|
|
sprintf(string_data, "%17.17g", double_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLDATE:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :date_data = DATA;
|
|
rdatestr(date_data, string_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLDTIME:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :dt_data = DATA;
|
|
dttoasc(&dt_data, string_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLINTERVAL:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :intvl_data = DATA;
|
|
intoasc(&intvl_data, string_data);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
$ifdef HAVE_IFX_IUS;
|
|
case SQLSERIAL8:
|
|
case SQLINT8:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :int8_var = DATA;
|
|
memset(string_data, ' ', sizeof(string_data));
|
|
ifx_int8toasc(&int8_var, string_data, 200);
|
|
p = string_data; /* rtrim string_data */
|
|
while ((*p != ' ') && (p < &string_data[sizeof(string_data) - 1])) ++p;
|
|
*p = 0;
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
case SQLLVARCHAR:
|
|
ifx_var_flag(&lvar_tmp, 1);
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :lvar_tmp = DATA;
|
|
fieldleng = ifx_var_getlen(&lvar_tmp);
|
|
if (fieldleng > 2) { /* fix by Alex Shepherd */
|
|
fieldleng -= 2;
|
|
}
|
|
if ((char_data = (char *)emalloc(fieldleng + 1)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of memory");
|
|
RETURN_FALSE;
|
|
}
|
|
memcpy(char_data, ifx_var_getdata(&lvar_tmp), fieldleng);
|
|
ifx_var_dealloc(&lvar_tmp);
|
|
add_assoc_stringl(return_value, fieldname, char_data, fieldleng, 0);
|
|
break;
|
|
case SQLBOOL:
|
|
$endif;
|
|
case SQLVCHAR:
|
|
case SQLNVCHAR:
|
|
case SQLCHAR:
|
|
case SQLNCHAR:
|
|
if ((char_data = (char *)emalloc(fieldleng + 1)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of memory");
|
|
RETURN_FALSE;
|
|
}
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :char_data = DATA;
|
|
if (IFXG(charasvarchar) != 0 && (fieldtype == SQLCHAR || fieldtype == SQLNCHAR)) {
|
|
ldchar(char_data, fieldleng, char_data);
|
|
}
|
|
add_assoc_string(return_value, fieldname, char_data, DUP);
|
|
efree(char_data);
|
|
char_data = NULL;
|
|
break;
|
|
$ifdef HAVE_IFX_IUS;
|
|
case SQLUDTFIXED:
|
|
bid_b = Ifx_Result->res_id[locind];
|
|
add_assoc_long(return_value, fieldname,bid_b);
|
|
bid = php_intifxus_new_slob(&EG(regular_list) TSRMLS_CC);
|
|
slocator = php_intifxus_get_slobloc(bid, &EG(regular_list) TSRMLS_CC);
|
|
EXEC SQL SET DESCRIPTOR :descrpid VALUE :i DATA = :*slocator;
|
|
Ifx_Result->res_id[locind] = bid;
|
|
++locind;
|
|
break;
|
|
$endif;
|
|
case SQLBYTES:
|
|
case SQLTEXT:
|
|
bid_b = Ifx_Result->res_id[locind];
|
|
locator_b = php_intifx_get_blobloc(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
++locind;
|
|
|
|
if (IFXG(blobinfile) == 0) {
|
|
php_intifx_init_blob(locator_b, BLMODE_INMEM, 0 TSRMLS_CC);
|
|
} else {
|
|
php_intifx_init_blob(locator_b, BLMODE_INFILE, 0 TSRMLS_CC);
|
|
}
|
|
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :*locator_b = DATA;
|
|
|
|
/* work around for ESQL/C bug with NULL values and BLOBS */
|
|
if ((locator_b->loc_status < 0) && (locator_b->loc_bufsize == 0)){
|
|
locator_b->loc_indicator = -1;
|
|
}
|
|
|
|
/* normal check for NULL values */
|
|
if (locator_b->loc_indicator == -1) {
|
|
if ((IFXG(textasvarchar) == 0 && fieldtype == SQLTEXT) ||
|
|
(IFXG(byteasvarchar) == 0 && fieldtype == SQLBYTES)
|
|
) {
|
|
bid = php_intifx_copy_blob(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
php_intifx_update_blob(bid,nullstr, strlen(nullstr), &EG(regular_list) TSRMLS_CC);
|
|
add_assoc_long(return_value, fieldname, bid);
|
|
php_intifx_release_blob(locator_b TSRMLS_CC);
|
|
break;
|
|
}
|
|
if ((fieldtype == SQLTEXT) || (fieldtype == SQLBYTES)
|
|
$ifdef HAVE_IFX_IUS;
|
|
|| (fieldtype == SQLUDTFIXED)
|
|
$endif;
|
|
) {
|
|
add_assoc_string(return_value, fieldname, nullstr, DUP);
|
|
php_intifx_release_blob(locator_b TSRMLS_CC);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (locator_b->loc_status < 0) { /* blob too large */
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory (%d bytes) for blob", locator_b->loc_bufsize);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* return blob as VARCHAR ? */
|
|
/* note that in case of "blobinfile" */
|
|
/* you get the file name */
|
|
/* a new one for every row ! */
|
|
if ((IFXG(textasvarchar) != 0 && fieldtype == SQLTEXT) ||
|
|
(IFXG(byteasvarchar) != 0 && fieldtype == SQLBYTES)
|
|
) {
|
|
char *content;
|
|
long lg;
|
|
|
|
lg = php_intifx_get_blob(bid_b, &EG(regular_list), &content TSRMLS_CC);
|
|
if (content == NULL || lg < 0) {
|
|
add_assoc_string(return_value, fieldname, nullstr, DUP);
|
|
} else {
|
|
add_assoc_stringl(return_value, fieldname, content, lg, DUP);
|
|
}
|
|
|
|
php_intifx_release_blob(locator_b TSRMLS_CC);
|
|
break;
|
|
}
|
|
|
|
/* copy blob */
|
|
bid = php_intifx_copy_blob(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
|
|
/* no, return as blob id */
|
|
add_assoc_long(return_value, fieldname, bid);
|
|
php_intifx_release_blob(locator_b TSRMLS_CC);
|
|
break;
|
|
|
|
default:
|
|
sprintf(string_data, "ESQL/C : %s : unsupported field type[%d]", fieldname, fieldleng);
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_htmltbl_result(int resultid [, string htmltableoptions])
|
|
**
|
|
** formats all rows of the resultid query into a html table
|
|
** the optional second argument is a string of <table> tag options
|
|
**
|
|
** returns the number of rows printed or FALSE on error
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_htmltbl_result(resource resultid [, string htmltableoptions])
|
|
Formats all rows of the resultid query into a html table */
|
|
PHP_FUNCTION(ifx_htmltbl_result)
|
|
{
|
|
zval **result, **arg2;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char *cursorid; /* query cursor id */
|
|
char *statemid; /* statement id */
|
|
char *descrpid; /* descriptor id */
|
|
int fieldcount; /* field count */
|
|
int i; /* an index */
|
|
char fieldname[64]; /* fieldname */
|
|
short fieldtype; /* field type */
|
|
int fieldleng; /* field length */
|
|
$ifdef HAVE_IFX_IUS;
|
|
ifx_int8_t int8_var;
|
|
lvarchar *lvar_tmp;
|
|
$endif;
|
|
short indicator;
|
|
int int_data;
|
|
char *char_data = NULL;
|
|
long date_data;
|
|
interval intvl_data = {0};
|
|
datetime dt_data = {0};
|
|
decimal dec_data = {0};
|
|
short short_data;
|
|
float float_data;
|
|
double double_data;
|
|
loc_t *locator_b;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
char *content;
|
|
char *copy_content;
|
|
long lg;
|
|
char *nullstr;
|
|
int num_fields;
|
|
char string_data[256];
|
|
long long_data;
|
|
char *p;
|
|
int locind,bid_b;
|
|
char *table_options;
|
|
int moredata;
|
|
|
|
switch (ZEND_NUM_ARGS()) {
|
|
case 1:
|
|
if (zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
table_options = NULL;
|
|
break;
|
|
case 2:
|
|
if (zend_get_parameters_ex(2, &result, &arg2) == FAILURE) {
|
|
RETURN_FALSE;
|
|
}
|
|
table_options = (*arg2)->value.str.val;
|
|
break;
|
|
default:
|
|
WRONG_PARAM_COUNT;
|
|
break;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
if (strcmp(Ifx_Result->cursorid, "") == 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a select cursor!");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ifx = Ifx_Result->connecid;
|
|
cursorid = Ifx_Result->cursorid;
|
|
statemid = Ifx_Result->statemid;
|
|
descrpid = Ifx_Result->descrpid;
|
|
fieldcount = Ifx_Result->numcols;
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
/* try to fetch the first row */
|
|
EXEC SQL FETCH :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
switch (ifx_check()) {
|
|
case IFX_ERROR:
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
{
|
|
char *ifx_err = ifx_error(ifx);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not fetch next row on cursor %s (%s)", ifx_err, cursorid);
|
|
efree(ifx_err);
|
|
}
|
|
RETURN_FALSE;
|
|
break;
|
|
case IFX_NODATA:
|
|
moredata = 0;
|
|
break;
|
|
default:
|
|
Ifx_Result->rowid = moredata = 1;
|
|
break;
|
|
}
|
|
|
|
if (!moredata) {
|
|
php_printf("<h2>No rows found</h2>\n");
|
|
RETURN_LONG(0);
|
|
}
|
|
num_fields = fieldcount;
|
|
nullstr = php_intifx_null(TSRMLS_C);
|
|
|
|
/* start table tag */
|
|
if (table_options == NULL) {
|
|
php_printf("<table><tr>");
|
|
} else {
|
|
php_printf("<table %s><tr>", table_options);
|
|
}
|
|
|
|
/* table headings */
|
|
for (i = 1; i <= num_fields; i++) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :fieldname = NAME;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Get descriptor (field # %d) fails (%s)", i, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
p = fieldname; /* Capitalize and rtrim fieldname */
|
|
*p = toupper(*p);
|
|
while ((*p != ' ') && (p < &fieldname[sizeof(fieldname) - 1])) ++p;
|
|
*p = 0;
|
|
if (strcmp("(expression)", fieldname) == 0) { /* stored proc */
|
|
sprintf(fieldname, "[Expr_%d]", i);
|
|
}
|
|
php_printf("<th>%s</th>", fieldname);
|
|
}
|
|
php_printf("</tr>\n");
|
|
|
|
/* start spitting out rows untill none left */
|
|
while (moredata) {
|
|
php_printf("<tr>");
|
|
locind = 0;
|
|
for (i = 1; i <= num_fields; i++) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i
|
|
:fieldtype = TYPE,
|
|
:fieldleng = LENGTH,
|
|
:indicator = INDICATOR;
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Get descriptor (field # %d) fails (%s)", i, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (indicator == -1) { /* NULL */
|
|
if (fieldtype == SQLTEXT || fieldtype == SQLBYTES) {
|
|
++locind;
|
|
}
|
|
php_printf("<td>%s</td>", nullstr);
|
|
continue;
|
|
}
|
|
|
|
switch (fieldtype) {
|
|
case SQLSERIAL:
|
|
case SQLINT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :int_data = DATA;
|
|
long_data = int_data;
|
|
sprintf(string_data, "%ld", long_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLSMINT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :short_data = DATA;
|
|
long_data = short_data;
|
|
sprintf(string_data, "%ld", long_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLDECIMAL:
|
|
case SQLMONEY:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :dec_data = DATA;
|
|
memset(string_data, 0x20, 64);
|
|
dectoasc(&dec_data, string_data, 63, -1);
|
|
for (p = string_data; *p != ' '; ++p) ;
|
|
*p = 0;
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLSMFLOAT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :float_data = DATA;
|
|
double_data = float_data;
|
|
sprintf(string_data, "%17.17g", double_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLFLOAT:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :double_data = DATA;
|
|
sprintf(string_data, "%17.17g", double_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLDATE:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :date_data = DATA;
|
|
rdatestr(date_data, string_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLDTIME:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :dt_data = DATA;
|
|
dttoasc(&dt_data, string_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLINTERVAL:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :intvl_data = DATA;
|
|
intoasc(&intvl_data, string_data);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
$ifdef HAVE_IFX_IUS;
|
|
case SQLSERIAL8:
|
|
case SQLINT8:
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :int8_var = DATA;
|
|
memset(string_data, ' ', sizeof(string_data));
|
|
ifx_int8toasc(&int8_var, string_data, 200);
|
|
p = string_data; /* rtrim string_data */
|
|
while ((*p != ' ') && (p < &string_data[sizeof(string_data) - 1])) ++p;
|
|
*p = 0;
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
case SQLLVARCHAR:
|
|
ifx_var_flag(&lvar_tmp, 1);
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :lvar_tmp = DATA;
|
|
fieldleng = ifx_var_getlen(&lvar_tmp);
|
|
if (fieldleng > 2) { /* fix by Alex Shepherd */
|
|
fieldleng -= 2;
|
|
}
|
|
if ((char_data = (char *)emalloc(fieldleng + 1)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of memory");
|
|
RETURN_FALSE;
|
|
}
|
|
memcpy(char_data, ifx_var_getdata(&lvar_tmp), fieldleng);
|
|
ifx_var_dealloc(&lvar_tmp);
|
|
add_assoc_stringl(return_value, fieldname, char_data, fieldleng, 0);
|
|
break;
|
|
case SQLBOOL:
|
|
$endif;
|
|
case SQLCHAR:
|
|
case SQLVCHAR:
|
|
case SQLNCHAR:
|
|
case SQLNVCHAR:
|
|
if ((char_data = (char *)emalloc(fieldleng + 1)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Out of memory");
|
|
RETURN_FALSE;
|
|
}
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :char_data = DATA;
|
|
if (IFXG(charasvarchar) != 0 && (fieldtype == SQLCHAR || fieldtype == SQLNCHAR)) {
|
|
ldchar(char_data, fieldleng, char_data);
|
|
}
|
|
php_printf("<td>%s</td>", char_data);
|
|
efree(char_data);
|
|
char_data = NULL;
|
|
break;
|
|
case SQLTEXT :
|
|
/* treated always as a long VARCHAR here */
|
|
/* if blobinbfile, too bad */
|
|
bid_b = Ifx_Result->res_id[locind];
|
|
++locind;
|
|
locator_b = php_intifx_get_blobloc(bid_b, &EG(regular_list) TSRMLS_CC);
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :*locator_b = DATA;
|
|
|
|
/* work around for ESQL/C bug with NULL values and BLOBS */
|
|
if ((locator_b->loc_status < 0) && (locator_b->loc_bufsize == 0)){
|
|
locator_b->loc_indicator = -1;
|
|
}
|
|
|
|
/* normal check for NULL values */
|
|
if (locator_b->loc_indicator == -1) {
|
|
if ((fieldtype == SQLTEXT) || (fieldtype == SQLBYTES)
|
|
$ifdef HAVE_IFX_IUS;
|
|
|| (fieldtype == SQLUDTFIXED)
|
|
$endif;
|
|
) {
|
|
php_printf("<td>%s</td>", nullstr);
|
|
break;
|
|
}
|
|
}
|
|
if (locator_b->loc_status < 0) { /* blob too large */
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not enough memory (%d bytes) for blob", locator_b->loc_bufsize);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
/* get blob contents */
|
|
lg = php_intifx_get_blob(bid_b, &EG(regular_list), &content TSRMLS_CC);
|
|
|
|
if (content == NULL || lg < 0) {
|
|
php_printf("<td>%s</td>", nullstr);
|
|
} else {
|
|
/* need an extra byte for string terminator */
|
|
copy_content = emalloc(lg + 1);
|
|
if (copy_content == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not enough memory for TEXT column");
|
|
RETURN_FALSE;
|
|
}
|
|
memcpy(copy_content, content, lg);
|
|
copy_content[lg] = 0;
|
|
php_printf("<td>%s</td>", copy_content);
|
|
efree(copy_content);
|
|
}
|
|
break;
|
|
|
|
case SQLBYTES :
|
|
++locind;
|
|
php_printf("<td>(BYTE)</td>");
|
|
break;
|
|
default :
|
|
sprintf(string_data, "ESQL/C: %s : unsupported field type[%d]", fieldname, fieldleng);
|
|
php_printf("<td>%s</td>", string_data);
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
php_printf("</tr>\n");
|
|
|
|
/* fetch next row */
|
|
EXEC SQL FETCH :cursorid USING SQL DESCRIPTOR :descrpid;
|
|
switch (ifx_check()) {
|
|
case IFX_ERROR:
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
{
|
|
char *ifx_err = ifx_error(ifx);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not fetch next row on cursor %s (%s)", ifx_err, cursorid);
|
|
efree(ifx_err);
|
|
}
|
|
RETURN_FALSE;
|
|
break;
|
|
case IFX_NODATA:
|
|
moredata = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
} /* switch() */
|
|
Ifx_Result->rowid++;
|
|
} /* endwhile (moredata); */
|
|
php_printf("</table>\n");
|
|
RETURN_LONG(Ifx_Result->rowid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** array ifx_fieldtypes(int resultid)
|
|
**
|
|
** returns an associative array with fieldnames as key
|
|
** and SQL fieldtypes as data for query $resultid
|
|
**
|
|
** returns FALSE on error
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto array ifx_fieldtypes(resource resultid)
|
|
Returns an associative array with fieldnames as key for query <resultid> */
|
|
PHP_FUNCTION(ifx_fieldtypes)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char *cursorid; /* query cursor id */
|
|
char *statemid; /* statement id */
|
|
char *descrpid; /* descriptor id */
|
|
int fieldcount; /* field count */
|
|
int i; /* an index */
|
|
char fieldname[64]; /* fieldname */
|
|
short fieldtype; /* field type */
|
|
char *char_data = NULL;
|
|
EXEC SQL END DECLARE SECTION;
|
|
int num_fields;
|
|
char *p;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
if (strcmp(Ifx_Result->cursorid, "") == 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a select cursor!");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ifx = Ifx_Result->connecid;
|
|
cursorid = Ifx_Result->cursorid;
|
|
statemid = Ifx_Result->statemid;
|
|
descrpid = Ifx_Result->descrpid;
|
|
fieldcount = Ifx_Result->numcols;
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
array_init(return_value);
|
|
num_fields = fieldcount;
|
|
for (i = 1; i <= num_fields; i++) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :fieldname = NAME, :fieldtype = TYPE;
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Get descriptor (field # %d) fails (%s)", i, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
p = fieldname; /* rtrim fieldname */
|
|
while ((*p != ' ') && (p < &fieldname[sizeof(fieldname) - 1])) ++p;
|
|
*p = 0;
|
|
if (strcmp("(expression)", fieldname) == 0) { /* stored proc */
|
|
sprintf(fieldname, "[Expr_%d]", i);
|
|
}
|
|
|
|
switch (fieldtype) {
|
|
case SQLSERIAL:
|
|
char_data = "SQLSERIAL";
|
|
break;
|
|
case SQLINT:
|
|
char_data = "SQLINT";
|
|
break;
|
|
case SQLSMINT:
|
|
char_data = "SQLSMINT";
|
|
break;
|
|
case SQLDECIMAL:
|
|
char_data = "SQLDECIMAL";
|
|
break;
|
|
case SQLMONEY:
|
|
char_data = "SQLMONEY";
|
|
break;
|
|
case SQLSMFLOAT:
|
|
char_data = "SQLSMFLOAT";
|
|
break;
|
|
case SQLFLOAT:
|
|
char_data = "SQLFLOAT";
|
|
break;
|
|
case SQLDATE:
|
|
char_data = "SQLDATE";
|
|
break;
|
|
case SQLDTIME:
|
|
char_data = "SQLDTIME";
|
|
break;
|
|
case SQLINTERVAL:
|
|
char_data = "SQLINTERVAL";
|
|
break;
|
|
case SQLCHAR:
|
|
char_data = "SQLCHAR";
|
|
break;
|
|
case SQLVCHAR:
|
|
char_data = "SQLVCHAR";
|
|
break;
|
|
case SQLNCHAR:
|
|
char_data = "SQLNCHAR";
|
|
break;
|
|
case SQLNVCHAR:
|
|
char_data = "SQLNVCHAR";
|
|
break;
|
|
case SQLTEXT:
|
|
char_data = "SQLTEXT";
|
|
break;
|
|
case SQLBYTES:
|
|
char_data = "SQLBYTES";
|
|
break;
|
|
$ifdef HAVE_IFX_IUS;
|
|
case SQLUDTFIXED:
|
|
char_data = "SQLUDTFIXED";
|
|
break;
|
|
case SQLBOOL:
|
|
char_data = "SQLBOOL";
|
|
break;
|
|
case SQLINT8:
|
|
char_data = "SQLINT8";
|
|
break;
|
|
case SQLSERIAL8:
|
|
char_data = "SQLSERIAL8";
|
|
break;
|
|
case SQLLVARCHAR:
|
|
char_data = "SQLLVARCHAR";
|
|
break;
|
|
$endif;
|
|
default:
|
|
char_data = emalloc(20);
|
|
sprintf(char_data, "ESQL/C : %i", fieldtype);
|
|
break;
|
|
} /* switch (fieldtype) */
|
|
|
|
add_assoc_string(return_value, fieldname, char_data, DUP);
|
|
} /* for() */
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** array ifx_fieldproperties(int resultid)
|
|
**
|
|
** returns an associative array with fieldnames as key
|
|
** and SQL fieldproperties as data for query $resultid
|
|
**
|
|
** properties are encoded as : "SQLTYPE;length;precision;scale;ISNULLABLE"
|
|
** where SQLTYPE = the Informix type like "SQLVCHAR" etc...
|
|
** ISNULLABLE = "Y" or "N"
|
|
**
|
|
** returns FALSE on error
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto array ifx_fieldproperties(resource resultid)
|
|
Returns an associative for query <resultid> array with fieldnames as key */
|
|
PHP_FUNCTION(ifx_fieldproperties)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char *cursorid; /* query cursor id */
|
|
char *statemid; /* statement id */
|
|
char *descrpid; /* descriptor id */
|
|
int fieldcount; /* field count */
|
|
int i; /* an index */
|
|
char fieldname[64]; /* fieldname */
|
|
short fieldtype; /* field type */
|
|
char *char_data = NULL;
|
|
int size;
|
|
int precision;
|
|
int scale;
|
|
int isnullable;
|
|
EXEC SQL END DECLARE SECTION;
|
|
int num_fields;
|
|
char string_data[256];
|
|
char *p;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
if (strcmp(Ifx_Result->cursorid, "") == 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a select cursor!");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
ifx = Ifx_Result->connecid;
|
|
cursorid = Ifx_Result->cursorid;
|
|
statemid = Ifx_Result->statemid;
|
|
descrpid = Ifx_Result->descrpid;
|
|
fieldcount = Ifx_Result->numcols;
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
array_init(return_value);
|
|
num_fields = fieldcount;
|
|
|
|
for (i = 1; i <= num_fields; i++) {
|
|
EXEC SQL GET DESCRIPTOR :descrpid VALUE :i :fieldname = NAME,
|
|
:fieldtype = TYPE,
|
|
:size = LENGTH,
|
|
:precision = PRECISION,
|
|
:scale = SCALE,
|
|
:isnullable = NULLABLE;
|
|
|
|
if (ifx_check() < 0) {
|
|
char *ifx_err = ifx_error(ifx);
|
|
IFXG(sv_sqlcode) = SQLCODE;
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Get descriptor (field # %d) fails (%s)", i, ifx_err);
|
|
efree(ifx_err);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
p = fieldname; /* rtrim fieldname */
|
|
while ((*p != ' ') && (p < &fieldname[sizeof(fieldname) - 1])) ++p;
|
|
*p = 0;
|
|
if (strcmp("(expression)", fieldname) == 0) { /* stored proc */
|
|
sprintf(fieldname, "[Expr_%d]", i);
|
|
}
|
|
|
|
switch (fieldtype) {
|
|
case SQLSERIAL:
|
|
char_data = "SQLSERIAL";
|
|
break;
|
|
case SQLINT:
|
|
char_data = "SQLINT";
|
|
break;
|
|
case SQLSMINT:
|
|
char_data = "SQLSMINT";
|
|
break;
|
|
case SQLDECIMAL:
|
|
char_data = "SQLDECIMAL";
|
|
break;
|
|
case SQLMONEY:
|
|
char_data = "SQLMONEY";
|
|
break;
|
|
case SQLSMFLOAT:
|
|
char_data = "SQLSMFLOAT";
|
|
break;
|
|
case SQLFLOAT:
|
|
char_data = "SQLFLOAT";
|
|
break;
|
|
case SQLDATE:
|
|
char_data = "SQLDATE";
|
|
break;
|
|
case SQLDTIME:
|
|
char_data = "SQLDTIME";
|
|
break;
|
|
case SQLINTERVAL:
|
|
char_data = "SQLINTERVAL";
|
|
break;
|
|
case SQLCHAR:
|
|
char_data = "SQLCHAR";
|
|
break;
|
|
case SQLVCHAR:
|
|
char_data = "SQLVCHAR";
|
|
break;
|
|
case SQLTEXT:
|
|
char_data = "SQLTEXT";
|
|
break;
|
|
case SQLBYTES:
|
|
char_data = "SQLBYTES";
|
|
break;
|
|
case SQLNCHAR:
|
|
char_data = "SQLNCHAR";
|
|
break;
|
|
case SQLNVCHAR:
|
|
char_data = "SQLNVCHAR";
|
|
break;
|
|
$ifdef HAVE_IFX_IUS;
|
|
case SQLUDTFIXED:
|
|
char_data = "SQLUDTFIXED";
|
|
break;
|
|
case SQLBOOL:
|
|
char_data = "SQLBOOL";
|
|
break;
|
|
case SQLINT8:
|
|
char_data = "SQLINT8";
|
|
break;
|
|
case SQLSERIAL8:
|
|
char_data = "SQLSERIAL8";
|
|
break;
|
|
case SQLLVARCHAR:
|
|
char_data = "SQLLVARCHAR";
|
|
break;
|
|
$endif;
|
|
default:
|
|
char_data = emalloc(20);
|
|
sprintf(char_data, "ESQL/C : %i", fieldtype);
|
|
break;
|
|
} /* switch (fieldtype) */
|
|
|
|
sprintf(string_data, "%s;%d;%d;%d;%c", char_data, size, precision, scale, (isnullable ? 'Y' : 'N'));
|
|
add_assoc_string(return_value, fieldname, string_data, DUP);
|
|
} /* for() */
|
|
}
|
|
/* }}} */
|
|
|
|
/* --------------------------------------------------------------
|
|
** int ifx_num_rows(int resultid)
|
|
**
|
|
** returns the number of rows already fetched for query resultid
|
|
**
|
|
** ---------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_num_rows(resource resultid)
|
|
Returns the number of rows already fetched for query identified by resultid */
|
|
PHP_FUNCTION(ifx_num_rows)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
RETURN_LONG(Ifx_Result->rowid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* --------------------------------------------------------------
|
|
** int ifx_getsqlca(int resultid)
|
|
**
|
|
** returns the sqlerrd[] fields of the sqlca struct for query resultid
|
|
** following the prepare (select) or execute immediate (insert/update/execute procedure)
|
|
**
|
|
** ---------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto array ifx_getsqlca(resource resultid)
|
|
Returns the sqlerrd[] fields of the sqlca struct for query resultid */
|
|
PHP_FUNCTION(ifx_getsqlca)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
char fieldname[16];
|
|
int e;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
/* create pseudo-row array to return */
|
|
array_init(return_value);
|
|
|
|
/* fill array with 6 fields sqlerrd0 .. sqlerrd5 */
|
|
/* each ESQLC call saves these sqlca values */
|
|
for (e = 0; e < 6; e++) {
|
|
sprintf(fieldname, "sqlerrd%d", e);
|
|
add_assoc_long(return_value, fieldname, Ifx_Result->sqlerrd[e]);
|
|
}
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_num_fields(int resultid)
|
|
**
|
|
** returns the number of columns in query resultid
|
|
** or FALSE on error
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_num_fields(resource resultid)
|
|
Returns the number of columns in query resultid */
|
|
PHP_FUNCTION(ifx_num_fields)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
IFXG(sv_sqlcode) = 0;
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
RETURN_LONG(Ifx_Result->numcols);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_free_result(int resultid)
|
|
**
|
|
** releases resources for query associated with resultid
|
|
**
|
|
** returns FALSE on error
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_free_result(resource resultid)
|
|
Releases resources for query associated with resultid */
|
|
PHP_FUNCTION(ifx_free_result)
|
|
{
|
|
zval **result;
|
|
IFX_RES *Ifx_Result;
|
|
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *ifx; /* connection ID */
|
|
char *cursorid; /* query cursor id */
|
|
char *statemid; /* statement id */
|
|
char *descrpid; /* descriptor id */
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
int i;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &result) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
IFXG(sv_sqlcode = 0);
|
|
|
|
ZEND_FETCH_RESOURCE(Ifx_Result, IFX_RES *, result, -1, "Informix Result", le_result);
|
|
|
|
for (i = 0; i < MAX_RESID; ++i) {
|
|
if (Ifx_Result->res_id[i] > 0) {
|
|
zend_list_delete(Ifx_Result->res_id[i]);
|
|
Ifx_Result->res_id[i] = -1;
|
|
}
|
|
}
|
|
|
|
ifx = Ifx_Result->connecid;
|
|
cursorid = Ifx_Result->cursorid;
|
|
statemid = Ifx_Result->statemid;
|
|
descrpid = Ifx_Result->descrpid;
|
|
|
|
EXEC SQL set connection :ifx;
|
|
PHP_IFX_CHECK_CONNECTION(ifx);
|
|
|
|
EXEC SQL free :statemid;
|
|
if (strlen(cursorid) != 0) {
|
|
EXEC SQL CLOSE :cursorid;
|
|
EXEC SQL FREE :cursorid;
|
|
}
|
|
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :descrpid;
|
|
|
|
zend_list_delete(Z_RESVAL_PP(result));
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_getType(long id, HashTable *list)
|
|
*
|
|
* returns the type of an id-object
|
|
* bid: Id of object
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error otherwise the type: TYPE_BLTEXT, TYPE_BLBYTE, TYPE_SLOB
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_getType(long id, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_res;
|
|
int type;
|
|
|
|
Ifx_res = (IFX_IDRES *) zend_list_find(id, &type);
|
|
if (type != le_idresult) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix id-result index", id);
|
|
return -1;
|
|
}
|
|
return Ifx_res->type;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_create_blob(int type, int mode, string param)
|
|
**
|
|
** creates a blob-object
|
|
** type: 1=TEXT, 0=BYTE
|
|
** mode: blob-object holds 0=the content in memory, 1=content in file
|
|
** param: if mode=0: pointer to the content
|
|
** mode=1: pointer to the filestring
|
|
** return false on error otherwise the new Blob-Object-id
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_create_blob(int type, int mode, string param)
|
|
Creates a blob-object */
|
|
PHP_FUNCTION(ifx_create_blob)
|
|
{
|
|
zval **pmode, **pparam,**ptype;
|
|
long id;
|
|
long mode,type;
|
|
|
|
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &ptype, &pmode, &pparam) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
convert_to_long_ex(pmode);
|
|
convert_to_string_ex(pparam);
|
|
convert_to_long_ex(ptype);
|
|
|
|
type = Z_LVAL_PP(ptype);
|
|
if (type != 0) {
|
|
type = TYPE_BLTEXT;
|
|
}
|
|
|
|
mode = Z_LVAL_PP(pmode);
|
|
if (mode != 0) {
|
|
mode=BLMODE_INFILE;
|
|
}
|
|
|
|
id = php_intifx_create_blob(type, mode, Z_STRVAL_PP(pparam), Z_STRLEN_PP(pparam), &EG(regular_list) TSRMLS_CC);
|
|
|
|
if (id < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(id);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_create_blob(long type, long mode, char* param, long len, HashTable *list TSRMLS_DC)
|
|
*
|
|
* creates an blob-object for the PHP Resource list
|
|
* type: 1=TEXT, 0=BYTE
|
|
* mode: blob-object holds 0=the content in momory, 1=content in file
|
|
* param: if mode=0: pointer to the content
|
|
* mode=1: pointer to the filestring
|
|
* len: length of param
|
|
* list: internal hashlist of php
|
|
* return -1 on error otherwise the new Blob-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_create_blob(long type, long mode, char* param, long len, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob;
|
|
|
|
Ifx_blob=emalloc(sizeof(IFX_IDRES));
|
|
if (Ifx_blob == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
|
|
memset(Ifx_blob, 0, sizeof(IFX_IDRES));
|
|
|
|
if (type == 0 ) {
|
|
Ifx_blob->type = TYPE_BLBYTE;
|
|
} else {
|
|
Ifx_blob->type = TYPE_BLTEXT;
|
|
}
|
|
Ifx_blob->BLOB.mode = (int) mode;
|
|
|
|
if (php_intifx_init_blob(&Ifx_blob->BLOB.blob_data, mode, 1 TSRMLS_CC) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
|
|
if (mode == BLMODE_INMEM) {
|
|
if (len >= 0) {
|
|
char *content = emalloc(len);
|
|
if (content == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
memcpy(content,param,len);
|
|
Ifx_blob->BLOB.blob_data.loc_buffer = content;
|
|
Ifx_blob->BLOB.blob_data.loc_bufsize = len;
|
|
Ifx_blob->BLOB.blob_data.loc_size = len;
|
|
Ifx_blob->BLOB.blob_data.loc_oflags = 0;
|
|
}
|
|
} else {
|
|
|
|
if (*param && param != "") {
|
|
|
|
/*
|
|
* copy the filename in param to filename in loc_fname
|
|
* otherwise we'll unlink non-temporary files
|
|
*
|
|
* loc_fname gets filled by php_intifx_init_blob_infile
|
|
*/
|
|
if (Ifx_blob->BLOB.blob_data.loc_fname != NULL) {
|
|
if (php_copy_file(param, Ifx_blob->BLOB.blob_data.loc_fname TSRMLS_CC) == FAILURE) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create blob-resource file. File copy failed: %s", param);
|
|
return -1;
|
|
}
|
|
Ifx_blob->BLOB.blob_data.loc_size = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return zend_list_insert(Ifx_blob,le_idresult);
|
|
}
|
|
|
|
static long php_intifx_init_blob(loc_t *blob, long mode, long new TSRMLS_DC)
|
|
{
|
|
if (new) {
|
|
memset(blob, 0, sizeof(loc_t));
|
|
}
|
|
|
|
blob->loc_status = 0;
|
|
blob->loc_type = SQLTEXT;
|
|
blob->loc_xfercount = 0;
|
|
blob->loc_indicator = 0;
|
|
|
|
if (mode == BLMODE_INMEM) {
|
|
return php_intifx_init_blob_inmem(blob, new TSRMLS_CC);
|
|
} else {
|
|
return php_intifx_init_blob_infile(blob, new TSRMLS_CC);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static long php_intifx_init_blob_inmem(loc_t *blob, long new TSRMLS_DC)
|
|
{
|
|
blob->loc_loctype = LOCMEMORY;
|
|
|
|
if (new) {
|
|
blob->loc_buffer = NULL;
|
|
blob->loc_bufsize = -1;
|
|
blob->loc_size = 0;
|
|
}
|
|
|
|
blob->loc_mflags = 0;
|
|
blob->loc_oflags = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static long php_intifx_init_blob_infile(loc_t *blob, long new TSRMLS_DC)
|
|
{
|
|
char *filename;
|
|
|
|
blob->loc_loctype = LOCFNAME;
|
|
|
|
if (new) {
|
|
|
|
filename = php_intifx_create_tmpfile(TSRMLS_C);
|
|
|
|
if (filename == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
|
|
blob->loc_fname = filename;
|
|
blob->loc_size = 0;
|
|
blob->loc_fd = -1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static void php_intifx_release_blob(loc_t *blob TSRMLS_DC)
|
|
{
|
|
|
|
#if IFX_VERSION < 724 /* this Informix memory leak is fixed from 7.24 on */
|
|
/* according to the current PERL DBD::Informix */
|
|
/* and otherwise I get segmenation violations with 7.30 */
|
|
|
|
/* Not set to NULL, so function will free resources */
|
|
#else
|
|
/* Set to NULL so php_intifx_release_blob() doens't try to free stuff it shouldn't */
|
|
|
|
if (blob->loc_loctype == LOCMEMORY) {
|
|
blob->loc_buffer = NULL;
|
|
}
|
|
#endif
|
|
|
|
switch (blob->loc_loctype) {
|
|
|
|
case LOCMEMORY:
|
|
if (blob->loc_buffer != NULL) {
|
|
efree(blob->loc_buffer);
|
|
blob->loc_buffer = NULL;
|
|
}
|
|
break;
|
|
|
|
case LOCFNAME:
|
|
if (blob->loc_fd >= 0) {
|
|
close(blob->loc_fd);
|
|
}
|
|
blob->loc_fd = -1;
|
|
|
|
if (blob->loc_fname != NULL) {
|
|
unlink(blob->loc_fname);
|
|
efree(blob->loc_fname);
|
|
blob->loc_fname = NULL;
|
|
}
|
|
break;
|
|
|
|
case LOCFILE:
|
|
case LOCUSER:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_copy_blob(int bid)
|
|
**
|
|
** duplicates the given blob-object
|
|
** bid: Id of Blobobject
|
|
**
|
|
** return false on error otherwise the new Blob-Object-id
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_copy_blob(int bid)
|
|
Duplicates the given blob-object */
|
|
PHP_FUNCTION(ifx_copy_blob)
|
|
{
|
|
zval **pbid;
|
|
long newid;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pbid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
|
|
newid = php_intifx_copy_blob(Z_LVAL_PP(pbid), &EG(regular_list) TSRMLS_CC);
|
|
|
|
if (newid < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(newid);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_copy_blob(long bid, HashTable *list)
|
|
*
|
|
* duplicates the given blob-object in the PHP resource list
|
|
* bid: Id of Blobobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error otherwise the new Blob-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_copy_blob(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob, *Ifx_blob_orig;
|
|
loc_t *locator, *locator_orig;
|
|
int type;
|
|
|
|
Ifx_blob_orig = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || !(Ifx_blob_orig->type == TYPE_BLBYTE || Ifx_blob_orig->type == TYPE_BLTEXT)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix blob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
Ifx_blob = emalloc(sizeof(IFX_IDRES));
|
|
if (Ifx_blob == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
|
|
memset(Ifx_blob, 0, sizeof(IFX_IDRES));
|
|
|
|
Ifx_blob->type = Ifx_blob_orig->type;
|
|
Ifx_blob->BLOB.mode = Ifx_blob_orig->BLOB.mode;
|
|
|
|
locator = &(Ifx_blob->BLOB.blob_data);
|
|
locator_orig = &(Ifx_blob_orig->BLOB.blob_data);
|
|
|
|
if (php_intifx_init_blob(locator, Ifx_blob->BLOB.mode, 1 TSRMLS_CC) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_blob->BLOB.mode == BLMODE_INMEM) {
|
|
char *content;
|
|
if (locator_orig->loc_bufsize >= 0 && locator_orig->loc_buffer != NULL) {
|
|
if ((content = emalloc(locator_orig->loc_bufsize)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
memcpy(content,locator_orig->loc_buffer, locator_orig->loc_bufsize);
|
|
locator->loc_buffer = content;
|
|
locator->loc_bufsize = locator_orig->loc_bufsize;
|
|
locator->loc_size = locator_orig->loc_size;
|
|
}
|
|
} else { /* BLMODE_INFILE */
|
|
|
|
if (locator_orig->loc_size) {
|
|
php_copy_file(locator_orig->loc_fname, locator->loc_fname TSRMLS_CC);
|
|
}
|
|
|
|
}
|
|
|
|
return zend_list_insert(Ifx_blob, le_idresult);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_free_blob(int bid)
|
|
**
|
|
** deletes the blob-object
|
|
** bid: Id of Blobobject
|
|
** return false on error otherwise true
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_free_blob(int bid)
|
|
Deletes the blob-object */
|
|
PHP_FUNCTION(ifx_free_blob)
|
|
{
|
|
zval **pid;
|
|
long ret;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pid);
|
|
|
|
ret = php_intifx_free_blob(Z_LVAL_PP(pid), &EG(regular_list) TSRMLS_CC);
|
|
if (ret < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_free_blob(long bid, HashTable *list)
|
|
*
|
|
* deletes the blob-object from the PHP Resource List
|
|
* bid: Id of Blobobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error otherwise 0
|
|
* FREES BYTE-MEMORY WITH EFREE()
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_free_blob(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob;
|
|
int type;
|
|
|
|
Ifx_blob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_blob->type == TYPE_BLTEXT || Ifx_blob->type == TYPE_BLBYTE)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix blob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (!(Ifx_blob->type == TYPE_BLTEXT || Ifx_blob->type == TYPE_BLBYTE)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix BYTE or TEXT type", bid);
|
|
return -1;
|
|
}
|
|
|
|
zend_list_delete(bid);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** string ifx_get_blob(int bid)
|
|
**
|
|
** returns the content of the blob-object
|
|
** bid: Id of Blobobject
|
|
** return the content
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto string ifx_get_blob(int bid)
|
|
Returns the content of the blob-object */
|
|
PHP_FUNCTION(ifx_get_blob)
|
|
{
|
|
zval **pbid;
|
|
char *content;
|
|
long len;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pbid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
|
|
len = php_intifx_get_blob(Z_LVAL_PP(pbid), &EG(regular_list), &content TSRMLS_CC);
|
|
if (content == NULL || len < 0) {
|
|
RETURN_STRING(php_intifx_null(TSRMLS_C), 1);
|
|
}
|
|
RETURN_STRINGL(content, len, 1);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_get_blob(long bid, HashTable *list, char** content)
|
|
*
|
|
* returns the content of the blob-object
|
|
* bid: Id of Blobobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error
|
|
* returns the pointer to the content in char** content and the amount of content in bytes
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_get_blob(long bid, HashTable *list, char** content TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob;
|
|
int type;
|
|
|
|
Ifx_blob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_blob->type == TYPE_BLTEXT || Ifx_blob->type == TYPE_BLBYTE)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix blob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_blob->BLOB.mode == BLMODE_INMEM) {
|
|
*content = Ifx_blob->BLOB.blob_data.loc_buffer;
|
|
return Ifx_blob->BLOB.blob_data.loc_size;
|
|
}
|
|
*content = Ifx_blob->BLOB.blob_data.loc_fname;
|
|
return strlen(Ifx_blob->BLOB.blob_data.loc_fname);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* loc_t *php_intifx_get_blobloc(long bid, HashTable *list TSRMLS_DC)
|
|
*
|
|
* returns the blob-locator-structur
|
|
* bid: Id of Blobobject
|
|
* list: internal hashlist of php
|
|
* return NULL on error or the pointer to the locator-structur
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static loc_t *php_intifx_get_blobloc(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob;
|
|
int type;
|
|
|
|
Ifx_blob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_blob->type == TYPE_BLTEXT || Ifx_blob->type == TYPE_BLBYTE)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix blob-result index", bid);
|
|
return NULL;
|
|
}
|
|
return &(Ifx_blob->BLOB.blob_data);
|
|
}
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int update_blob(int bid, string content)
|
|
**
|
|
** updates the content of the blob-object
|
|
** bid: Id of Blobobject
|
|
** content: string of new data
|
|
** return false on error otherwise true
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_update_blob(int bid, string content)
|
|
Updates the content of the blob-object */
|
|
PHP_FUNCTION(ifx_update_blob)
|
|
{
|
|
zval **pbid, **pparam;
|
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &pbid, &pparam) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
convert_to_string_ex(pparam);
|
|
|
|
if (php_intifx_update_blob(Z_LVAL_PP(pbid), Z_STRVAL_PP(pparam), Z_STRLEN_PP(pparam), &EG(regular_list) TSRMLS_CC) < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_update_blob(long bid, char* param, long len, HashTable *list)
|
|
*
|
|
* updates the content of the blob-object
|
|
* bid: Id of Blobobject
|
|
* param: string of new data
|
|
* len: length of string
|
|
* list: internal hashlist of php
|
|
* return nothing
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_update_blob(long bid, char* param, long len, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_blob;
|
|
int type;
|
|
|
|
Ifx_blob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_blob->type == TYPE_BLTEXT || Ifx_blob->type == TYPE_BLBYTE)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix blob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_blob->BLOB.mode == BLMODE_INMEM) {
|
|
char *content;
|
|
|
|
if (Ifx_blob->BLOB.blob_data.loc_buffer != NULL) {
|
|
efree(Ifx_blob->BLOB.blob_data.loc_buffer);
|
|
}
|
|
if (len >= 0) {
|
|
if ((content = emalloc(len)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
memcpy(content, param, len);
|
|
Ifx_blob->BLOB.blob_data.loc_buffer = content;
|
|
Ifx_blob->BLOB.blob_data.loc_bufsize = len;
|
|
Ifx_blob->BLOB.blob_data.loc_size = len;
|
|
} else {
|
|
Ifx_blob->BLOB.blob_data.loc_buffer = NULL;
|
|
Ifx_blob->BLOB.blob_data.loc_bufsize = -1;
|
|
Ifx_blob->BLOB.blob_data.loc_size = -1;
|
|
}
|
|
Ifx_blob->BLOB.blob_data.loc_mflags = 0;
|
|
Ifx_blob->BLOB.blob_data.loc_oflags = 0;
|
|
} else {
|
|
char *filename;
|
|
|
|
if (Ifx_blob->BLOB.blob_data.loc_fname != NULL) {
|
|
efree(Ifx_blob->BLOB.blob_data.loc_fname);
|
|
}
|
|
if ((filename = emalloc(len + 1)) == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create blob-resource");
|
|
return -1;
|
|
}
|
|
memcpy(filename, param, len);
|
|
filename[len] = 0;
|
|
Ifx_blob->BLOB.blob_data.loc_fname = filename;
|
|
Ifx_blob->BLOB.blob_data.loc_size = -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
* internal function
|
|
*
|
|
* php_intifx_create_tmpfile(TSRMLS_D)
|
|
* creates a temporary file to store a blob in
|
|
*-------------------------------------------------
|
|
*/
|
|
static char* php_intifx_create_tmpfile(TSRMLS_D)
|
|
{
|
|
char filename[10];
|
|
char *blobdir;
|
|
char *retval;
|
|
char *opened_path;
|
|
FILE *fp;
|
|
|
|
if ((blobdir = getenv("php_blobdir")) == NULL) {
|
|
blobdir = ".";
|
|
}
|
|
|
|
sprintf(filename, "blb");
|
|
|
|
if ((fp = php_open_temporary_file(blobdir, filename, &opened_path TSRMLS_CC))) {
|
|
fclose(fp);
|
|
retval = estrndup(opened_path, strlen(opened_path));
|
|
efree(opened_path);
|
|
} else {
|
|
retval = NULL;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* int php_intifx_alloc_ibind(IFX_RES *Ifx_Result, int items TSRMLS_DC)
|
|
*
|
|
* Allocates descriptors for input parameters
|
|
* return 0 for error. 1 for ok
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_alloc_ibind(IFX_RES *Ifx_Result, int items TSRMLS_DC)
|
|
{
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *i_bind = Ifx_Result->i_descrpid;
|
|
int bind_size = items;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
if (items > Ifx_Result->numicols) {
|
|
|
|
if (Ifx_Result->numicols > 0) {
|
|
EXEC SQL DEALLOCATE DESCRIPTOR :i_bind;
|
|
if (ifx_check() < 0) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
EXEC SQL ALLOCATE DESCRIPTOR :i_bind WITH MAX :bind_size;
|
|
if (ifx_check() < 0) {
|
|
return 0;
|
|
}
|
|
|
|
Ifx_Result->numicols = items;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* int php_intifx_preparse(char *statement TSRMLS_DC)
|
|
*
|
|
* Count the placeholders (?) parameters in the statement
|
|
* return -1 for error. 0 or number of question marks
|
|
*
|
|
* Thanks to DBD-Informix
|
|
*
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_preparse(char *statement TSRMLS_DC)
|
|
{
|
|
char end_quote = '\0';
|
|
char *src;
|
|
char *dst;
|
|
int idx = 0;
|
|
int style = 0;
|
|
int laststyle = 0;
|
|
char ch;
|
|
|
|
src = statement;
|
|
dst = statement;
|
|
|
|
while ((ch = *src++) != '\0') {
|
|
if (ch == end_quote) {
|
|
end_quote = '\0';
|
|
} else if (end_quote != '\0') {
|
|
*dst++ = ch;
|
|
continue;
|
|
} else if (ch == '\'' || ch == '\"') {
|
|
end_quote = ch;
|
|
} else if (ch == '{') {
|
|
end_quote = '}';
|
|
} else if (ch == '-' && *src == '-') {
|
|
end_quote = '\n';
|
|
}
|
|
|
|
if (ch == '?') {
|
|
/* X/Open standard */
|
|
*dst++ = '?';
|
|
idx++;
|
|
style = 3;
|
|
} else {
|
|
/* Perhaps ':=' PL/SQL construct or dbase:table in Informix */
|
|
/* Or it could be :2 or :22 as part of a DATETIME/INTERVAL */
|
|
*dst++ = ch;
|
|
continue;
|
|
}
|
|
|
|
if (laststyle && style != laststyle) {
|
|
return -1;
|
|
}
|
|
laststyle = style;
|
|
}
|
|
|
|
*dst = '\0';
|
|
return(idx);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* int php_intifx_count_descriptors(char *p_statemid TSRMLS_DC)
|
|
*
|
|
* count the number of descriptors allocated for a certain statement
|
|
* return 384 or number of descriptors
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_count_descriptors(char *p_statemid TSRMLS_DC)
|
|
{
|
|
EXEC SQL BEGIN DECLARE SECTION;
|
|
char *statemid = p_statemid;
|
|
EXEC SQL END DECLARE SECTION;
|
|
|
|
struct sqlda *s_da;
|
|
int ret = 384;
|
|
|
|
EXEC SQL DESCRIBE :statemid INTO s_da;
|
|
|
|
if (ifx_check() >= 0) {
|
|
|
|
ret = s_da->sqld;
|
|
|
|
/*
|
|
* Thanks to DBD-Informix
|
|
*/
|
|
|
|
#if (ESQLC_VERSION >= 720 || (ESQLC_VERSION >= 501 && ESQLC_VERSION < 600))
|
|
SqlFreeMem(s_da, SQLDA_FREE);
|
|
} else {
|
|
free(s_da);
|
|
#endif
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** void ifx_blobinfile_mode(int mode)
|
|
**
|
|
** sets the default blob-mode for all select-queries
|
|
** mode=0: save Byte-Blobs in momory
|
|
** mode=1: save Byte-Blobs in a file
|
|
** return nothing
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_blobinfile_mode(int mode)
|
|
Sets the default blob-mode for all select-queries */
|
|
PHP_FUNCTION(ifx_blobinfile_mode)
|
|
{
|
|
zval **pmode;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pmode) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pmode);
|
|
|
|
IFXG(blobinfile) = Z_LVAL_PP(pmode);
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** void ifx_textasvarchar(int mode)
|
|
**
|
|
** sets the default text-mode for all select-queries
|
|
** mode=0: select returns a blob-id
|
|
** mode=1: select returns a varchar with text-content
|
|
** return nothing
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_textasvarchar(int mode)
|
|
Sets the default text-mode for all select-queries */
|
|
PHP_FUNCTION(ifx_textasvarchar)
|
|
{
|
|
zval **pmode;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pmode) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pmode);
|
|
|
|
IFXG(textasvarchar) = Z_LVAL_PP(pmode);
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** void ifx_byteasvarchar(int mode)
|
|
**
|
|
** sets the default byte-mode for all select-queries
|
|
** mode=0: select returns a blob-id
|
|
** mode=1: select returns a varchar with byte-content
|
|
** return nothing
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_byteasvarchar(int mode)
|
|
Sets the default byte-mode for all select-queries */
|
|
PHP_FUNCTION(ifx_byteasvarchar)
|
|
{
|
|
zval **pmode;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pmode) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pmode);
|
|
|
|
IFXG(byteasvarchar) = Z_LVAL_PP(pmode);
|
|
RETURN_TRUE;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** void ifx_nullformat(int mode)
|
|
**
|
|
** sets the default return value of a NULL-value on a fetch-row
|
|
** mode=0: return ""
|
|
** mode=1: return "NULL"
|
|
** return nothing
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_nullformat(int mode)
|
|
Sets the default return value of a NULL-value on a fetch-row */
|
|
PHP_FUNCTION(ifx_nullformat)
|
|
{
|
|
zval **pmode;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pmode) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pmode);
|
|
|
|
IFXG(nullformat) = Z_LVAL_PP(pmode);
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* void php_intifx_null()
|
|
*
|
|
* return the NULL-string depending on .nullformat
|
|
* return "" or "NULL"
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static char* php_intifx_null(TSRMLS_D)
|
|
{
|
|
char* tmp;
|
|
|
|
if (IFXG(nullformat) == 0) {
|
|
tmp = IFXG(nullvalue);
|
|
} else {
|
|
tmp = IFXG(nullstring);
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_create_char(string param)
|
|
**
|
|
** creates an char-object
|
|
** param: content
|
|
** return false on error otherwise the new char-Object-id
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifx_create_char(string param)
|
|
Creates a char-object */
|
|
PHP_FUNCTION(ifx_create_char)
|
|
{
|
|
zval **pparam;
|
|
long id;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pparam) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_string_ex(pparam);
|
|
|
|
id = php_intifx_create_char(Z_STRVAL_PP(pparam), Z_STRLEN_PP(pparam), &EG(regular_list) TSRMLS_CC);
|
|
|
|
if (id < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(id);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_create_char(char* param, long len, HashTable *list TSRMLS_DC)
|
|
*
|
|
* creates an char-object
|
|
* param: content
|
|
* len: length of param
|
|
* list: internal hashlist of php
|
|
* return -1 on error otherwise the new char-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_create_char(char* param, long len, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_char;
|
|
|
|
Ifx_char = emalloc(sizeof(IFX_IDRES));
|
|
if (Ifx_char == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create char-resource");
|
|
return -1;
|
|
}
|
|
|
|
Ifx_char->type = TYPE_CHAR;
|
|
|
|
if (param == NULL || len < 0) {
|
|
Ifx_char->CHAR.char_data = NULL;
|
|
Ifx_char->CHAR.len = 0;
|
|
} else {
|
|
Ifx_char->CHAR.char_data = emalloc(len + 1);
|
|
if (Ifx_char->CHAR.char_data == NULL) {
|
|
efree(Ifx_char);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create char-resource");
|
|
return -1;
|
|
}
|
|
memcpy(Ifx_char->CHAR.char_data, param,len);
|
|
Ifx_char->CHAR.char_data[len] = 0;
|
|
Ifx_char->CHAR.len = len;
|
|
}
|
|
return zend_list_insert(Ifx_char, le_idresult);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** string ifx_get_char(int bid)
|
|
**
|
|
** returns the content of the char-object
|
|
** bid: Id of charobject
|
|
** return the content
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto string ifx_get_char(int bid)
|
|
Returns the content of the char-object */
|
|
PHP_FUNCTION(ifx_get_char)
|
|
{
|
|
zval **pbid;
|
|
char *content;
|
|
long len;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pbid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
|
|
len = php_intifx_get_char(Z_LVAL_PP(pbid), &EG(regular_list), &content TSRMLS_CC);
|
|
if (content == NULL || len < 0) {
|
|
RETURN_STRING("", 1);
|
|
}
|
|
RETURN_STRINGL(content, len, 1);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_get_char(long bid, HashTable *list, char** content)
|
|
*
|
|
* returns the content of the char-object
|
|
* bid: Id of charobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error
|
|
* returns the pointer to the content in char** content and the amount of content in bytes
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
static long php_intifx_get_char(long bid, HashTable *list, char** content TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_char;
|
|
int type;
|
|
|
|
Ifx_char = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_char->type == TYPE_CHAR)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix char-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
*content = Ifx_char->CHAR.char_data;
|
|
return Ifx_char->CHAR.len;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_free_char(int bid)
|
|
**
|
|
** deletes the char-object
|
|
** bid: Id of charobject
|
|
** return false on error otherwise true
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_free_char(int bid)
|
|
Deletes the char-object */
|
|
PHP_FUNCTION(ifx_free_char)
|
|
{
|
|
zval **pid;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pid);
|
|
|
|
if (php_intifx_free_char(Z_LVAL_PP(pid), &EG(regular_list) TSRMLS_CC) < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_free_char(long bid, HashTable *list TSRMLS_DC)
|
|
*
|
|
* deletes the char-object
|
|
* bid: Id of Charobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error otherwise 0
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_free_char(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_char;
|
|
int type;
|
|
|
|
Ifx_char = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_char->type == TYPE_CHAR)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix char-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_char->CHAR.char_data != NULL) {
|
|
efree(Ifx_char->CHAR.char_data);
|
|
}
|
|
zend_list_delete(bid);
|
|
efree(Ifx_char);
|
|
return 0;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifx_update_char(int bid, string content)
|
|
**
|
|
** updates the content of the char-object
|
|
** bid: Id of charobject
|
|
** content: string of new data
|
|
** return false on error otherwise true
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifx_update_char(int bid, string content)
|
|
Updates the content of the char-object */
|
|
PHP_FUNCTION(ifx_update_char)
|
|
{
|
|
zval **pbid, **pparam;
|
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &pbid, &pparam) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
convert_to_string_ex(pparam);
|
|
|
|
if (php_intifx_update_char(Z_LVAL_PP(pbid), Z_STRVAL_PP(pparam), Z_STRLEN_PP(pparam), &EG(regular_list) TSRMLS_CC) < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_update_char(long bid, char* param, long len, HashTable *list)
|
|
*
|
|
* updates the content of the char-object
|
|
* bid: Id of charobject
|
|
* param: string of new data
|
|
* len: length of string
|
|
* list: internal hashlist of php
|
|
* return nothing
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifx_update_char(long bid, char* param, long len, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_char;
|
|
int type;
|
|
|
|
Ifx_char = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult && !(Ifx_char->type == TYPE_CHAR)) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix char-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_char->CHAR.char_data != NULL) {
|
|
efree(Ifx_char->CHAR.char_data);
|
|
}
|
|
Ifx_char->CHAR.char_data = NULL;
|
|
Ifx_char->CHAR.len = 0;
|
|
|
|
if (param == NULL || len < 0) {
|
|
Ifx_char->CHAR.char_data = NULL;
|
|
Ifx_char->CHAR.len = 0;
|
|
} else {
|
|
Ifx_char->CHAR.char_data = emalloc(len + 1);
|
|
if (Ifx_char->CHAR.char_data == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create char-resource");
|
|
return -1;
|
|
}
|
|
memcpy(Ifx_char->CHAR.char_data, param,len);
|
|
Ifx_char->CHAR.char_data[len] = 0;
|
|
Ifx_char->CHAR.len = len;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
$ifdef HAVE_IFX_IUS;
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_create_slob(int mode)
|
|
**
|
|
** creates an slob-object and opens it
|
|
** mode: 1=LO_RDONLY, 2=LO_WRONLY, 4=LO_APPEND, 8=LO_RDWR, 16=LO_BUFFER, 32=LO_NOBUFFER -> or-mask
|
|
** return false on error otherwise the new Slob-Object-id
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifxus_create_slob(int mode)
|
|
Creates a slob-object and opens it */
|
|
PHP_FUNCTION(ifxus_create_slob)
|
|
{
|
|
zval **pmode;
|
|
long id;
|
|
long mode, create_mode;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pmode) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
|
|
convert_to_long_ex(pmode);
|
|
mode = Z_LVAL_PP(pmode);
|
|
|
|
create_mode = 0;
|
|
if ((mode & 1) != 0) {
|
|
create_mode |= LO_RDONLY;
|
|
}
|
|
if ((mode & 2) != 0) {
|
|
create_mode |= LO_WRONLY;
|
|
}
|
|
if ((mode & 4) != 0) {
|
|
create_mode |= LO_APPEND;
|
|
}
|
|
if ((mode & 8) != 0) {
|
|
create_mode |= LO_RDWR;
|
|
}
|
|
if ((mode & 16) != 0) {
|
|
create_mode |= LO_BUFFER;
|
|
}
|
|
if ((mode & 32) != 0) {
|
|
create_mode |= LO_NOBUFFER;
|
|
}
|
|
|
|
id = php_intifxus_create_slob(create_mode, &EG(regular_list) TSRMLS_CC);
|
|
|
|
if (id < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(id);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifx_create_slob(long create_mode, HashTable *list TSRMLS_DC)
|
|
*
|
|
* creates an slob-object and opens it
|
|
* mode: 1=LO_RDONLY, 2=LO_WRONLY, 4=LO_APPEND, 8=LO_RDWR, 16=LO_BUFFER, 32=LO_NOBUFFER -> or-mask
|
|
* list: internal hashlist of php
|
|
* return -1 on error otherwise the new Blob-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifxus_create_slob(long create_mode, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_slob;
|
|
int errcode;
|
|
|
|
Ifx_slob = emalloc(sizeof(IFX_IDRES));
|
|
if (Ifx_slob == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create slob-resource");
|
|
return -1;
|
|
}
|
|
|
|
errcode = ifx_lo_def_create_spec(&(Ifx_slob->SLOB.createspec));
|
|
if (errcode < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create slob-resource: %d", errcode);
|
|
return -1;
|
|
}
|
|
|
|
Ifx_slob->type = TYPE_SLOB;
|
|
Ifx_slob->SLOB.lofd = ifx_lo_create(Ifx_slob->SLOB.createspec, create_mode, &(Ifx_slob->SLOB.slob_data), &errcode);
|
|
if (errcode < 0 || Ifx_slob->SLOB.lofd < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create slob-resource: %d", errcode);
|
|
return -1;
|
|
}
|
|
return zend_list_insert(Ifx_slob, le_idresult);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_free_slob(int bid)
|
|
**
|
|
** deletes the slob-object
|
|
** bid: Id of Slobobject
|
|
** return false on error otherwise true
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifxus_free_slob(int bid)
|
|
Deletes the slob-object */
|
|
PHP_FUNCTION(ifxus_free_slob)
|
|
{
|
|
zval **pid;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pid);
|
|
|
|
if (php_intifxus_free_slob(Z_LVAL_PP(pid), &EG(regular_list) TSRMLS_CC) < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifxus_free_slob(long bid, HashTable *list)
|
|
*
|
|
* deletes the slob-object
|
|
* bid: Id of Slobobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error otherwise 0
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifxus_free_slob(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_slob;
|
|
int type;
|
|
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (php_intifxus_close_slob(bid, &EG(regular_list) TSRMLS_CC) < 0) {
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_slob->SLOB.createspec != NULL) {
|
|
ifx_lo_spec_free(Ifx_slob->SLOB.createspec);
|
|
Ifx_slob->SLOB.createspec = NULL;
|
|
}
|
|
efree(Ifx_slob);
|
|
zend_list_delete(bid);
|
|
return 0;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_close_slob(int bid)
|
|
**
|
|
** deletes the slob-object
|
|
** bid: Id of Slobobject
|
|
** return false on error otherwise true
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto bool ifxus_close_slob(int bid)
|
|
Deletes the slob-object */
|
|
PHP_FUNCTION(ifxus_close_slob)
|
|
{
|
|
zval **pid;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pid);
|
|
|
|
if (php_intifxus_close_slob(Z_LVAL_PP(pid), &EG(regular_list) TSRMLS_CC) < 0) {
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_TRUE;
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifxus_close_slob(long bid, HashTable *list)
|
|
*
|
|
* deletes the slob-object
|
|
* bid: Id of Slobobject
|
|
* list: internal hashlist of php
|
|
*
|
|
* return -1 on error otherwise 0
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifxus_close_slob(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_slob;
|
|
int type;
|
|
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_slob->SLOB.lofd < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Slob-resource already closed");
|
|
return -1;
|
|
}
|
|
|
|
if (ifx_lo_close(Ifx_slob->SLOB.lofd) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't close slob-resource");
|
|
return -1;
|
|
}
|
|
Ifx_slob->SLOB.lofd = -1;
|
|
return 0;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_open_slob(long bid, int mode)
|
|
**
|
|
** opens an slob-object
|
|
** bid: existing slob-id
|
|
** mode: 1=LO_RDONLY, 2=LO_WRONLY, 4=LO_APPEND, 8=LO_RDWR, 16=LO_BUFFER, 32=LO_NOBUFFER -> or-mask
|
|
** return false on error otherwise the new Slob-Object-id
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifxus_open_slob(int bid, int mode)
|
|
Opens an slob-object */
|
|
PHP_FUNCTION(ifxus_open_slob)
|
|
{
|
|
zval **pbid, **pmode;
|
|
long mode,create_mode;
|
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(1, &pbid, &pmode) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pmode);
|
|
convert_to_long_ex(pbid);
|
|
|
|
mode = Z_LVAL_PP(pmode);
|
|
create_mode = 0;
|
|
if ((mode & 1) != 0) {
|
|
create_mode|=LO_RDONLY;
|
|
}
|
|
if ((mode & 2) != 0) {
|
|
create_mode|=LO_WRONLY;
|
|
}
|
|
if ((mode & 4) != 0) {
|
|
create_mode|=LO_APPEND;
|
|
}
|
|
if ((mode & 8) != 0) {
|
|
create_mode|=LO_RDWR;
|
|
}
|
|
if ((mode & 16) != 0) {
|
|
create_mode|=LO_BUFFER;
|
|
}
|
|
if ((mode & 32) != 0) {
|
|
create_mode|=LO_NOBUFFER;
|
|
}
|
|
|
|
RETURN_LONG(php_intifxus_open_slob(Z_LVAL_PP(pbid), create_mode, &EG(regular_list) TSRMLS_CC));
|
|
}
|
|
/* }}} */
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifxus_open_slob(long bid,long create_mode, HashTable *list)
|
|
*
|
|
* opens an slob-object
|
|
* mode: 1=LO_RDONLY, 2=LO_WRONLY, 4=LO_APPEND, 8=LO_RDWR, 16=LO_BUFFER, 32=LO_NOBUFFER -> or-mask
|
|
* list: internal hashlist of php
|
|
* return -1 on error otherwise the new Blob-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifxus_open_slob(long bid, long create_mode, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_slob;
|
|
int errcode;
|
|
int type;
|
|
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
return -1;
|
|
}
|
|
|
|
if (Ifx_slob->SLOB.lofd > 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Slob-resource already open");
|
|
return -1;
|
|
}
|
|
|
|
Ifx_slob->SLOB.lofd = ifx_lo_open(&(Ifx_slob->SLOB.slob_data), create_mode, &errcode);
|
|
if (errcode < 0 || Ifx_slob->SLOB.lofd < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't open slob-resource: %d", errcode);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* long php_intifxus_new_slob(HashTable *list TSRMLS_DC)
|
|
*
|
|
* creates an slob-object but don't open it
|
|
* list: internal hashlist of php
|
|
* return -1 on error otherwise the new slob-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static long php_intifxus_new_slob(HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_slob;
|
|
|
|
Ifx_slob = emalloc(sizeof(IFX_IDRES));
|
|
if (Ifx_slob == NULL) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't create slob-resource");
|
|
return -1;
|
|
}
|
|
|
|
Ifx_slob->type = TYPE_SLOB;
|
|
Ifx_slob->SLOB.lofd = -1;
|
|
Ifx_slob->SLOB.createspec = NULL;
|
|
return zend_list_insert(Ifx_slob, le_idresult);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
* internal function
|
|
* ifx_lo_t *php_intifxus_get_slobloc(long bid, HashTable *list)
|
|
*
|
|
* retuens the ifx_lo_t-structure of a slob-object
|
|
* list: internal hashlist of php
|
|
* return -1 on error otherwise the new Blob-Object-id
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
static ifx_lo_t *php_intifxus_get_slobloc(long bid, HashTable *list TSRMLS_DC)
|
|
{
|
|
IFX_IDRES *Ifx_slob;
|
|
int type;
|
|
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
return NULL;
|
|
}
|
|
return &(Ifx_slob->SLOB.slob_data);
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_tell_slob(long bid)
|
|
**
|
|
** returns the current file or seek position of an open slob-object
|
|
** bid: existing slob-id
|
|
** return false on error otherwise the seek-position
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifxus_tell_slob(int bid)
|
|
Returns the current file or seek position of an open slob-object */
|
|
PHP_FUNCTION(ifxus_tell_slob)
|
|
{
|
|
zval **pbid;
|
|
long bid;
|
|
IFX_IDRES *Ifx_slob;
|
|
ifx_int8_t akt_seek_pos;
|
|
int type;
|
|
long lakt_seek_pos;
|
|
|
|
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &pbid) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
bid = Z_LVAL_PP(pbid);
|
|
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (ifx_lo_tell(Ifx_slob->SLOB.lofd, &akt_seek_pos) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't perform tell-operation");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (ifx_int8tolong(&akt_seek_pos, &lakt_seek_pos) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Seek-position to large for long");
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(lakt_seek_pos);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_seek_slob(long bid, int mode, long offset)
|
|
**
|
|
** sets the current file or seek position of an open slob-object
|
|
** bid: existing slob-id
|
|
** mode: 0=LO_SEEK_SET, 1=LO_SEEK_CUR, 2=LO_SEEK_END
|
|
** offset: byte-offset
|
|
** return false on error otherwise the seek-position
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifxus_seek_slob(int bid, int mode, long offset)
|
|
Sets the current file or seek position of an open slob-object */
|
|
PHP_FUNCTION(ifxus_seek_slob)
|
|
{
|
|
zval **pbid, **pmode, **poffset;
|
|
long bid,lakt_seek_pos;
|
|
IFX_IDRES *Ifx_slob;
|
|
ifx_int8_t akt_seek_pos, offset;
|
|
int type, mode;
|
|
|
|
if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &pbid, &pmode, &poffset) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
convert_to_long_ex(pmode);
|
|
convert_to_long_ex(poffset);
|
|
|
|
bid = Z_LVAL_PP(pbid);
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
mode = LO_SEEK_SET;
|
|
if (Z_LVAL_PP(pmode) == 1) {
|
|
mode = LO_SEEK_CUR;
|
|
}
|
|
if (Z_LVAL_PP(pmode) == 2) {
|
|
mode = LO_SEEK_END;
|
|
}
|
|
|
|
ifx_int8cvlong(Z_LVAL_PP(poffset), &offset);
|
|
if (ifx_lo_seek(Ifx_slob->SLOB.lofd, &offset, mode, &akt_seek_pos) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't perform seek-operation");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if (ifx_int8tolong(&akt_seek_pos, &lakt_seek_pos) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Seek-position to large for long");
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_LONG(lakt_seek_pos);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_read_slob(long bid, long nbytes)
|
|
**
|
|
** reads nbytes of the slob-object
|
|
** bid: existing slob-id
|
|
** nbytes: bytes zu read
|
|
** return false on error otherwise the string
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto string ifxus_read_slob(int bid, int nbytes)
|
|
Reads nbytes of the slob-object */
|
|
PHP_FUNCTION(ifxus_read_slob)
|
|
{
|
|
zval **pbid, **pnbytes;
|
|
long bid, nbytes;
|
|
IFX_IDRES *Ifx_slob;
|
|
int errcode, type;
|
|
char *buffer;
|
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &pbid, &pnbytes) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
convert_to_long_ex(pnbytes);
|
|
|
|
bid = Z_LVAL_PP(pbid);
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
nbytes = Z_LVAL_PP(pnbytes);
|
|
buffer = emalloc(nbytes);
|
|
|
|
if (ifx_lo_read(Ifx_slob->SLOB.lofd, buffer, nbytes, &errcode) < 0) {
|
|
efree(buffer);
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error reading slob: %d", errcode);
|
|
RETURN_FALSE;
|
|
}
|
|
RETURN_STRINGL(buffer, nbytes, 0);
|
|
}
|
|
/* }}} */
|
|
|
|
/* ----------------------------------------------------------------------
|
|
** int ifxus_write_slob(long bid, string content)
|
|
**
|
|
** writes a string into the slob-object
|
|
** bid: existing slob-id
|
|
** content: content to write
|
|
** return false on error otherwise bytes written
|
|
** ----------------------------------------------------------------------
|
|
*/
|
|
|
|
/* {{{ proto int ifxus_write_slob(int bid, string content)
|
|
Writes a string into the slob-object */
|
|
PHP_FUNCTION(ifxus_write_slob)
|
|
{
|
|
zval **pbid, **pcontent;
|
|
long bid, nbytes;
|
|
IFX_IDRES *Ifx_slob;
|
|
int errcode, type;
|
|
char *buffer;
|
|
|
|
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &pbid, &pcontent) == FAILURE) {
|
|
WRONG_PARAM_COUNT;
|
|
}
|
|
convert_to_long_ex(pbid);
|
|
convert_to_string_ex(pcontent);
|
|
|
|
bid = Z_LVAL_PP(pbid);
|
|
Ifx_slob = (IFX_IDRES *) zend_list_find(bid, &type);
|
|
if (type != le_idresult || Ifx_slob->type != TYPE_SLOB) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a Informix slob-result index", bid);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
buffer = Z_STRVAL_PP(pcontent);
|
|
nbytes = Z_STRLEN_PP(pcontent);
|
|
|
|
if (nbytes <= 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "String has no content");
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
if ((nbytes = ifx_lo_write(Ifx_slob->SLOB.lofd, buffer, nbytes, &errcode)) < 0) {
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error writing slob: %d", errcode);
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
RETURN_LONG(nbytes);
|
|
}
|
|
/* }}} */
|
|
|
|
$endif;
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Local variables:
|
|
* tab-width: 4
|
|
* c-basic-offset: 4
|
|
* End:
|
|
*/
|