Any chance this will make it into RC1 ??
-- Ard
Index: interbase.c =================================================================== RCS file: /repository/php-src/ext/interbase/interbase.c,v retrieving revision 1.194 diff -u -r1.194 interbase.c --- interbase.c 21 Jan 2004 10:22:04 -0000 1.194 +++ interbase.c 31 Jan 2004 01:13:17 -0000 @@ -153,6 +153,10 @@ PHP_FE(ibase_wait_event, NULL) PHP_FE(ibase_set_event_handler, NULL) PHP_FE(ibase_free_event_handler, NULL) + PHP_FE(ibase_servmgr_connect, NULL) + PHP_FE(ibase_servmgr_disconnect, NULL) + PHP_FE(ibase_backup, NULL) + PHP_FE(ibase_restore, NULL) {NULL, NULL, NULL} }; @@ -181,7 +185,7 @@ #endif /* True globals, no need for thread safety */ -static int le_blob, le_link, le_plink, le_result, le_query, le_trans, le_event; +static int le_blob, le_link, le_plink, le_result, le_query, le_trans, le_event, le_servmgr; ZEND_DECLARE_MODULE_GLOBALS(ibase) @@ -612,6 +616,28 @@ } /* }}} */ +/* {{{ _php_ibase_free_servmgr() */ +static void _php_ibase_free_servmgr(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + ibase_servmgr *sv = (ibase_servmgr *) rsrc->ptr; + + IBDEBUG("Cleaning up service manager resource"); + + if (isc_service_detach(IB_STATUS, &sv->handle)) { + _php_ibase_error(TSRMLS_C); + } + + if (sv->hostname) { + efree(sv->hostname); + } + if (sv->username) { + efree(sv->username); + } + + efree(sv); +} +/* }}} */ + /* {{{ startup, shutdown and info functions */ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("ibase.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_ibase_globals, ibase_globals) @@ -646,6 +672,7 @@ le_plink = zend_register_list_destructors_ex(php_ibase_commit_link_rsrc, _php_ibase_close_plink, "interbase link persistent", module_number); le_trans = zend_register_list_destructors_ex(_php_ibase_free_trans, NULL, "interbase transaction", module_number); le_event = zend_register_list_destructors_ex(_php_ibase_free_event, NULL, "interbase event", module_number); + le_servmgr = zend_register_list_destructors_ex(_php_ibase_free_servmgr, NULL, "interbase service manager handle", module_number); REGISTER_LONG_CONSTANT("IBASE_DEFAULT", PHP_IBASE_DEFAULT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IBASE_TEXT", PHP_IBASE_FETCH_BLOBS, CONST_PERSISTENT); /* deprecated, for BC only */ @@ -786,7 +813,7 @@ /* }}} */ /* {{{ _php_ibase_attach_db() */ -static int _php_ibase_attach_db(char *server, char *uname, char *passwd, char *charset, int buffers, char *role, isc_db_handle *db TSRMLS_DC) +int _php_ibase_attach_db(char *server, char *uname, char *passwd, char *charset, int buffers, char *role, isc_db_handle *db TSRMLS_DC) { char dpb_buffer[256], *dpb, *p; int dpb_length, len; @@ -4530,6 +4557,126 @@ /* }}} */ +/* {{{ proto resource ibase_servmgr_connect(string host, string dba_username, string dba_password) */ +PHP_FUNCTION(ibase_servmgr_connect) +{ + long hlen, ulen, plen, spb_len; + ibase_servmgr *result, svm = { NULL, NULL, NULL }; + char buf[128], *password; + + RESET_ERRMSG; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", + &svm.hostname, &hlen, &svm.username, &ulen, &password, &plen)) { + + RETURN_FALSE; + } + + /* construct the spb, hack the service name into it as well */ + spb_len = snprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%s" "%s:service_mgr", + isc_spb_version, isc_spb_current_version, isc_spb_user_name, (char)ulen, + svm.username, isc_spb_password, (char)plen, password, svm.hostname); + + assert(sizeof(buf) > spb_len && spb_len != -1); + + /* attach to the service manager */ + if (isc_service_attach(IB_STATUS, 0, &buf[spb_len-hlen-12], /* points to %s:service_mgr part */ + &svm.handle, (unsigned short)spb_len, buf)) { + _php_ibase_error(TSRMLS_C); + RETURN_FALSE; + } + + result = (ibase_servmgr*)emalloc(sizeof(ibase_servmgr)); + result->handle = svm.handle; + result->hostname = estrdup(svm.hostname); + result->username = estrdup(svm.username); + + ZEND_REGISTER_RESOURCE(return_value, result, le_servmgr); + zend_list_addref(Z_LVAL_P(return_value)); +} +/* }}} */ + +/* {{{ proto bool ibase_servmgr_disconnect(resource service_handle) */ +PHP_FUNCTION(ibase_servmgr_disconnect) +{ + zval *res; + + RESET_ERRMSG; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res)) { + RETURN_FALSE; + } + + zend_list_delete(Z_LVAL_P(res)); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ */ +static void _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAMETERS, char operation) +{ + /** + * It appears that the service API is a little bit confused about which flag + * to use for the source and destination in the case of a restore operation. + * When passing the backup file as isc_spb_dbname and the destination db as + * bpk_file, things work well. + */ + zval *res; + char *db, *bk, buf[200]; + long dblen, bklen, spb_len, opts = 0; + zend_bool replace = 0; + ibase_servmgr *svm; + + RESET_ERRMSG; + + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, operation == isc_action_svc_backup ? "rss" : "rss|b", + &res, &db, &dblen, &bk, &bklen, &replace)) { + RETURN_FALSE; + } + + ZEND_FETCH_RESOURCE(svm, ibase_servmgr *, &res, -1, "Interbase service manager handle", le_servmgr); + + switch (operation) { + default: + break; + case isc_action_svc_restore: + opts |= replace ? isc_spb_res_replace : isc_spb_res_create; + } + + /* fill the param buffer */ + spb_len = snprintf(buf, sizeof(buf), "%c%c%c%c%s%c%c%c%s%c%c%c%c%c", + operation, isc_spb_dbname, (char)dblen, (char)(dblen >> 8), db, + isc_spb_bkp_file, (char)bklen, (char)(bklen >> 8), bk, isc_spb_options, + (char)opts,(char)(opts >> 8), (char)(opts >> 16), (char)(opts >> 24)); + + assert(sizeof(buf) > spb_len && spb_len != -1); + + /* now start the backup/restore job */ + if (isc_service_start(IB_STATUS, &svm->handle, NULL, (unsigned short)spb_len, buf)) { + _php_ibase_error(TSRMLS_C); + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool ibase_backup(resource service_handle, string source_db, string dest_file) + Initiates a backup task in the service manager and returns immediately */ +PHP_FUNCTION(ibase_backup) +{ + _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_backup); +} + +/* {{{ proto bool ibase_restore(resource service_handle, string source_file, string dest_db [, bool replace]) + Initiates a restore task in the service manager and returns immediately */ +PHP_FUNCTION(ibase_restore) +{ + _php_ibase_backup_restore(INTERNAL_FUNCTION_PARAM_PASSTHRU, isc_action_svc_restore); +} +/* }}} */ + #endif /* HAVE_IBASE */ /* Index: php_interbase.h =================================================================== RCS file: /repository/php-src/ext/interbase/php_interbase.h,v retrieving revision 1.64 diff -u -r1.64 php_interbase.h --- php_interbase.h 8 Jan 2004 17:32:17 -0000 1.64 +++ php_interbase.h 31 Jan 2004 01:13:17 -0000 @@ -88,6 +88,11 @@ PHP_FUNCTION(ibase_set_event_handler); PHP_FUNCTION(ibase_free_event_handler); +PHP_FUNCTION(ibase_servmgr_connect); +PHP_FUNCTION(ibase_servmgr_disconnect); +PHP_FUNCTION(ibase_backup); +PHP_FUNCTION(ibase_restore); + #define IBASE_MSGSIZE 256 #define MAX_ERRMSG (IBASE_MSGSIZE*2) @@ -175,6 +180,12 @@ void **thread_ctx; } ibase_event; +typedef struct { + isc_svc_handle handle; + char *hostname; + char *username; +} ibase_servmgr; + enum php_interbase_option { PHP_IBASE_DEFAULT = 0, /* fetch flags */
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php