├── CREDITS ├── EXPERIMENTAL ├── LICENSE ├── README ├── config.m4 ├── config.w32 ├── couchdb.c ├── examples ├── example.php └── php.gif ├── package2.xml └── php_couchdb.h /CREDITS: -------------------------------------------------------------------------------- 1 | couchdb 2 | Andrew Colin Kissa 3 | 4 | Couchdb extension uses some code from oauth by the following 5 | 6 | John Jawed 7 | Felipe Pena 8 | Rasmus Lerdorf 9 | -------------------------------------------------------------------------------- /EXPERIMENTAL: -------------------------------------------------------------------------------- 1 | this extension is experimental, 2 | its functions may change their names 3 | or move to extension all together 4 | so do not rely to much on them 5 | you have been warned! 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | The PHP License, Version 3.0 3 | Copyright (c) 1999 - 2003 The PHP Group. All rights reserved. 4 | -------------------------------------------------------------------- 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, is permitted provided that the following conditions 8 | are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | 3. The name "PHP" must not be used to endorse or promote products 19 | derived from this software without prior written permission. For 20 | written permission, please contact group@php.net. 21 | 22 | 4. Products derived from this software may not be called "PHP", nor 23 | may "PHP" appear in their name, without prior written permission 24 | from group@php.net. You may indicate that your software works in 25 | conjunction with PHP by saying "Foo for PHP" instead of calling 26 | it "PHP Foo" or "phpfoo" 27 | 28 | 5. The PHP Group may publish revised and/or new versions of the 29 | license from time to time. Each version will be given a 30 | distinguishing version number. 31 | Once covered code has been published under a particular version 32 | of the license, you may always continue to use it under the terms 33 | of that version. You may also choose to use such covered code 34 | under the terms of any subsequent version of the license 35 | published by the PHP Group. No one other than the PHP Group has 36 | the right to modify the terms applicable to covered code created 37 | under this License. 38 | 39 | 6. Redistributions of any form whatsoever must retain the following 40 | acknowledgment: 41 | "This product includes PHP, freely available from 42 | ". 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND 45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP 48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 | OF THE POSSIBILITY OF SUCH DAMAGE. 56 | 57 | -------------------------------------------------------------------- 58 | 59 | This software consists of voluntary contributions made by many 60 | individuals on behalf of the PHP Group. 61 | 62 | The PHP Group can be contacted via Email at group@php.net. 63 | 64 | For more information on the PHP Group and the PHP project, 65 | please see . 66 | 67 | This product includes the Zend Engine, freely available at 68 | . 69 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | HACKING 3 | ======= 4 | 5 | 1) you can modify the generated code as with any other PHP extension 6 | 7 | BUILDING ON UNIX etc. 8 | ===================== 9 | 10 | To compile your new extension, you will have to execute the following steps: 11 | 12 | 1. $ ./phpize 13 | 2. $ ./configure 14 | 3. $ make 15 | 4. $ make test 16 | 5. $ [sudo] make install 17 | 18 | 19 | 20 | BUILDING ON WINDOWS 21 | =================== 22 | 23 | No windows build is available at the moment 24 | 25 | TESTING 26 | ======= 27 | 28 | You can now load the extension using a php.ini directive 29 | 30 | extension="couchdb.so" 31 | 32 | or load it at runtime using the dl() function 33 | 34 | dl("couchdb.so"); 35 | 36 | The extension should now be available, you can test this 37 | using the extension_loaded() function: 38 | 39 | if (extension_loaded("couchdb")) 40 | echo "couchdb loaded :)"; 41 | else 42 | echo "something is wrong :("; 43 | 44 | The extension will also add its own block to the output 45 | of phpinfo(); 46 | 47 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl config.m4 for couchdb 2 | dnl $Id: $ 3 | dnl vim: noet ts=1 sw=1 4 | 5 | PHP_ARG_ENABLE([couchdb], [whether to enable couchdb support], 6 | [ --enable-couchdb Enable couchdb support]) 7 | 8 | if test "$PHP_COUCHDB" != "no"; then 9 | PHP_SUBST(COUCHDB_SHARED_LIBADD) 10 | 11 | PHP_ADD_LIBRARY(curl,,COUCHDB_SHARED_LIBADD) 12 | 13 | PHP_NEW_EXTENSION(couchdb, couchdb.c, $ext_shared) 14 | CFLAGS="$CFLAGS -Wall -g" 15 | 16 | PHP_ADD_EXTENSION_DEP(couchdb, curl) 17 | PHP_ADD_EXTENSION_DEP(couchdb, json) 18 | fi 19 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | ARG_ENABLE("couchdb", "enable couchdb support", "no"); 5 | 6 | if (PHP_COUCHDB != "no") { 7 | EXTENSION("couchdb", "couchdb.c"); 8 | } 9 | -------------------------------------------------------------------------------- /couchdb.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2009 | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Andrew Colin Kissa | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "zend_exceptions.h" 27 | #include "ext/standard/info.h" 28 | #include "ext/standard/php_string.h" 29 | #include "ext/standard/php_smart_str.h" 30 | #include "ext/standard/url.h" 31 | #include "Zend/zend_extensions.h" 32 | #include "php_couchdb.h" 33 | #include "ext/json/php_json.h" 34 | 35 | #include 36 | 37 | 38 | #define CAAL(s, v) add_assoc_long_ex(returned_info, s, sizeof(s), (long) v); 39 | #define CAAD(s, v) add_assoc_double_ex(returned_info, s, sizeof(s), (double) v); 40 | #define CAAS(s, v) add_assoc_string_ex(returned_info, s, sizeof(s), (char *) (v ? v : ""), 1); 41 | 42 | 43 | #define COUCHDB_ERROR(errcode, msg, ... ) \ 44 | zend_throw_exception_ex(couchdb_exception_ce_ptr, errcode TSRMLS_CC, msg, ##__VA_ARGS__); 45 | 46 | #define FREE_ARGS_HASH(a) \ 47 | if (a) { \ 48 | zend_hash_destroy(a); \ 49 | FREE_HASHTABLE(a); \ 50 | } 51 | 52 | #define PROCESS_JSON_RESULT(code, object, assoc) \ 53 | if (code != -1 && object->lastresponse.c) { \ 54 | MAKE_STD_ZVAL(zret); \ 55 | ZVAL_STRINGL(zret, object->lastresponse.c, object->lastresponse.len, 1); \ 56 | couchdb_set_response_args(object->properties, zret TSRMLS_CC); \ 57 | php_json_decode(return_value, object->lastresponse.c, object->lastresponse.len, assoc TSRMLS_CC); \ 58 | return; \ 59 | }else{ \ 60 | RETURN_NULL(); \ 61 | } \ 62 | 63 | #define PROCESS_JSON_RESULT_EX(code, object, assoc) \ 64 | if (code != -1 && object->lastresponse.c) { \ 65 | MAKE_STD_ZVAL(zret); \ 66 | ZVAL_STRINGL(zret, object->lastresponse.c, object->lastresponse.len, 1); \ 67 | couchdb_set_response_args(object->properties, zret TSRMLS_CC); \ 68 | php_json_decode(return_value, object->lastresponse.c, object->lastresponse.len, assoc TSRMLS_CC); \ 69 | return; \ 70 | }else{ \ 71 | COUCHDB_ERROR(0, object->lastresponse.c); \ 72 | } \ 73 | 74 | #define PROCESS_JSON_RESULT_COMPART(code, object, assoc) \ 75 | long depth = JSON_PARSER_DEFAULT_DEPTH; \ 76 | if (code != -1 && object->lastresponse.c) { \ 77 | MAKE_STD_ZVAL(zret); \ 78 | ZVAL_STRINGL(zret, object->lastresponse.c, object->lastresponse.len, 1); \ 79 | couchdb_set_response_args(object->properties, zret TSRMLS_CC); \ 80 | php_json_decode(return_value, object->lastresponse.c, object->lastresponse.len, assoc, depth TSRMLS_CC); \ 81 | return; \ 82 | }else{ \ 83 | RETURN_NULL(); \ 84 | } \ 85 | 86 | #define PROCESS_JSON_RESULT_COMPART_EX(code, object, assoc) \ 87 | long depth = JSON_PARSER_DEFAULT_DEPTH; \ 88 | if (code != -1 && object->lastresponse.c) { \ 89 | MAKE_STD_ZVAL(zret); \ 90 | ZVAL_STRINGL(zret, object->lastresponse.c, object->lastresponse.len, 1); \ 91 | couchdb_set_response_args(object->properties, zret TSRMLS_CC); \ 92 | php_json_decode(return_value, object->lastresponse.c, object->lastresponse.len, assoc, depth TSRMLS_CC); \ 93 | return; \ 94 | }else{ \ 95 | if (object->lastresponse.len) { \ 96 | COUCHDB_ERROR(0, object->lastresponse.c); \ 97 | }else{ \ 98 | COUCHDB_ERROR(0, "Unknown error"); \ 99 | } \ 100 | } \ 101 | 102 | #define PROCESS_BOOL_RESULT(code, object, rcode) \ 103 | if (code == rcode && object->lastresponse.c) { \ 104 | MAKE_STD_ZVAL(zret); \ 105 | ZVAL_STRINGL(zret, object->lastresponse.c, object->lastresponse.len, 1); \ 106 | couchdb_set_response_args(object->properties, zret TSRMLS_CC); \ 107 | RETURN_TRUE; \ 108 | }else{ \ 109 | RETURN_FALSE; \ 110 | } \ 111 | 112 | #define PROCESS_BOOL_RESULT_EX(code, object, rcode) \ 113 | if (code == rcode && object->lastresponse.c) { \ 114 | MAKE_STD_ZVAL(zret); \ 115 | ZVAL_STRINGL(zret, object->lastresponse.c, object->lastresponse.len, 1); \ 116 | couchdb_set_response_args(object->properties, zret TSRMLS_CC); \ 117 | RETURN_TRUE; \ 118 | }else{ \ 119 | if (object->lastresponse.len) { \ 120 | COUCHDB_ERROR(0, object->lastresponse.c); \ 121 | }else { \ 122 | COUCHDB_ERROR(0, "Unknown error"); \ 123 | }\ 124 | } \ 125 | 126 | #define CHECK_DB_NAME(object) \ 127 | db_name_len = Z_STRLEN_PP(couchdb_get_property(object, COUCHDB_DB TSRMLS_CC)); \ 128 | if (!db_name_len) { \ 129 | COUCHDB_ERROR(0, COUCHDB_DB_NOT_SET); \ 130 | return; \ 131 | } \ 132 | db_name = Z_STRVAL_PP(couchdb_get_property(object, COUCHDB_DB TSRMLS_CC)); \ 133 | 134 | 135 | #ifndef TRUE 136 | #define TRUE 1 137 | #define FALSE 0 138 | #endif 139 | 140 | #ifndef MIN 141 | # define MIN(a,b) (aproperties, prop_name, prop_len+1, h, (void **)&data_ptr) == SUCCESS) { 285 | return (zval **)data_ptr; 286 | } 287 | 288 | return NULL; 289 | } 290 | /* }}} */ 291 | 292 | static inline int couchdb_set_property(php_couchdb_object *local_client, zval *prop, char *prop_name TSRMLS_DC) /* {{{ */ 293 | { 294 | size_t prop_len = 0; 295 | ulong h; 296 | 297 | prop_len = strlen(prop_name); 298 | h = zend_hash_func(prop_name, prop_len+1); 299 | 300 | return zend_hash_quick_update(local_client->properties, prop_name, prop_len+1, h, (void *)&prop, sizeof(zval *), NULL); 301 | } 302 | /* }}} */ 303 | 304 | static void couchdb_hash_dtor(php_couchdb_object *local_client TSRMLS_DC) /* {{{ */ 305 | { 306 | HashTable *ht; 307 | 308 | ht = local_client->properties; 309 | 310 | FREE_ARGS_HASH(ht); 311 | } 312 | /* }}} */ 313 | 314 | static size_t couchdb_read_response(char *ptr, size_t size, size_t nmemb, void *ctx) /* {{{ */ 315 | { 316 | uint relsize; 317 | php_couchdb_object *local_client = (php_couchdb_object *)ctx; 318 | 319 | relsize = size * nmemb; 320 | smart_str_appendl(&local_client->lastresponse, ptr, relsize); 321 | 322 | return relsize; 323 | } 324 | /* }}} */ 325 | 326 | static size_t couchdb_write_response(void *ptr, size_t size, size_t nmemb, void *ctx) /* {{{ */ 327 | { 328 | php_couchdb_object *local_client = (php_couchdb_object *)ctx; 329 | 330 | if (local_client->lastrequest.len) { 331 | size_t out = MIN(size * nmemb, local_client->lastrequest.len - local_client->previous); 332 | if (out) { 333 | memcpy(ptr, ((char *) local_client->lastrequest.c) + local_client->previous, out); 334 | local_client->previous += out; 335 | return out; 336 | } 337 | } 338 | 339 | return 0; 340 | } 341 | /* }}} */ 342 | 343 | static CURLcode couchdb_make_request(php_couchdb_object *local_client, const char *url, const smart_str *payload, const char *http_method, HashTable *request_headers TSRMLS_DC) /* {{{ */ 344 | { 345 | CURLcode cres, crres, cookie_result; 346 | CURL *curl; 347 | zval **zca_info, **zca_path; 348 | void *p_cur; 349 | struct curl_slist *curl_headers = NULL, *cookies, *cookie_itr; 350 | long response_code = -1; 351 | char *current_key; 352 | smart_str rheader = {0}; 353 | uint current_key_len; 354 | ulong num_key; 355 | 356 | zca_info = couchdb_get_property(local_client, COUCHDB_CA_INFO TSRMLS_CC); 357 | zca_path = couchdb_get_property(local_client, COUCHDB_CA_PATH TSRMLS_CC); 358 | 359 | curl = curl_easy_init(); 360 | 361 | curl_headers = curl_slist_append(curl_headers, COUCHDB_ACCEPT_HEADERS); 362 | 363 | if (request_headers) { 364 | for (zend_hash_internal_pointer_reset(request_headers); zend_hash_get_current_data(request_headers, (void **)&p_cur) == SUCCESS; 365 | zend_hash_move_forward(request_headers)) { 366 | if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(request_headers, ¤t_key, ¤t_key_len, &num_key, 0, NULL)) { 367 | smart_str_appends(&rheader, current_key); 368 | smart_str_appends(&rheader, ": "); 369 | smart_str_appends(&rheader, Z_STRVAL_PP((zval **)p_cur)); 370 | smart_str_0(&rheader); 371 | curl_headers = curl_slist_append(curl_headers, rheader.c); 372 | smart_str_free(&rheader); 373 | } 374 | } 375 | } 376 | 377 | if (payload->len) { 378 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload->c); 379 | curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload->len); 380 | } 381 | 382 | if (local_client->lastrequest.len && strcmp(http_method, COUCHDB_PUT) == 0) { 383 | curl_easy_setopt(curl, CURLOPT_PUT, TRUE); 384 | curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE); 385 | curl_easy_setopt(curl, CURLOPT_READFUNCTION, couchdb_write_response); 386 | curl_easy_setopt(curl, CURLOPT_READDATA, local_client); 387 | curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, local_client->lastrequest.len); 388 | #if !defined(ZTS) 389 | curl_headers = curl_slist_append(curl_headers, "Transfer-Encoding: chunked"); 390 | #endif 391 | } 392 | 393 | curl_easy_setopt(curl, CURLOPT_URL, url); 394 | if(zca_path && Z_STRLEN_PP(zca_path)) { 395 | curl_easy_setopt(curl, CURLOPT_CAPATH, Z_STRVAL_PP(zca_path)); 396 | } 397 | 398 | if(zca_info && Z_STRLEN_PP(zca_info)) { 399 | curl_easy_setopt(curl, CURLOPT_CAINFO, Z_STRVAL_PP(zca_info)); 400 | } 401 | 402 | curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); 403 | 404 | if (local_client->use_cookie_auth) { 405 | curl_easy_setopt(curl, CURLOPT_COOKIE, local_client->cookie.c); 406 | curl_headers = curl_slist_append(curl_headers, "X-CouchDB-WWW-Authenticate: Cookie"); 407 | curl_headers = curl_slist_append(curl_headers, "Authorization:"); 408 | } 409 | curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_method); 410 | curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); 411 | curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 4L); 412 | curl_headers = curl_slist_append(curl_headers, "Expect:"); 413 | curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers); 414 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, couchdb_read_response); 415 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, local_client); 416 | #if defined(ZTS) 417 | curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); 418 | #endif 419 | 420 | smart_str_free(&local_client->lastresponse); 421 | 422 | cres = curl_easy_perform(curl); 423 | 424 | smart_str_0(&local_client->lastresponse); 425 | smart_str_free(&local_client->lastrequest); 426 | 427 | curl_slist_free_all(curl_headers); 428 | 429 | if (CURLE_OK == cres) { 430 | crres = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); 431 | cookie_result = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies); 432 | if (CURLE_OK == cookie_result) { 433 | char *token, *p; 434 | int x = 1; 435 | 436 | cookie_itr = cookies; 437 | while (cookie_itr) { 438 | p = php_strtok_r(cookie_itr->data, "\t", &token); 439 | while (p) { 440 | if (x == 6) { 441 | smart_str_free(&local_client->cookie); 442 | smart_str_appends(&local_client->cookie, p); 443 | smart_str_appendc(&local_client->cookie, '='); 444 | }else if (x == 7) { 445 | smart_str_appends(&local_client->cookie, p); 446 | } 447 | x++; 448 | p = php_strtok_r(NULL, "\t", &token); 449 | } 450 | cookie_itr = cookie_itr->next; 451 | } 452 | smart_str_0(&local_client->cookie); 453 | curl_slist_free_all(cookies); 454 | }else { 455 | php_error(E_WARNING, COUCHDB_COOKIE_NOT_GOT); 456 | } 457 | }else { 458 | crres = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); 459 | php_error(E_WARNING, COUCHDB_SERVER_FAIL, local_client->lastresponse.c); 460 | } 461 | curl_easy_cleanup(curl); 462 | 463 | return response_code; 464 | } 465 | /* }}} */ 466 | 467 | static long couchdb_prepare_request(php_couchdb_object *local_client, const char *url, const char *method, zval *request_params, HashTable *request_headers, int get_flags TSRMLS_DC) /* {{{ */ 468 | { 469 | long http_response_code; 470 | smart_str surl = {0}, payload = {0}, postdata = {0}; 471 | HashTable *rargs = NULL; 472 | 473 | if (request_params) { 474 | switch (Z_TYPE_P(request_params)) { 475 | case IS_ARRAY: 476 | rargs = HASH_OF(request_params); 477 | couchdb_build_query(&postdata, rargs, 0); 478 | break; 479 | case IS_STRING: 480 | smart_str_appendl(&postdata, Z_STRVAL_P(request_params), Z_STRLEN_P(request_params)); 481 | break; 482 | } 483 | } 484 | 485 | smart_str_0(&postdata); 486 | smart_str_0(&surl); 487 | smart_str_appends(&surl, url); 488 | 489 | http_response_code = -1; 490 | 491 | 492 | if (strcmp(method, COUCHDB_GET) == 0 || strcmp(method, COUCHDB_DELETE) == 0) { 493 | if (postdata.len) { 494 | smart_str_append(http_url_concat(&surl), &postdata); 495 | } 496 | }else { 497 | if (get_flags && postdata.len) { 498 | smart_str_append(http_url_concat(&surl), &postdata); 499 | }else { 500 | smart_str_append(&payload, &postdata); 501 | smart_str_0(&payload); 502 | } 503 | } 504 | 505 | smart_str_0(&surl); 506 | 507 | http_response_code = couchdb_make_request(local_client, surl.c, &payload, method, request_headers TSRMLS_CC); 508 | 509 | smart_str_free(&payload); 510 | 511 | if (http_response_code < COUCHDB_STATUS_OK || http_response_code > COUCHDB_STATUS_END) { 512 | http_response_code = -1; 513 | } 514 | 515 | smart_str_free(&surl); 516 | smart_str_free(&postdata); 517 | 518 | return http_response_code; 519 | } 520 | /* }}} */ 521 | 522 | static int couchdb_cookie_login(php_couchdb_object *local_client, char *url, char *user_name, char *password TSRMLS_DC) /* {{{ */ 523 | { 524 | zval *auth_string; 525 | char *buff, *euser_name, *epassword; 526 | int tlen = 0; 527 | long http_response_code; 528 | 529 | 530 | euser_name = couchdb_encode_url(user_name); 531 | epassword = couchdb_encode_url(password); 532 | 533 | tlen = spprintf(&buff, 0, "username=%s&password=%s", euser_name, epassword); 534 | 535 | MAKE_STD_ZVAL(auth_string); 536 | ZVAL_STRINGL(auth_string, buff, tlen, 1); 537 | 538 | efree(euser_name); 539 | efree(epassword); 540 | efree(buff); 541 | 542 | http_response_code = couchdb_prepare_request(local_client, url, COUCHDB_POST, auth_string, NULL, 0 TSRMLS_CC); 543 | 544 | zval_ptr_dtor(&auth_string); 545 | 546 | if (http_response_code == COUCHDB_STATUS_OK) { 547 | return TRUE; 548 | }else { 549 | return FALSE; 550 | } 551 | 552 | } 553 | /* }}} */ 554 | 555 | static int couchdb_cookie_logout(php_couchdb_object *local_client, char *url TSRMLS_DC) /* {{{ */ 556 | { 557 | long http_response_code; 558 | 559 | http_response_code = couchdb_prepare_request(local_client, url, COUCHDB_DELETE, NULL, NULL, 0 TSRMLS_CC); 560 | 561 | if (http_response_code == COUCHDB_STATUS_OK) { 562 | return TRUE; 563 | }else { 564 | return FALSE; 565 | } 566 | } 567 | /* }}} */ 568 | 569 | static inline php_couchdb_object *fetch_couchdb_object(zval *obj TSRMLS_DC) /* {{{ */ 570 | { 571 | php_couchdb_object *local_client = (php_couchdb_object *)zend_object_store_get_object(obj TSRMLS_CC); 572 | 573 | local_client->this_ptr = obj; 574 | 575 | return local_client; 576 | } 577 | /* }}} */ 578 | 579 | static zval *couchdb_read_member(zval *obj, zval *mem, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ 580 | { 581 | zval *return_value = NULL; 582 | php_couchdb_object *local_client; 583 | 584 | local_client = fetch_couchdb_object(obj TSRMLS_CC); 585 | 586 | return_value = zend_get_std_object_handlers()->read_property(obj, mem, type, key TSRMLS_CC); 587 | 588 | return return_value; 589 | 590 | } 591 | /* }}} */ 592 | 593 | static void couchdb_write_member(zval *obj, zval *mem, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */ 594 | { 595 | char *property; 596 | php_couchdb_object *local_client; 597 | 598 | property = Z_STRVAL_P(mem); 599 | local_client = fetch_couchdb_object(obj TSRMLS_CC); 600 | 601 | zend_get_std_object_handlers()->write_property(obj, mem, value, key TSRMLS_CC); 602 | } 603 | /* }}} */ 604 | 605 | static void couchdb_object_free_storage(void *obj TSRMLS_DC) /* {{{ */ 606 | { 607 | php_couchdb_object *local_client; 608 | 609 | local_client = (php_couchdb_object *) obj; 610 | 611 | zend_object_std_dtor(&local_client->std TSRMLS_CC); 612 | 613 | if (local_client->lastresponse.c) { 614 | smart_str_free(&local_client->lastresponse); 615 | } 616 | 617 | if (local_client->lastrequest.c) { 618 | smart_str_free(&local_client->lastrequest); 619 | } 620 | 621 | if (local_client->cookie.c) { 622 | smart_str_free(&local_client->cookie); 623 | } 624 | 625 | efree(obj); 626 | } 627 | /* }}} */ 628 | 629 | static zend_object_value couchdb_client_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */ 630 | { 631 | zend_object_value retval; 632 | php_couchdb_object *local_client; 633 | 634 | local_client = ecalloc(1, sizeof(php_couchdb_object)); 635 | zend_object_std_init(&(local_client->std), ce TSRMLS_CC); 636 | 637 | retval.handle = zend_objects_store_put(local_client, (zend_objects_store_dtor_t)zend_objects_destroy_object, couchdb_object_free_storage, NULL TSRMLS_CC); 638 | retval.handlers = (zend_object_handlers *) &couchdb_client_handlers; 639 | 640 | return retval; 641 | } 642 | /* }}} */ 643 | 644 | static void _couchdb_getdbinfo(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */ 645 | { 646 | php_couchdb_object *local_client; 647 | char *url = NULL, *db_name, *edb_name; 648 | int db_name_len = 0; 649 | smart_str surl = {0}; 650 | long http_response_code; 651 | zend_bool assoc = 1; 652 | zval * zret = NULL; 653 | 654 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &db_name, &db_name_len) == FAILURE) { 655 | return; 656 | } 657 | 658 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 659 | 660 | if (!db_name_len) { 661 | CHECK_DB_NAME(local_client); 662 | } 663 | 664 | edb_name = couchdb_encode_url(db_name); 665 | 666 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 667 | 668 | smart_str_appends(&surl, url); 669 | smart_str_appendc(&surl, '/'); 670 | smart_str_appends(&surl, edb_name); 671 | smart_str_0(&surl); 672 | 673 | efree(edb_name); 674 | 675 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 676 | 677 | smart_str_free(&surl); 678 | 679 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 680 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 681 | #else 682 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 683 | #endif 684 | 685 | } 686 | /* }}} */ 687 | 688 | static void _couchdb_sendrequest(INTERNAL_FUNCTION_PARAMETERS, int type, zend_bool throw_exception) /* {{{ */ 689 | { 690 | php_couchdb_object *local_client; 691 | char *url = NULL, *db_name, *edb_name, *ldb_name=NULL; 692 | int db_name_len = 0; 693 | smart_str surl = {0}; 694 | long http_response_code, comp_response; 695 | zval * zret = NULL, *dbp = NULL; 696 | 697 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &db_name, &db_name_len) == FAILURE) { 698 | return; 699 | } 700 | 701 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 702 | 703 | if (!db_name_len) { 704 | CHECK_DB_NAME(local_client); 705 | } 706 | 707 | edb_name = couchdb_encode_url(db_name); 708 | 709 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 710 | 711 | smart_str_appends(&surl, url); 712 | smart_str_appendc(&surl, '/'); 713 | smart_str_appends(&surl, edb_name); 714 | if (type == COUCHDB_DB_COMPACT) { 715 | smart_str_appends(&surl, COUCHDB_COMPACT); 716 | } 717 | smart_str_0(&surl); 718 | 719 | efree(edb_name); 720 | 721 | if (type == COUCHDB_DB_COMPACT) { 722 | comp_response = COUCHDB_STATUS_ACCEPTED; 723 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_POST, NULL, NULL, 0 TSRMLS_CC); 724 | }else if (type == COUCHDB_DB_DELETE) { 725 | comp_response = COUCHDB_STATUS_OK; 726 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_DELETE, NULL, NULL, 0 TSRMLS_CC); 727 | 728 | ldb_name = ""; 729 | MAKE_STD_ZVAL(dbp); 730 | ZVAL_STRING(dbp, ldb_name, 1); 731 | 732 | if (couchdb_set_property(local_client, dbp, COUCHDB_DB TSRMLS_CC) != SUCCESS) { 733 | COUCHDB_ERROR(0, COUCHDB_DB_DESELECT_FAIL); 734 | return; 735 | } 736 | }else{ 737 | comp_response = COUCHDB_STATUS_CREATED; 738 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_PUT, NULL, NULL, 0 TSRMLS_CC); 739 | } 740 | 741 | 742 | smart_str_free(&surl); 743 | 744 | if (throw_exception) { 745 | PROCESS_BOOL_RESULT_EX(http_response_code, local_client, comp_response); 746 | }else { 747 | PROCESS_BOOL_RESULT(http_response_code, local_client, comp_response); 748 | } 749 | 750 | } 751 | /* }}} */ 752 | 753 | /* ---- METHODS ---- */ 754 | 755 | /* {{{ proto void CouchdbClient::__construct(string url [,bool use_cookie_auth [, string db_name]]) 756 | Constructor of the CouchdbClient class */ 757 | TC_METHOD(__construct) 758 | { 759 | HashTable *hasht; 760 | php_couchdb_object *local_client; 761 | zval *urp, *dbp, *obj = NULL, *zuser_name, *zpassword; 762 | char *uri, *db_name = NULL, *striped_url; 763 | smart_str surl = {0}; 764 | int uri_len, db_name_len = 0; 765 | php_url *urlparts; 766 | zend_bool use_cookie_auth = 0; 767 | 768 | obj = getThis(); 769 | local_client = fetch_couchdb_object(obj TSRMLS_CC); 770 | 771 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bs", &uri, &uri_len, &use_cookie_auth, &db_name, &db_name_len) == FAILURE) { 772 | return; 773 | } 774 | 775 | if (!uri_len) { 776 | COUCHDB_ERROR(0, COUCHDB_INVALID_URI); 777 | return; 778 | } 779 | 780 | urlparts = php_url_parse_ex(uri, strlen(uri)); 781 | 782 | if (!urlparts || !urlparts->host || !urlparts->scheme) { 783 | COUCHDB_ERROR(0, COUCHDB_INVALID_URI); 784 | php_url_free(urlparts); 785 | return; 786 | } 787 | 788 | if ((strcmp(urlparts->scheme, "http") != 0) && (strcmp(urlparts->scheme, "https") != 0)) { 789 | COUCHDB_ERROR(0, COUCHDB_INVALID_SCHEME, urlparts->scheme); 790 | php_url_free(urlparts); 791 | return; 792 | } 793 | 794 | /* check if user auth details were supplied */ 795 | if ((!urlparts->user || !urlparts->pass) && use_cookie_auth) { 796 | COUCHDB_ERROR(0, COUCHDB_COOKIE_PARAMS); 797 | php_url_free(urlparts); 798 | return; 799 | } 800 | 801 | local_client->cookie.c = NULL; 802 | local_client->lastresponse.c = NULL; 803 | local_client->lastrequest.c = NULL; 804 | local_client->previous = 0; 805 | local_client->use_cookie_auth = 0; 806 | 807 | if (!db_name_len) { 808 | db_name = ""; 809 | } 810 | 811 | TSRMLS_SET_CTX(local_client->thread_ctx); 812 | 813 | if (local_client->properties) { 814 | zend_hash_clean(local_client->properties); 815 | hasht = local_client->properties; 816 | }else { 817 | ALLOC_HASHTABLE(hasht); 818 | zend_hash_init(hasht, 0, NULL, ZVAL_PTR_DTOR, 0); 819 | local_client->properties = hasht; 820 | } 821 | 822 | MAKE_STD_ZVAL(urp); 823 | ZVAL_STRINGL(urp, uri, uri_len, 1); 824 | if (couchdb_set_property(local_client, urp, COUCHDB_URL TSRMLS_CC) != SUCCESS) { 825 | return; 826 | } 827 | 828 | MAKE_STD_ZVAL(dbp); 829 | ZVAL_STRINGL(dbp, db_name, db_name_len, 1); 830 | if (couchdb_set_property(local_client, dbp, COUCHDB_DB TSRMLS_CC) != SUCCESS) { 831 | return; 832 | } 833 | 834 | if (use_cookie_auth) { 835 | /* do cookie login */ 836 | if (urlparts->port) { 837 | spprintf(&striped_url, 0, "%s://%s:%d", urlparts->scheme, urlparts->host, urlparts->port); 838 | smart_str_appends(&surl, striped_url); 839 | smart_str_appends(&surl, COUCHDB_SESSION); 840 | smart_str_0(&surl); 841 | }else { 842 | spprintf(&striped_url, 0, "%s://%s", urlparts->scheme, urlparts->host); 843 | smart_str_appends(&surl, striped_url); 844 | smart_str_appends(&surl, COUCHDB_SESSION); 845 | smart_str_0(&surl); 846 | } 847 | 848 | if (couchdb_cookie_login(local_client, surl.c, urlparts->user, urlparts->pass TSRMLS_CC) == 0) { 849 | COUCHDB_ERROR(0, COUCHDB_COOKIE_AUTH_FAILURE); 850 | FREE_ARGS_HASH(local_client->properties); 851 | efree(striped_url); 852 | php_url_free(urlparts); 853 | smart_str_free(&surl); 854 | return; 855 | } 856 | 857 | smart_str_free(&surl); 858 | uri = striped_url; 859 | efree(striped_url); 860 | 861 | local_client->use_cookie_auth = 1; 862 | } 863 | 864 | MAKE_STD_ZVAL(zuser_name); 865 | MAKE_STD_ZVAL(zpassword); 866 | 867 | if (use_cookie_auth) { 868 | ZVAL_STRING(zuser_name, urlparts->user, 1); 869 | ZVAL_STRING(zpassword, urlparts->pass, 1); 870 | }else { 871 | ZVAL_STRING(zuser_name, "", 1); 872 | ZVAL_STRING(zpassword, "", 1); 873 | } 874 | 875 | php_url_free(urlparts); 876 | 877 | if (couchdb_set_property(local_client, zuser_name, COUCHDB_USER TSRMLS_CC) != SUCCESS) { 878 | return; 879 | } 880 | 881 | if (couchdb_set_property(local_client, zpassword, COUCHDB_PASSWORD TSRMLS_CC) != SUCCESS) { 882 | return; 883 | } 884 | 885 | } 886 | /* }}} */ 887 | 888 | /* {{{ CouchdbClient::__destruct 889 | Destructor for CouchdbClient */ 890 | TC_METHOD(__destruct) 891 | { 892 | php_couchdb_object *local_client; 893 | char *url; 894 | smart_str surl = {0}; 895 | 896 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 897 | 898 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { 899 | return; 900 | } 901 | 902 | if (local_client->cookie.c) { 903 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 904 | 905 | smart_str_appends(&surl, url); 906 | smart_str_appends(&surl, COUCHDB_SESSION); 907 | smart_str_0(&surl); 908 | 909 | couchdb_cookie_logout(local_client, surl.c TSRMLS_CC); 910 | smart_str_free(&local_client->cookie); 911 | smart_str_free(&surl); 912 | } 913 | 914 | couchdb_hash_dtor(local_client TSRMLS_CC); 915 | } 916 | /* }}} */ 917 | 918 | /* {{{ proto bool CouchdbClient::compactDatabase([, string db_name ]) 919 | Compacts a CouchDB database 920 | */ 921 | TC_METHOD(compactDatabase) 922 | { 923 | _couchdb_sendrequest(INTERNAL_FUNCTION_PARAM_PASSTHRU, COUCHDB_DB_COMPACT, FALSE); 924 | } 925 | /* }}} */ 926 | 927 | /* {{{ proto bool CouchdbClient::createDatabase([, string db_name ]) 928 | Creates a CouchDB database 929 | Returns true on success and false for failure. 930 | */ 931 | TC_METHOD(createDatabase) 932 | { 933 | _couchdb_sendrequest(INTERNAL_FUNCTION_PARAM_PASSTHRU, COUCHDB_DB_NONE, TRUE); 934 | } 935 | /* }}} */ 936 | 937 | /* {{{ proto bool CouchdbClient::deleteDatabase([, string db_name]) 938 | Drops (deletes) a CouchDB database 939 | */ 940 | TC_METHOD(deleteDatabase) 941 | { 942 | _couchdb_sendrequest(INTERNAL_FUNCTION_PARAM_PASSTHRU, COUCHDB_DB_DELETE, TRUE); 943 | } 944 | /* }}} */ 945 | 946 | /* {{{ proto array CouchdbClient::getDatabaseInfo([, string db_name ]) 947 | Returns CouchDB database information 948 | */ 949 | TC_METHOD(getDatabaseInfo) 950 | { 951 | _couchdb_getdbinfo(INTERNAL_FUNCTION_PARAM_PASSTHRU, COUCHDB_DB_INFO); 952 | } 953 | /* }}} */ 954 | 955 | /* {{{ proto array CouchdbClient::getDatabaseChanges([, array query_options ]) 956 | Returns CouchDB database change history 957 | */ 958 | TC_METHOD(getDatabaseChanges) 959 | { 960 | php_couchdb_object *local_client; 961 | char *url = NULL, *db_name, *edb_name; 962 | int db_name_len = 0; 963 | smart_str surl = {0}; 964 | long http_response_code; 965 | zend_bool assoc = 1; 966 | zval * zret = NULL, *query_options; 967 | 968 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &query_options) == FAILURE) { 969 | return; 970 | } 971 | 972 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 973 | 974 | CHECK_DB_NAME(local_client); 975 | 976 | edb_name = couchdb_encode_url(db_name); 977 | 978 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 979 | 980 | smart_str_appends(&surl, url); 981 | smart_str_appendc(&surl, '/'); 982 | smart_str_appends(&surl, COUCHDB_CHANGES); 983 | 984 | smart_str_0(&surl); 985 | 986 | efree(edb_name); 987 | 988 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, query_options, NULL, 0 TSRMLS_CC); 989 | 990 | smart_str_free(&surl); 991 | 992 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 993 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 994 | #else 995 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 996 | #endif 997 | } 998 | /* }}} */ 999 | 1000 | /* {{{ proto array CouchdbClient::getAllDocs([, bool by_sequence [, array query_options]]) 1001 | Returns all CouchDB documents in the database 1002 | */ 1003 | TC_METHOD(getAllDocs) 1004 | { 1005 | php_couchdb_object *local_client; 1006 | zval *query_options = NULL, *zret; 1007 | char *db_name = NULL, *edb_name = NULL, *url = NULL; 1008 | smart_str surl = {0}; 1009 | int db_name_len = 0; 1010 | long http_response_code; 1011 | zend_bool by_sequence = 0, assoc = 1; 1012 | 1013 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ba", &by_sequence, &query_options) == FAILURE) { 1014 | return; 1015 | } 1016 | 1017 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1018 | 1019 | CHECK_DB_NAME(local_client); 1020 | 1021 | edb_name = couchdb_encode_url(db_name); 1022 | 1023 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1024 | 1025 | smart_str_appends(&surl, url); 1026 | smart_str_appendc(&surl, '/'); 1027 | smart_str_appends(&surl, edb_name); 1028 | if (by_sequence) { 1029 | smart_str_appends(&surl, COUCHDB_ALL_DOCS_SEQ); 1030 | }else { 1031 | smart_str_appends(&surl, COUCHDB_ALL_DOCS); 1032 | } 1033 | smart_str_0(&surl); 1034 | 1035 | efree(edb_name); 1036 | 1037 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, query_options, NULL, 0 TSRMLS_CC); 1038 | 1039 | smart_str_free(&surl); 1040 | 1041 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1042 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1043 | #else 1044 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1045 | #endif 1046 | 1047 | } 1048 | /* }}} */ 1049 | 1050 | /* {{{ proto object CouchdbClient::getDoc(string doc_id [, array options]) 1051 | Returns a CouchDB document from the database 1052 | */ 1053 | TC_METHOD(getDoc) 1054 | { 1055 | php_couchdb_object *local_client; 1056 | char *doc_id = NULL, *db_name = NULL, *edb_name = NULL, *url = NULL, *edoc_id; 1057 | int doc_id_len = 0, db_name_len = 0; 1058 | smart_str surl = {0}; 1059 | zval *options = NULL, *zret; 1060 | long http_response_code; 1061 | zend_bool assoc = 0; 1062 | zend_bool raw = 0; 1063 | 1064 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ab", &doc_id, &doc_id_len, &options, &raw) == FAILURE) { 1065 | return; 1066 | } 1067 | 1068 | if (!doc_id_len) { 1069 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 1070 | return; 1071 | } 1072 | 1073 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1074 | 1075 | CHECK_DB_NAME(local_client); 1076 | 1077 | edb_name = couchdb_encode_url(db_name); 1078 | 1079 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1080 | 1081 | smart_str_appends(&surl, url); 1082 | smart_str_appendc(&surl, '/'); 1083 | smart_str_appends(&surl, edb_name); 1084 | if (raw) { 1085 | edoc_id = doc_id; 1086 | } else { 1087 | edoc_id = couchdb_encode_url(doc_id); 1088 | } 1089 | smart_str_appendc(&surl, '/'); 1090 | smart_str_appends(&surl, edoc_id); 1091 | smart_str_0(&surl); 1092 | 1093 | efree(edb_name); 1094 | efree(edoc_id); 1095 | 1096 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, options, NULL, 0 TSRMLS_CC); 1097 | 1098 | smart_str_free(&surl); 1099 | 1100 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1101 | PROCESS_JSON_RESULT_COMPART_EX(http_response_code, local_client, assoc); 1102 | #else 1103 | PROCESS_JSON_RESULT_EX(http_response_code, local_client, assoc); 1104 | #endif 1105 | 1106 | } 1107 | /* }}} */ 1108 | 1109 | /* {{{ proto object CouchdbClient::storeDoc(mixed document) 1110 | Stores or updates a CouchDB document 1111 | */ 1112 | TC_METHOD(storeDoc) 1113 | { 1114 | php_couchdb_object *local_client; 1115 | char *doc_id = NULL, *db_name = NULL, *edb_name = NULL, *url = NULL, *edoc_id, *tmp_document = NULL, *http_method = COUCHDB_PUT; 1116 | int doc_id_len = 0, db_name_len = 0, tmp_document_len = 0; 1117 | smart_str surl = {0}, json_string = {0}; 1118 | zval *document = NULL, **zdoc_id = NULL, *zjson_string, *zret, *tmp_json_object; 1119 | long http_response_code; 1120 | zend_bool assoc = 0, document_is_string = 0, got_doc_id = 0; 1121 | HashTable *zdocument_array = NULL; 1122 | HashTable *rheaders = NULL; 1123 | 1124 | 1125 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &document) == FAILURE) { 1126 | return; 1127 | } 1128 | 1129 | if ((Z_TYPE_P(document) != IS_ARRAY) && (Z_TYPE_P(document) != IS_OBJECT) && (Z_TYPE_P(document) != IS_STRING)) { 1130 | COUCHDB_ERROR(0, COUCHDB_DOC_PARAM_TYPE); 1131 | return; 1132 | } 1133 | 1134 | switch (Z_TYPE_P(document)) { 1135 | case IS_ARRAY: 1136 | zdocument_array = HASH_OF(document); 1137 | 1138 | if (zend_hash_find(zdocument_array, "_id", sizeof("_id"), (void**)&zdoc_id) == SUCCESS){ 1139 | got_doc_id = 1; 1140 | } 1141 | break; 1142 | case IS_OBJECT: 1143 | if (zend_hash_find(Z_OBJPROP_P(document), "_id", sizeof("_id"), (void**)&zdoc_id) == SUCCESS){ 1144 | got_doc_id = 1; 1145 | } 1146 | break; 1147 | case IS_STRING: 1148 | document_is_string = 1; 1149 | tmp_document = Z_STRVAL_P(document); 1150 | tmp_document_len = Z_STRLEN_P(document); 1151 | 1152 | MAKE_STD_ZVAL(tmp_json_object); 1153 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1154 | long depth = JSON_PARSER_DEFAULT_DEPTH; 1155 | 1156 | php_json_decode(tmp_json_object, tmp_document, tmp_document_len, assoc, depth TSRMLS_CC); 1157 | #else 1158 | php_json_decode(tmp_json_object, tmp_document, tmp_document_len, assoc TSRMLS_CC); 1159 | #endif 1160 | if (Z_TYPE_P(tmp_json_object) == IS_OBJECT) { 1161 | if (zend_hash_find(Z_OBJPROP_P(tmp_json_object), "_id", sizeof("_id"), (void**)&zdoc_id) == SUCCESS){ 1162 | got_doc_id = 1; 1163 | } 1164 | efree(tmp_json_object); 1165 | }else { 1166 | efree(tmp_json_object); 1167 | COUCHDB_ERROR(0, COUCHDB_INVALID_JSON_STRING); 1168 | return; 1169 | } 1170 | break; 1171 | } 1172 | 1173 | if (got_doc_id) { 1174 | if (Z_TYPE_PP(zdoc_id) != IS_STRING) { 1175 | convert_to_string_ex(zdoc_id); 1176 | doc_id = Z_STRVAL_PP(zdoc_id); 1177 | doc_id_len = Z_STRLEN_PP(zdoc_id); 1178 | }else { 1179 | doc_id = Z_STRVAL_PP(zdoc_id); 1180 | doc_id_len = Z_STRLEN_PP(zdoc_id); 1181 | } 1182 | } 1183 | 1184 | if (!document_is_string) { 1185 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1186 | long json_options = 0; 1187 | 1188 | php_json_encode(&json_string, document, json_options TSRMLS_CC); 1189 | #else 1190 | php_json_encode(&json_string, document TSRMLS_CC); 1191 | #endif 1192 | 1193 | if (!json_string.len) { 1194 | COUCHDB_ERROR(0, COUCHDB_JSON_ENCODE_FAIL); 1195 | smart_str_free(&json_string); 1196 | return; 1197 | } 1198 | 1199 | if (strcmp(json_string.c, "null") == 0) { 1200 | COUCHDB_ERROR(0, COUCHDB_JSON_ENCODE_NULL); 1201 | smart_str_free(&json_string); 1202 | return; 1203 | } 1204 | } 1205 | 1206 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1207 | 1208 | CHECK_DB_NAME(local_client); 1209 | 1210 | edb_name = couchdb_encode_url(db_name); 1211 | 1212 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1213 | 1214 | smart_str_appends(&surl, url); 1215 | smart_str_appendc(&surl, '/'); 1216 | smart_str_appends(&surl, edb_name); 1217 | if (doc_id_len) { 1218 | smart_str_appendc(&surl, '/'); 1219 | edoc_id = couchdb_encode_url(doc_id); 1220 | smart_str_appends(&surl, edoc_id); 1221 | } 1222 | smart_str_0(&surl); 1223 | 1224 | efree(edb_name); 1225 | if (doc_id_len) { 1226 | efree(edoc_id); 1227 | } 1228 | 1229 | if (!doc_id_len) { 1230 | http_method = COUCHDB_POST; 1231 | } 1232 | 1233 | //add json header 1234 | ALLOC_HASHTABLE(rheaders); 1235 | zend_hash_init(rheaders, 0, NULL, ZVAL_PTR_DTOR, 0); 1236 | 1237 | couchdb_add_req_arg(rheaders, "Content-Type", "application/json" TSRMLS_CC); 1238 | 1239 | if (!document_is_string) { 1240 | smart_str_0(&json_string); 1241 | 1242 | MAKE_STD_ZVAL(zjson_string); 1243 | ZVAL_STRINGL(zjson_string, json_string.c, json_string.len, 1); 1244 | 1245 | http_response_code = couchdb_prepare_request(local_client, surl.c, http_method, zjson_string, rheaders, 0 TSRMLS_CC); 1246 | 1247 | zval_ptr_dtor(&zjson_string); 1248 | smart_str_free(&json_string); 1249 | }else { 1250 | http_response_code = couchdb_prepare_request(local_client, surl.c, http_method, document, rheaders, 0 TSRMLS_CC); 1251 | } 1252 | 1253 | smart_str_free(&surl); 1254 | FREE_ARGS_HASH(rheaders); 1255 | 1256 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1257 | PROCESS_JSON_RESULT_COMPART_EX(http_response_code, local_client, assoc); 1258 | #else 1259 | PROCESS_JSON_RESULT_EX(http_response_code, local_client, assoc); 1260 | #endif 1261 | } 1262 | /* }}} */ 1263 | 1264 | /* {{{ proto bool CouchdbClient::deleteDoc(string doc_id, string rev) 1265 | Deletes a CouchDB document 1266 | */ 1267 | TC_METHOD(deleteDoc) 1268 | { 1269 | php_couchdb_object *local_client; 1270 | zval *zret; 1271 | char *db_name = NULL, *edb_name = NULL, *url = NULL, *doc_id, *rev, *edoc_id; 1272 | smart_str surl = {0}; 1273 | int db_name_len = 0, doc_id_len = 0, rev_len = 0; 1274 | long http_response_code; 1275 | 1276 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &doc_id, &doc_id_len, &rev, &rev_len) == FAILURE) { 1277 | return; 1278 | } 1279 | 1280 | if (!doc_id_len || !rev_len) { 1281 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 1282 | return; 1283 | } 1284 | 1285 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1286 | 1287 | CHECK_DB_NAME(local_client); 1288 | 1289 | edb_name = couchdb_encode_url(db_name); 1290 | 1291 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1292 | 1293 | smart_str_appends(&surl, url); 1294 | smart_str_appendc(&surl, '/'); 1295 | smart_str_appends(&surl, edb_name); 1296 | edoc_id = couchdb_encode_url(doc_id); 1297 | smart_str_appendc(&surl, '/'); 1298 | smart_str_appends(&surl, edoc_id); 1299 | smart_str_appends(&surl, "?rev="); 1300 | smart_str_appends(&surl, rev); 1301 | smart_str_0(&surl); 1302 | 1303 | efree(edb_name); 1304 | efree(edoc_id); 1305 | 1306 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_DELETE, NULL, NULL, 0 TSRMLS_CC); 1307 | 1308 | smart_str_free(&surl); 1309 | 1310 | PROCESS_BOOL_RESULT_EX(http_response_code, local_client, COUCHDB_STATUS_OK); 1311 | } 1312 | /* }}} */ 1313 | 1314 | /* {{{ proto array CouchdbClient::storeDocs(mixed document [, bool all_or_nothing]) 1315 | Stores or updates multiple CouchDB documents */ 1316 | TC_METHOD(storeDocs) 1317 | { 1318 | php_couchdb_object *local_client; 1319 | zval *documents = NULL, *tmp_json_object, *zjson_string, *zret; 1320 | char *db_name, *edb_name, *tmp_document, *url, *final_json_string, *all_or_nothing_str = "false"; 1321 | smart_str surl = {0}, json_string = {0}; 1322 | int db_name_len = 0, tmp_document_len = 0, final_json_string_len = 0; 1323 | long http_response_code; 1324 | zend_bool all_or_nothing = 0, document_is_string = 0, assoc = 1; 1325 | HashTable *rheaders = NULL; 1326 | 1327 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &documents, &all_or_nothing) == FAILURE) { 1328 | return; 1329 | } 1330 | 1331 | if ((Z_TYPE_P(documents) != IS_ARRAY) && (Z_TYPE_P(documents) != IS_OBJECT) && (Z_TYPE_P(documents) != IS_STRING)) { 1332 | COUCHDB_ERROR(0, COUCHDB_DOC_PARAM_TYPE); 1333 | return; 1334 | } 1335 | 1336 | if (Z_TYPE_P(documents) == IS_STRING) { 1337 | document_is_string = 1; 1338 | tmp_document = Z_STRVAL_P(documents); 1339 | tmp_document_len = Z_STRLEN_P(documents); 1340 | 1341 | MAKE_STD_ZVAL(tmp_json_object); 1342 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1343 | long depth = JSON_PARSER_DEFAULT_DEPTH; 1344 | 1345 | php_json_decode(tmp_json_object, tmp_document, tmp_document_len, assoc, depth TSRMLS_CC); 1346 | #else 1347 | php_json_decode(tmp_json_object, tmp_document, tmp_document_len, assoc TSRMLS_CC); 1348 | #endif 1349 | if (Z_TYPE_P(tmp_json_object) == IS_OBJECT) { 1350 | efree(tmp_json_object); 1351 | }else { 1352 | efree(tmp_json_object); 1353 | COUCHDB_ERROR(0, COUCHDB_INVALID_JSON_STRING); 1354 | return; 1355 | } 1356 | }else { 1357 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1358 | long json_options = 0; 1359 | 1360 | php_json_encode(&json_string, documents, json_options TSRMLS_CC); 1361 | #else 1362 | php_json_encode(&json_string, documents TSRMLS_CC); 1363 | #endif 1364 | 1365 | if (!json_string.len) { 1366 | COUCHDB_ERROR(0, COUCHDB_JSON_ENCODE_FAIL); 1367 | smart_str_free(&json_string); 1368 | return; 1369 | } 1370 | 1371 | if (strcmp(json_string.c, "null") == 0) { 1372 | COUCHDB_ERROR(0, COUCHDB_JSON_ENCODE_NULL); 1373 | smart_str_free(&json_string); 1374 | return; 1375 | } 1376 | } 1377 | 1378 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1379 | 1380 | CHECK_DB_NAME(local_client); 1381 | 1382 | edb_name = couchdb_encode_url(db_name); 1383 | 1384 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1385 | 1386 | smart_str_appends(&surl, url); 1387 | smart_str_appendc(&surl, '/'); 1388 | smart_str_appends(&surl, edb_name); 1389 | smart_str_appends(&surl, COUCHDB_BULK_DOCS); 1390 | smart_str_0(&surl); 1391 | 1392 | efree(edb_name); 1393 | 1394 | // we should add the json header in every case, either no one will let us on the couch. 1395 | ALLOC_HASHTABLE(rheaders); 1396 | zend_hash_init(rheaders, 0, NULL, ZVAL_PTR_DTOR, 0); 1397 | couchdb_add_req_arg(rheaders, "Content-Type", "application/json" TSRMLS_CC); 1398 | 1399 | if (!document_is_string) { 1400 | 1401 | if (all_or_nothing) { 1402 | all_or_nothing_str = "true"; 1403 | } 1404 | 1405 | smart_str_0(&json_string); 1406 | final_json_string_len = spprintf(&final_json_string, 0, "{\"all_or_nothing\":%s,\"docs\":%s}", all_or_nothing_str, json_string.c); 1407 | 1408 | MAKE_STD_ZVAL(zjson_string); 1409 | ZVAL_STRINGL(zjson_string, final_json_string, final_json_string_len, 1); 1410 | 1411 | smart_str_free(&json_string); 1412 | 1413 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_POST, zjson_string, rheaders, 0 TSRMLS_CC); 1414 | 1415 | zval_ptr_dtor(&zjson_string); 1416 | efree(final_json_string); 1417 | }else { 1418 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_POST, documents, rheaders, 0 TSRMLS_CC); 1419 | } 1420 | 1421 | smart_str_free(&surl); 1422 | 1423 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1424 | PROCESS_JSON_RESULT_COMPART_EX(http_response_code, local_client, assoc); 1425 | #else 1426 | PROCESS_JSON_RESULT_EX(http_response_code, local_client, assoc); 1427 | #endif 1428 | 1429 | } 1430 | /* }}} */ 1431 | 1432 | /* {{{ proto object CouchdbClient::getTempView(mixed temp_view) 1433 | Executes a temporary CouchDB view query */ 1434 | TC_METHOD(getTempView) 1435 | { 1436 | php_couchdb_object *local_client; 1437 | zval *temp_view, *tmp_json_object, *zjson_string, *zret; 1438 | char *db_name, *edb_name, *url, *tmp_document; 1439 | smart_str json_string = {0}, surl = {0}; 1440 | int db_name_len = 0, tmp_document_len = 0; 1441 | long http_response_code; 1442 | zend_bool document_is_string = 0, assoc = 0; 1443 | HashTable *rheaders = NULL; 1444 | 1445 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &temp_view) == FAILURE) { 1446 | return; 1447 | } 1448 | 1449 | if ((Z_TYPE_P(temp_view) != IS_ARRAY) && (Z_TYPE_P(temp_view) != IS_OBJECT) && (Z_TYPE_P(temp_view) != IS_STRING)) { 1450 | COUCHDB_ERROR(0, COUCHDB_DOC_PARAM_TYPE); 1451 | return; 1452 | } 1453 | 1454 | if (Z_TYPE_P(temp_view) == IS_STRING) { 1455 | document_is_string = 1; 1456 | tmp_document = Z_STRVAL_P(temp_view); 1457 | tmp_document_len = Z_STRLEN_P(temp_view); 1458 | MAKE_STD_ZVAL(tmp_json_object); 1459 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1460 | long depth = JSON_PARSER_DEFAULT_DEPTH; 1461 | php_json_decode(tmp_json_object, tmp_document, tmp_document_len, assoc, depth TSRMLS_CC); 1462 | #else 1463 | php_json_decode(tmp_json_object, tmp_document, tmp_document_len, assoc TSRMLS_CC); 1464 | #endif 1465 | if (Z_TYPE_P(tmp_json_object) == IS_OBJECT) { 1466 | efree(tmp_json_object); 1467 | }else { 1468 | efree(tmp_json_object); 1469 | COUCHDB_ERROR(0, COUCHDB_JSON_INVALID); 1470 | return; 1471 | } 1472 | }else { 1473 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1474 | long json_options = 0; 1475 | php_json_encode(&json_string, temp_view, json_options TSRMLS_CC); 1476 | #else 1477 | php_json_encode(&json_string, temp_view TSRMLS_CC); 1478 | #endif 1479 | 1480 | if (!json_string.len) { 1481 | COUCHDB_ERROR(0, COUCHDB_JSON_ENCODE_FAIL); 1482 | smart_str_free(&json_string); 1483 | return; 1484 | } 1485 | 1486 | if (strcmp(json_string.c, "null") == 0) { 1487 | COUCHDB_ERROR(0, COUCHDB_JSON_ENCODE_NULL); 1488 | smart_str_free(&json_string); 1489 | return; 1490 | } 1491 | } 1492 | 1493 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1494 | 1495 | CHECK_DB_NAME(local_client); 1496 | 1497 | edb_name = couchdb_encode_url(db_name); 1498 | 1499 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1500 | 1501 | smart_str_appends(&surl, url); 1502 | smart_str_appendc(&surl, '/'); 1503 | smart_str_appends(&surl, edb_name); 1504 | smart_str_appends(&surl, COUCHDB_TEMP_VIEW); 1505 | smart_str_0(&surl); 1506 | 1507 | efree(edb_name); 1508 | 1509 | ALLOC_HASHTABLE(rheaders); 1510 | zend_hash_init(rheaders, 0, NULL, ZVAL_PTR_DTOR, 0); 1511 | 1512 | couchdb_add_req_arg(rheaders, "Content-Type", "application/json" TSRMLS_CC); 1513 | 1514 | if (!document_is_string) { 1515 | MAKE_STD_ZVAL(zjson_string); 1516 | ZVAL_STRINGL(zjson_string, json_string.c, json_string.len, 1); 1517 | 1518 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_POST, zjson_string, rheaders, 0 TSRMLS_CC); 1519 | 1520 | smart_str_free(&json_string); 1521 | zval_ptr_dtor(&zjson_string); 1522 | }else { 1523 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_POST, temp_view, rheaders, 0 TSRMLS_CC); 1524 | } 1525 | 1526 | smart_str_free(&surl); 1527 | FREE_ARGS_HASH(rheaders); 1528 | 1529 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1530 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1531 | #else 1532 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1533 | #endif 1534 | 1535 | } 1536 | /* }}} */ 1537 | 1538 | /* {{{ proto object CouchdbClient::getView(string design_doc, string view_name [, array query_options]) 1539 | Executes a CouchDB view query */ 1540 | TC_METHOD(getView) 1541 | { 1542 | php_couchdb_object *local_client; 1543 | char *db_name, *edb_name, *url, *design_doc, *view_name, *edesign_doc, *eview_name; 1544 | int db_name_len = 0, design_doc_len = 0, view_name_len = 0; 1545 | smart_str surl = {0}; 1546 | long http_response_code; 1547 | zval *zret, *query_options = NULL; 1548 | zend_bool assoc = 0; 1549 | 1550 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|a", &design_doc, &design_doc_len, 1551 | &view_name, &view_name_len, &query_options) == FAILURE) { 1552 | return; 1553 | } 1554 | 1555 | if (!view_name_len || !design_doc_len) { 1556 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 1557 | return; 1558 | } 1559 | 1560 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1561 | 1562 | CHECK_DB_NAME(local_client); 1563 | 1564 | edb_name = couchdb_encode_url(db_name); 1565 | edesign_doc = couchdb_encode_url(design_doc); 1566 | eview_name = couchdb_encode_url(view_name); 1567 | 1568 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1569 | 1570 | smart_str_appends(&surl, url); 1571 | smart_str_appendc(&surl, '/'); 1572 | smart_str_appends(&surl, edb_name); 1573 | smart_str_appends(&surl, "/_design/"); 1574 | smart_str_appends(&surl, edesign_doc); 1575 | smart_str_appends(&surl, "/_view/"); 1576 | smart_str_appends(&surl, eview_name); 1577 | smart_str_0(&surl); 1578 | 1579 | efree(edb_name); 1580 | efree(edesign_doc); 1581 | efree(eview_name); 1582 | 1583 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, query_options, NULL, 0 TSRMLS_CC); 1584 | smart_str_free(&surl); 1585 | 1586 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1587 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1588 | #else 1589 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1590 | #endif 1591 | 1592 | } 1593 | /* }}} */ 1594 | 1595 | /* {{{ proto array CouchdbClient::copyDoc(string doc_id, string new_doc_id [, new_doc_revision]) 1596 | Copies a CouchDB document 1597 | */ 1598 | TC_METHOD(copyDoc) 1599 | { 1600 | php_couchdb_object *local_client; 1601 | zval *zret; 1602 | char *db_name, *edb_name, *doc_id, *new_doc_id, *url, *new_doc_revision, *edoc_id, *enew_doc_id, *buff; 1603 | int db_name_len = 0, doc_id_len = 0, new_doc_id_len = 0, new_doc_revision_len = 0; 1604 | smart_str surl = {0}; 1605 | long http_response_code; 1606 | zend_bool assoc = 1; 1607 | HashTable *rheaders = NULL; 1608 | 1609 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s", &doc_id, &doc_id_len, 1610 | &new_doc_id, &new_doc_id_len, &new_doc_revision, 1611 | &new_doc_revision_len) == FAILURE) { 1612 | return; 1613 | } 1614 | 1615 | if (!doc_id_len || !new_doc_id_len) { 1616 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 1617 | return; 1618 | } 1619 | 1620 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1621 | 1622 | CHECK_DB_NAME(local_client); 1623 | 1624 | edb_name = couchdb_encode_url(db_name); 1625 | edoc_id = couchdb_encode_url(doc_id); 1626 | 1627 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1628 | 1629 | smart_str_appends(&surl, url); 1630 | smart_str_appendc(&surl, '/'); 1631 | smart_str_appends(&surl, edb_name); 1632 | smart_str_appendc(&surl, '/'); 1633 | smart_str_appends(&surl, edoc_id); 1634 | smart_str_0(&surl); 1635 | 1636 | efree(edb_name); 1637 | efree(edoc_id); 1638 | 1639 | enew_doc_id = couchdb_encode_url(new_doc_id); 1640 | 1641 | ALLOC_HASHTABLE(rheaders); 1642 | zend_hash_init(rheaders, 0, NULL, ZVAL_PTR_DTOR, 0); 1643 | 1644 | if (!new_doc_revision_len) { 1645 | couchdb_add_req_arg(rheaders, "Destination", enew_doc_id TSRMLS_CC); 1646 | }else { 1647 | spprintf(&buff, 0, "%s?rev=%s", enew_doc_id, new_doc_revision); 1648 | couchdb_add_req_arg(rheaders, "Destination", buff TSRMLS_CC); 1649 | efree(buff); 1650 | } 1651 | 1652 | 1653 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_COPY, NULL, rheaders, 0 TSRMLS_CC); 1654 | 1655 | efree(enew_doc_id); 1656 | smart_str_free(&surl); 1657 | FREE_ARGS_HASH(rheaders); 1658 | 1659 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1660 | PROCESS_JSON_RESULT_COMPART_EX(http_response_code, local_client, assoc); 1661 | #else 1662 | PROCESS_JSON_RESULT_EX(http_response_code, local_client, assoc); 1663 | #endif 1664 | 1665 | } 1666 | /* }}} */ 1667 | 1668 | /* {{{ proto array CouchdbClient::storeAttachment(string doc_id, string filename, string attachment_name, string content_type [, string doc_rev]) 1669 | Stores an an attachment to the database 1670 | */ 1671 | TC_METHOD(storeAttachment) 1672 | { 1673 | php_couchdb_object *local_client; 1674 | char *db_name, *edb_name, *doc_id, *edoc_id, *filename, *attachment_name, *content_type, *doc_rev, *url; 1675 | char *file_contents, *eattachment_name; 1676 | int db_name_len = 0, doc_id_len = 0, filename_len = 0, attachment_name_len = 0, content_type_len = 0, doc_rev_len = 0, len, new_len; 1677 | smart_str surl = {0}; 1678 | php_stream *file_stream; 1679 | zval *zret; 1680 | long http_response_code, maxlen = PHP_STREAM_COPY_ALL; 1681 | zend_bool assoc = 0; 1682 | HashTable *rheaders = NULL; 1683 | 1684 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssss|s", &doc_id, &doc_id_len, &filename, &filename_len, 1685 | &attachment_name, &attachment_name_len, &content_type, &content_type_len, &doc_rev, 1686 | &doc_rev_len) == FAILURE) { 1687 | return; 1688 | } 1689 | 1690 | if (!doc_id_len || !filename_len || !attachment_name_len || !content_type_len) { 1691 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 1692 | return; 1693 | } 1694 | 1695 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1696 | 1697 | CHECK_DB_NAME(local_client); 1698 | 1699 | file_stream = php_stream_open_wrapper_ex(filename, "rb", 0 | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, NULL); 1700 | if (!file_stream) { 1701 | COUCHDB_ERROR(0, COUCHDB_FILE_OPEN_FAIL, filename); 1702 | return; 1703 | } 1704 | 1705 | if (!((len = php_stream_copy_to_mem(file_stream, &file_contents, maxlen, 0)) > 0)) { 1706 | if (len == 0) { 1707 | COUCHDB_ERROR(0, COUCHDB_FILE_EMPTY, filename); 1708 | return; 1709 | }else { 1710 | COUCHDB_ERROR(0, COUCHDB_FILE_READ_FAIL, filename); 1711 | return; 1712 | } 1713 | } 1714 | 1715 | php_stream_close(file_stream); 1716 | 1717 | edb_name = couchdb_encode_url(db_name); 1718 | edoc_id = couchdb_encode_url(doc_id); 1719 | eattachment_name = couchdb_encode_url(attachment_name); 1720 | 1721 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1722 | 1723 | smart_str_appends(&surl, url); 1724 | smart_str_appendc(&surl, '/'); 1725 | smart_str_appends(&surl, edb_name); 1726 | smart_str_appendc(&surl, '/'); 1727 | smart_str_appends(&surl, edoc_id); 1728 | smart_str_appendc(&surl, '/'); 1729 | smart_str_appends(&surl, eattachment_name); 1730 | if (doc_rev_len) { 1731 | smart_str_appends(&surl, "?rev="); 1732 | smart_str_appends(&surl, doc_rev); 1733 | } 1734 | smart_str_0(&surl); 1735 | 1736 | efree(edb_name); 1737 | efree(edoc_id); 1738 | efree(eattachment_name); 1739 | 1740 | ALLOC_HASHTABLE(rheaders); 1741 | zend_hash_init(rheaders, 0, NULL, ZVAL_PTR_DTOR, 0); 1742 | 1743 | couchdb_add_req_arg(rheaders, "Content-Type", content_type TSRMLS_CC); 1744 | 1745 | smart_str_free(&local_client->lastrequest); 1746 | smart_str_appendl(&local_client->lastrequest, file_contents, len); 1747 | smart_str_0(&local_client->lastrequest); 1748 | 1749 | efree(file_contents); 1750 | 1751 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_PUT, NULL, rheaders, 1 TSRMLS_CC); 1752 | 1753 | smart_str_free(&surl); 1754 | FREE_ARGS_HASH(rheaders); 1755 | 1756 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1757 | PROCESS_JSON_RESULT_COMPART_EX(http_response_code, local_client, assoc); 1758 | #else 1759 | PROCESS_JSON_RESULT_EX(http_response_code, local_client, assoc); 1760 | #endif 1761 | 1762 | } 1763 | /* }}} */ 1764 | 1765 | /* {{{ proto array CouchdbClient::deleteAttachment(string doc_id, string attachment_name, string doc_rev) 1766 | Deletes a CouchDB attachment 1767 | */ 1768 | TC_METHOD(deleteAttachment) 1769 | { 1770 | php_couchdb_object *local_client; 1771 | zval *zret; 1772 | char *db_name, *edb_name, *doc_id, *edoc_id, *attachment_name, *eattachment_name, *doc_rev, *url; 1773 | int db_name_len = 0, doc_id_len = 0, attachment_name_len = 0, doc_rev_len = 0; 1774 | smart_str surl = {0}; 1775 | long http_response_code; 1776 | zend_bool assoc = 0; 1777 | 1778 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &doc_id, &doc_id_len, &attachment_name, 1779 | &attachment_name_len, &doc_rev, &doc_rev_len) == FAILURE) { 1780 | return; 1781 | } 1782 | 1783 | if (!doc_id_len || !attachment_name_len || !doc_rev_len) { 1784 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 1785 | return; 1786 | } 1787 | 1788 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1789 | 1790 | CHECK_DB_NAME(local_client); 1791 | 1792 | edb_name = couchdb_encode_url(db_name); 1793 | edoc_id = couchdb_encode_url(doc_id); 1794 | eattachment_name = couchdb_encode_url(attachment_name); 1795 | 1796 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1797 | 1798 | smart_str_appends(&surl, url); 1799 | smart_str_appendc(&surl, '/'); 1800 | smart_str_appends(&surl, edb_name); 1801 | smart_str_appendc(&surl, '/'); 1802 | smart_str_appends(&surl, edoc_id); 1803 | smart_str_appendc(&surl, '/'); 1804 | smart_str_appends(&surl, eattachment_name); 1805 | smart_str_appends(&surl, "?rev="); 1806 | smart_str_appends(&surl, doc_rev); 1807 | smart_str_0(&surl); 1808 | 1809 | efree(edb_name); 1810 | efree(edoc_id); 1811 | efree(eattachment_name); 1812 | 1813 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_DELETE, NULL, NULL, 0 TSRMLS_CC); 1814 | 1815 | smart_str_free(&surl); 1816 | 1817 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1818 | PROCESS_JSON_RESULT_COMPART_EX(http_response_code, local_client, assoc); 1819 | #else 1820 | PROCESS_JSON_RESULT_EX(http_response_code, local_client, assoc); 1821 | #endif 1822 | 1823 | } 1824 | /* }}} */ 1825 | 1826 | /* {{{ proto array CouchdbClient::getServerInfo() 1827 | Returns CouchDB server information */ 1828 | TC_METHOD(getServerInfo) 1829 | { 1830 | php_couchdb_object *local_client; 1831 | char *url = NULL; 1832 | long http_response_code; 1833 | zend_bool assoc = 1; 1834 | zval * zret = NULL; 1835 | 1836 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { 1837 | return; 1838 | } 1839 | 1840 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1841 | 1842 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1843 | 1844 | http_response_code = couchdb_prepare_request(local_client, url, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 1845 | 1846 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1847 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1848 | #else 1849 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1850 | #endif 1851 | 1852 | } 1853 | /* }}} */ 1854 | 1855 | /* {{{ proto array CouchdbClient::getServerConfig() 1856 | Returns CouchDB server configuration */ 1857 | TC_METHOD(getServerConfig) 1858 | { 1859 | php_couchdb_object *local_client; 1860 | char *url = NULL, *group; 1861 | int group_len = 0; 1862 | smart_str surl = {0}; 1863 | long http_response_code; 1864 | zend_bool assoc = 1; 1865 | zval * zret = NULL; 1866 | 1867 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &group, &group_len) == FAILURE) { 1868 | return; 1869 | } 1870 | 1871 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1872 | 1873 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1874 | 1875 | smart_str_appends(&surl, url); 1876 | smart_str_appends(&surl, COUCHDB_CONFIG); 1877 | if (group_len) { 1878 | smart_str_appendc(&surl, '/'); 1879 | smart_str_appends(&surl, group); 1880 | } 1881 | smart_str_0(&surl); 1882 | 1883 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 1884 | 1885 | smart_str_free(&surl); 1886 | 1887 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1888 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1889 | #else 1890 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1891 | #endif 1892 | 1893 | } 1894 | /* }}} */ 1895 | 1896 | /* {{{ proto array CouchdbClient::getServerStats() 1897 | Returns CouchDB server statistics */ 1898 | TC_METHOD(getServerStats) 1899 | { 1900 | php_couchdb_object *local_client; 1901 | char *url = NULL; 1902 | smart_str surl = {0}; 1903 | long http_response_code; 1904 | zend_bool assoc = 1; 1905 | zval * zret = NULL; 1906 | 1907 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { 1908 | return; 1909 | } 1910 | 1911 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1912 | 1913 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1914 | 1915 | smart_str_appends(&surl, url); 1916 | smart_str_appends(&surl, COUCHDB_STATS); 1917 | smart_str_0(&surl); 1918 | 1919 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 1920 | 1921 | smart_str_free(&surl); 1922 | 1923 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1924 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1925 | #else 1926 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1927 | #endif 1928 | 1929 | } 1930 | /* }}} */ 1931 | 1932 | /* {{{ proto array CouchdbClient::listDatabases() 1933 | List the databases available on a CouchDB server. 1934 | */ 1935 | TC_METHOD(listDatabases) 1936 | { 1937 | php_couchdb_object *local_client; 1938 | char *url = NULL; 1939 | smart_str surl = {0}; 1940 | long http_response_code; 1941 | zend_bool assoc = 1; 1942 | zval * zret = NULL; 1943 | 1944 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { 1945 | return; 1946 | } 1947 | 1948 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1949 | 1950 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1951 | 1952 | smart_str_appends(&surl, url); 1953 | smart_str_appends(&surl, COUCHDB_ALL_DBS); 1954 | smart_str_0(&surl); 1955 | 1956 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 1957 | 1958 | smart_str_free(&surl); 1959 | 1960 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1961 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1962 | #else 1963 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 1964 | #endif 1965 | 1966 | } 1967 | /* }}} */ 1968 | 1969 | /* {{{ proto array CouchdbClient::listActiveTasks() 1970 | Lists active tasks */ 1971 | TC_METHOD(listActiveTasks) 1972 | { 1973 | php_couchdb_object *local_client; 1974 | char *url; 1975 | smart_str surl = {0}; 1976 | long http_response_code; 1977 | zval *zret = NULL; 1978 | zend_bool assoc = 1; 1979 | 1980 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { 1981 | return; 1982 | } 1983 | 1984 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 1985 | 1986 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 1987 | 1988 | smart_str_appends(&surl, url); 1989 | smart_str_appends(&surl, COUCHDB_ACTIVE_TASK); 1990 | smart_str_0(&surl); 1991 | 1992 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 1993 | 1994 | smart_str_free(&surl); 1995 | 1996 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 1997 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 1998 | #else 1999 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 2000 | #endif 2001 | 2002 | } 2003 | /* }}} */ 2004 | 2005 | /* {{{ proto array CouchdbClient::getUuids([, int count]) 2006 | Get server generated uuids */ 2007 | TC_METHOD(getUuids) 2008 | { 2009 | php_couchdb_object *local_client; 2010 | char *url = NULL, *buff = NULL; 2011 | smart_str surl = {0}; 2012 | int count = 0; 2013 | long http_response_code; 2014 | zend_bool assoc = 0; 2015 | zval * zret = NULL; 2016 | 2017 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &count) == FAILURE) { 2018 | return; 2019 | } 2020 | 2021 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2022 | 2023 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 2024 | 2025 | smart_str_appends(&surl, url); 2026 | smart_str_appends(&surl, COUCHDB_GET_UUIDS); 2027 | if (count) { 2028 | spprintf(&buff, 0, "?count=%d", count); 2029 | smart_str_appends(&surl, buff); 2030 | efree(buff); 2031 | } 2032 | smart_str_0(&surl); 2033 | 2034 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_GET, NULL, NULL, 0 TSRMLS_CC); 2035 | 2036 | smart_str_free(&surl); 2037 | 2038 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 2039 | PROCESS_JSON_RESULT_COMPART(http_response_code, local_client, assoc); 2040 | #else 2041 | PROCESS_JSON_RESULT(http_response_code, local_client, assoc); 2042 | #endif 2043 | 2044 | } 2045 | /* }}} */ 2046 | 2047 | /* {{{ proto bool CouchdbClient::startReplication(string source, string destination [, bool set_continuous]) 2048 | Start CouchDB replication 2049 | */ 2050 | TC_METHOD(startReplication) 2051 | { 2052 | php_couchdb_object *local_client; 2053 | char *url = NULL, *source, *destination, *buff; 2054 | int source_len = 0, destination_len = 0, tlen = 0; 2055 | smart_str surl = {0}; 2056 | long http_response_code; 2057 | zval * zret = NULL, *zjson_string; 2058 | zend_bool set_continuous = 0; 2059 | 2060 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &source, &source_len, &destination, &destination_len, &set_continuous) == FAILURE) { 2061 | return; 2062 | } 2063 | 2064 | if (!source_len || !destination_len) { 2065 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 2066 | return; 2067 | } 2068 | 2069 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2070 | 2071 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 2072 | 2073 | smart_str_appends(&surl, url); 2074 | smart_str_appends(&surl, COUCHDB_REPLICATE); 2075 | smart_str_0(&surl); 2076 | 2077 | if (set_continuous) { 2078 | tlen = spprintf(&buff, 0, "{\"source\":\"%s\",\"target\":\"%s\",\"continuous\":true}", source, destination); 2079 | }else { 2080 | tlen = spprintf(&buff, 0, "{\"source\":\"%s\",\"target\":\"%s\"}", source, destination); 2081 | } 2082 | 2083 | MAKE_STD_ZVAL(zjson_string); 2084 | ZVAL_STRINGL(zjson_string, buff, tlen, 1); 2085 | 2086 | efree(buff); 2087 | 2088 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_POST, zjson_string, NULL, 0 TSRMLS_CC); 2089 | 2090 | zval_ptr_dtor(&zjson_string); 2091 | smart_str_free(&surl); 2092 | 2093 | PROCESS_BOOL_RESULT(http_response_code, local_client, COUCHDB_STATUS_OK); 2094 | } 2095 | /* }}} */ 2096 | 2097 | /* {{{ proto mixed CouchdbClient::getLastResponse([, bool json_decode]) 2098 | Get the last recieved CouchDb server response */ 2099 | TC_METHOD(getLastResponse) 2100 | { 2101 | php_couchdb_object *local_client; 2102 | zend_bool json_decode = 0, assoc = 0; 2103 | 2104 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &json_decode) == FAILURE) { 2105 | return; 2106 | } 2107 | 2108 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2109 | 2110 | if (local_client->lastresponse.c) { 2111 | if (json_decode) { 2112 | #if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 3) || (PHP_MAJOR_VERSION > 5) 2113 | long depth = JSON_PARSER_DEFAULT_DEPTH; 2114 | php_json_decode(return_value, local_client->lastresponse.c, local_client->lastresponse.len, assoc, depth TSRMLS_CC); 2115 | #else 2116 | php_json_decode(return_value, local_client->lastresponse.c, local_client->lastresponse.len, assoc TSRMLS_CC); 2117 | #endif 2118 | }else { 2119 | RETURN_STRINGL(local_client->lastresponse.c, local_client->lastresponse.len, 1); 2120 | } 2121 | } 2122 | } 2123 | /* }}} */ 2124 | 2125 | /* {{{ proto bool CouchdbClient::setCAPath(string ca_path, string ca_info) 2126 | Set the Certificate Authority information */ 2127 | TC_METHOD(setCAPath) 2128 | { 2129 | php_couchdb_object *local_client; 2130 | char *ca_path, *ca_info; 2131 | int ca_path_len, ca_info_len; 2132 | zval *zca_path, *zca_info; 2133 | 2134 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2135 | 2136 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &ca_path, &ca_path_len, &ca_info, &ca_info_len) == FAILURE) { 2137 | return; 2138 | } 2139 | 2140 | if (ca_path_len) { 2141 | MAKE_STD_ZVAL(zca_path); 2142 | ZVAL_STRINGL(zca_path, ca_path, ca_path_len, 1); 2143 | if (couchdb_set_property(local_client, zca_path, COUCHDB_CA_PATH TSRMLS_CC) != SUCCESS) { 2144 | RETURN_NULL(); 2145 | } 2146 | } 2147 | 2148 | if (ca_info_len) { 2149 | MAKE_STD_ZVAL(zca_info); 2150 | ZVAL_STRINGL(zca_info, ca_info, ca_info_len, 1); 2151 | if (couchdb_set_property(local_client, zca_info, COUCHDB_CA_INFO TSRMLS_CC) != SUCCESS) { 2152 | RETURN_NULL(); 2153 | } 2154 | } 2155 | 2156 | RETURN_TRUE; 2157 | } 2158 | /* }}} */ 2159 | 2160 | /* {{{ proto array CouchdbClient::getCAPath() 2161 | Get the Certificate Authority information */ 2162 | TC_METHOD(getCAPath) 2163 | { 2164 | php_couchdb_object *local_client; 2165 | zval **zca_path, **zca_info; 2166 | 2167 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2168 | 2169 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { 2170 | return; 2171 | } 2172 | 2173 | zca_info = couchdb_get_property(local_client, COUCHDB_CA_INFO TSRMLS_CC); 2174 | zca_path = couchdb_get_property(local_client, COUCHDB_CA_PATH TSRMLS_CC); 2175 | 2176 | array_init(return_value); 2177 | 2178 | if (zca_info || zca_path) { 2179 | if(zca_info) { 2180 | add_assoc_stringl(return_value, "ca_info", Z_STRVAL_PP(zca_info), Z_STRLEN_PP(zca_info), 1); 2181 | } 2182 | 2183 | if(zca_path) { 2184 | add_assoc_stringl(return_value, "ca_path", Z_STRVAL_PP(zca_path), Z_STRLEN_PP(zca_path), 1); 2185 | } 2186 | } 2187 | } 2188 | /* }}} */ 2189 | 2190 | /* {{{ proto bool CouchdbClient::selectDB(string db_name) 2191 | Selects a CouchDb database 2192 | */ 2193 | TC_METHOD(selectDB) 2194 | { 2195 | char *db_name = NULL; 2196 | int db_name_len = 0; 2197 | php_couchdb_object *local_client; 2198 | zval *dbp = NULL; 2199 | 2200 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2201 | 2202 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &db_name, &db_name_len) == FAILURE) { 2203 | return; 2204 | } 2205 | 2206 | if (!db_name_len) { 2207 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 2208 | return; 2209 | } 2210 | 2211 | MAKE_STD_ZVAL(dbp); 2212 | ZVAL_STRINGL(dbp, db_name, db_name_len, 1); 2213 | 2214 | if (couchdb_set_property(local_client, dbp, COUCHDB_DB TSRMLS_CC) != SUCCESS) { 2215 | return; 2216 | } 2217 | 2218 | RETURN_TRUE; 2219 | } 2220 | /* }}} */ 2221 | 2222 | /* {{{ proto bool CouchdbClient::createAdminUser(string user_name, string password) 2223 | Creates and admin user */ 2224 | TC_METHOD(createAdminUser) 2225 | { 2226 | php_couchdb_object *local_client; 2227 | char *url, *user_name, *password, *euser_name, *epassword, *buff = NULL; 2228 | smart_str surl = {0}; 2229 | int user_name_len = 0, password_len = 0, tlen = 0; 2230 | long http_response_code; 2231 | zval *zret, *put_payload; 2232 | 2233 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &user_name, &user_name_len, &password, &password_len) == FAILURE) { 2234 | return; 2235 | } 2236 | 2237 | if (!user_name_len || !password_len) { 2238 | COUCHDB_ERROR(0, COUCHDB_EMPTY_PARAMS); 2239 | return; 2240 | } 2241 | 2242 | local_client = fetch_couchdb_object(getThis() TSRMLS_CC); 2243 | 2244 | url = Z_STRVAL_PP(couchdb_get_property(local_client, COUCHDB_URL TSRMLS_CC)); 2245 | 2246 | smart_str_appends(&surl, url); 2247 | smart_str_appends(&surl, COUCHDB_CONFIG); 2248 | smart_str_appends(&surl, "/admins/"); 2249 | 2250 | euser_name = couchdb_encode_url(user_name); 2251 | epassword = couchdb_encode_url(password); 2252 | 2253 | smart_str_appends(&surl, euser_name); 2254 | smart_str_0(&surl); 2255 | 2256 | efree(euser_name); 2257 | 2258 | MAKE_STD_ZVAL(put_payload); 2259 | tlen = spprintf(&buff, 0, "\"%s\"", epassword); 2260 | ZVAL_STRINGL(put_payload, buff, tlen, 1); 2261 | 2262 | efree(buff); 2263 | efree(epassword); 2264 | 2265 | http_response_code = couchdb_prepare_request(local_client, surl.c, COUCHDB_PUT, put_payload, NULL, 0 TSRMLS_CC); 2266 | 2267 | zval_ptr_dtor(&put_payload); 2268 | smart_str_free(&surl); 2269 | 2270 | PROCESS_BOOL_RESULT(http_response_code, local_client, COUCHDB_STATUS_OK); 2271 | 2272 | } 2273 | /* }}} */ 2274 | 2275 | /* {{{ arginfo */ 2276 | 2277 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_noparams, 0, 0, 0) 2278 | ZEND_END_ARG_INFO() 2279 | 2280 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_client__construct, 0,0,1) 2281 | ZEND_ARG_INFO(0, uri) 2282 | ZEND_ARG_INFO(0, use_cookie_auth) 2283 | ZEND_ARG_INFO(0, db_name) 2284 | ZEND_END_ARG_INFO() 2285 | 2286 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getdbinfo, 0, 0, 0) 2287 | ZEND_ARG_INFO(0, db_name) 2288 | ZEND_END_ARG_INFO() 2289 | 2290 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getdoc, 0, 0, 1) 2291 | ZEND_ARG_INFO(0, doc_id) 2292 | ZEND_ARG_ARRAY_INFO(0, options, 1) 2293 | ZEND_END_ARG_INFO() 2294 | 2295 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getalldocs, 0, 0, 0) 2296 | ZEND_ARG_INFO(0, by_sequence) 2297 | ZEND_ARG_ARRAY_INFO(0, query_options, 1) 2298 | ZEND_END_ARG_INFO() 2299 | 2300 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_copydoc, 0, 0, 2) 2301 | ZEND_ARG_INFO(0, doc_id) 2302 | ZEND_ARG_INFO(0, new_doc_id) 2303 | ZEND_ARG_INFO(0, new_doc_revision) 2304 | ZEND_END_ARG_INFO() 2305 | 2306 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_attach, 0, 0, 4) 2307 | ZEND_ARG_INFO(0, doc_id) 2308 | ZEND_ARG_INFO(0, filename) 2309 | ZEND_ARG_INFO(0, attachment_name) 2310 | ZEND_ARG_INFO(0, content_type) 2311 | ZEND_ARG_INFO(0, doc_rev) 2312 | ZEND_END_ARG_INFO() 2313 | 2314 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_delattach, 0, 0, 2) 2315 | ZEND_ARG_INFO(0, doc_id) 2316 | ZEND_ARG_INFO(0, attachment_name) 2317 | ZEND_ARG_INFO(0, doc_rev) 2318 | ZEND_END_ARG_INFO() 2319 | 2320 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_setca, 0, 0, 2) 2321 | ZEND_ARG_INFO(0, ca_path) 2322 | ZEND_ARG_INFO(0, ca_info) 2323 | ZEND_END_ARG_INFO() 2324 | 2325 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getuuids, 0, 0, 0) 2326 | ZEND_ARG_INFO(0, count) 2327 | ZEND_END_ARG_INFO() 2328 | 2329 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_startrepli, 0, 0, 2) 2330 | ZEND_ARG_INFO(0, source) 2331 | ZEND_ARG_INFO(0, destination) 2332 | ZEND_ARG_INFO(0, set_continuous) 2333 | ZEND_END_ARG_INFO() 2334 | 2335 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_savedocs, 0, 0, 1) 2336 | ZEND_ARG_INFO(0, documents) 2337 | ZEND_END_ARG_INFO() 2338 | 2339 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getview, 0, 0, 2) 2340 | ZEND_ARG_INFO(0, design_doc) 2341 | ZEND_ARG_INFO(0, view_name) 2342 | ZEND_END_ARG_INFO() 2343 | 2344 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_gettempview, 0, 0, 1) 2345 | ZEND_ARG_INFO(0, temp_view) 2346 | ZEND_END_ARG_INFO() 2347 | 2348 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_storedoc, 0, 0, 1) 2349 | ZEND_ARG_INFO(0, document) 2350 | ZEND_END_ARG_INFO() 2351 | 2352 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_deletedoc, 0, 0, 2) 2353 | ZEND_ARG_INFO(0, doc_id) 2354 | ZEND_ARG_INFO(0, rev) 2355 | ZEND_END_ARG_INFO() 2356 | 2357 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getresponse, 0, 0, 0) 2358 | ZEND_ARG_INFO(0, json_decode) 2359 | ZEND_END_ARG_INFO() 2360 | 2361 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_getdbchanges, 0, 0, 0) 2362 | ZEND_ARG_ARRAY_INFO(0, query_options, 1) 2363 | ZEND_END_ARG_INFO() 2364 | 2365 | ZEND_BEGIN_ARG_INFO_EX(arginfo_couchdb_createadminuser, 0, 0, 2) 2366 | ZEND_ARG_INFO(0, user_name) 2367 | ZEND_ARG_INFO(0, password) 2368 | ZEND_END_ARG_INFO() 2369 | 2370 | /* }}} */ 2371 | 2372 | static zend_function_entry couchdb_client_methods[] = { /* {{{ */ 2373 | TC_ME(__construct, arginfo_couchdb_client__construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL|ZEND_ACC_CTOR) 2374 | TC_ME(getServerInfo, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2375 | TC_ME(getServerConfig, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2376 | TC_ME(getServerStats, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2377 | TC_ME(listDatabases, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2378 | TC_ME(listActiveTasks, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2379 | TC_ME(getUuids, arginfo_couchdb_getuuids, ZEND_ACC_PUBLIC) 2380 | TC_ME(startReplication, arginfo_couchdb_startrepli, ZEND_ACC_PUBLIC) 2381 | TC_ME(createAdminUser, arginfo_couchdb_createadminuser, ZEND_ACC_PUBLIC) 2382 | TC_ME(compactDatabase, arginfo_couchdb_getdbinfo, ZEND_ACC_PUBLIC) 2383 | TC_ME(createDatabase, arginfo_couchdb_getdbinfo, ZEND_ACC_PUBLIC) 2384 | TC_ME(deleteDatabase, arginfo_couchdb_getdbinfo, ZEND_ACC_PUBLIC) 2385 | TC_MALIAS(dropDatabase, deleteDatabase, arginfo_couchdb_getdbinfo, ZEND_ACC_PUBLIC) 2386 | TC_ME(getDatabaseInfo, arginfo_couchdb_getdbinfo, ZEND_ACC_PUBLIC) 2387 | TC_ME(getDatabaseChanges, arginfo_couchdb_getdbchanges, ZEND_ACC_PUBLIC) 2388 | TC_ME(getAllDocs, arginfo_couchdb_getalldocs, ZEND_ACC_PUBLIC) 2389 | TC_ME(getDoc, arginfo_couchdb_getdoc, ZEND_ACC_PUBLIC) 2390 | TC_ME(storeDoc, arginfo_couchdb_storedoc, ZEND_ACC_PUBLIC) 2391 | TC_ME(deleteDoc, arginfo_couchdb_deletedoc, ZEND_ACC_PUBLIC) 2392 | TC_ME(storeDocs, arginfo_couchdb_savedocs, ZEND_ACC_PUBLIC) 2393 | TC_ME(getTempView, arginfo_couchdb_gettempview, ZEND_ACC_PUBLIC) 2394 | TC_ME(getView, arginfo_couchdb_getview, ZEND_ACC_PUBLIC) 2395 | TC_ME(copyDoc, arginfo_couchdb_copydoc, ZEND_ACC_PUBLIC) 2396 | TC_ME(storeAttachment, arginfo_couchdb_attach, ZEND_ACC_PUBLIC) 2397 | TC_ME(deleteAttachment, arginfo_couchdb_delattach, ZEND_ACC_PUBLIC) 2398 | TC_ME(getLastResponse, arginfo_couchdb_getresponse, ZEND_ACC_PUBLIC) 2399 | TC_ME(setCAPath, arginfo_couchdb_setca, ZEND_ACC_PUBLIC) 2400 | TC_ME(getCAPath, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2401 | TC_ME(selectDB, arginfo_couchdb_getdbinfo, ZEND_ACC_PUBLIC) 2402 | TC_ME(__destruct, arginfo_couchdb_noparams, ZEND_ACC_PUBLIC) 2403 | {NULL, NULL, NULL} 2404 | }; 2405 | /* }}} */ 2406 | 2407 | zend_function_entry couchdb_functions[] = { /* {{{ */ 2408 | {NULL, NULL, NULL} 2409 | }; 2410 | /* }}} */ 2411 | 2412 | /* {{{ PHP_MINIT_FUNCTION */ 2413 | 2414 | PHP_MINIT_FUNCTION(couchdb) 2415 | { 2416 | zend_class_entry client_ce; 2417 | 2418 | if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { 2419 | return FAILURE; 2420 | } 2421 | 2422 | 2423 | INIT_CLASS_ENTRY(client_ce, COUCHDB_CLASS, couchdb_client_methods); 2424 | client_ce.create_object = couchdb_client_new; 2425 | 2426 | 2427 | couchdb_client_ce_ptr = zend_register_internal_class(&client_ce TSRMLS_CC); 2428 | memcpy(&couchdb_client_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); 2429 | 2430 | couchdb_client_handlers.read_property = couchdb_read_member; 2431 | couchdb_client_handlers.write_property = couchdb_write_member; 2432 | 2433 | INIT_CLASS_ENTRY(client_ce, COUCHDB_EXCEPTION_CLASS, NULL); 2434 | couchdb_exception_ce_ptr = zend_register_internal_class_ex(&client_ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); 2435 | 2436 | return SUCCESS; 2437 | } /* }}} */ 2438 | 2439 | /* {{{ PHP_MSHUTDOWN_FUNCTION */ 2440 | 2441 | PHP_MSHUTDOWN_FUNCTION(couchdb) 2442 | { 2443 | couchdb_client_ce_ptr = NULL; 2444 | curl_global_cleanup(); 2445 | 2446 | return SUCCESS; 2447 | } 2448 | /* }}} */ 2449 | 2450 | /* {{{ PHP_MINFO_FUNCTION */ 2451 | 2452 | PHP_MINFO_FUNCTION(couchdb) 2453 | { 2454 | php_info_print_table_start(); 2455 | php_info_print_table_header(2, PHP_COUCHDB_NAME, "enabled"); 2456 | php_info_print_table_header(2, "Version", PHP_COUCHDB_VERSION); 2457 | php_info_print_table_end(); 2458 | } 2459 | /* }}} */ 2460 | 2461 | /* {{{ couchdb_module_entry */ 2462 | 2463 | zend_module_entry couchdb_module_entry = { 2464 | STANDARD_MODULE_HEADER, 2465 | PHP_COUCHDB_NAME, 2466 | couchdb_functions, 2467 | PHP_MINIT(couchdb), 2468 | PHP_MSHUTDOWN(couchdb), 2469 | NULL, 2470 | NULL, 2471 | PHP_MINFO(couchdb), 2472 | PHP_COUCHDB_VERSION, 2473 | STANDARD_MODULE_PROPERTIES 2474 | }; 2475 | /* }}} */ 2476 | 2477 | #if COMPILE_DL_COUCHDB 2478 | ZEND_GET_MODULE(couchdb) 2479 | #endif 2480 | 2481 | /* 2482 | * Local variables: 2483 | * tab-width: 4 2484 | * c-basic-offset: 4 2485 | * End: 2486 | * vim600: noet sw=4 ts=4 fdm=marker 2487 | * vim<600: noet sw=4 ts=4 2488 | */ 2489 | -------------------------------------------------------------------------------- /examples/example.php: -------------------------------------------------------------------------------- 1 | | 13 | +----------------------------------------------------------------------+ 14 | */ 15 | 16 | /* $ Id: */ 17 | /* 18 | Examples on how to use the PHP CouchDB extension 19 | */ 20 | 21 | /* Create the CouchdbClient object 22 | The url can support authentication as well 23 | - http://user:password@localhost:5984 24 | 25 | - Authentication is both by basic and cookie 26 | To use cookie authentication you need to set use_cookie_auth to true 27 | CouchdbClient("http://user:pass@localhost:5984",true); 28 | 29 | 30 | The url could be https 31 | - https://localhost:5984 32 | You may have to set the CA info using CouchdbClient::setCAPath() 33 | 34 | */ 35 | try { 36 | $conn = new CouchdbClient("http://localhost:5984"); 37 | 38 | print "Creating Database test_database :"; 39 | if($conn->createDatabase("test_database")) 40 | print "PASS\n"; 41 | else 42 | print "FAIL\n"; 43 | 44 | echo "Getting Database list\n"; 45 | $result = $conn->listDatabases(); 46 | print_r($result); 47 | print "===========================\n"; 48 | 49 | 50 | print "Selecting Database test_database\n"; 51 | $conn->selectDB("test_database"); 52 | print "===========================\n"; 53 | 54 | 55 | print "Getting Database info\n"; 56 | $result = $conn->getDatabaseInfo(); 57 | print_r($result); 58 | print "===========================\n"; 59 | 60 | 61 | print "Store document to DB\n"; 62 | /* The document can be created in multiple ways 63 | - PHP stdclass object 64 | - PHP array 65 | - JSON encoded string 66 | 67 | # Using PHP stdclass 68 | $new_doc = new stdClass(); 69 | $new_doc->title = "New content"; 70 | $new_doc->_id = "BlogPost65"; 71 | 72 | # Using PHP array 73 | #$new_doc = array(_id=>Blogpost65,title=>"New content"); 74 | 75 | # Using JSON string 76 | $new_doc = '{"_id":"Blogpost65","title":"New content"}'; 77 | */ 78 | $new_doc = '{"_id":"Blogpost65","title":"New content"}'; 79 | $last_result = $conn->storeDoc($new_doc); 80 | print_r($last_result); 81 | print "===========================\n"; 82 | 83 | 84 | print "Store multiple documents to the DB\n"; 85 | $new_docs = array(array('type'=>'blogpost','title'=>'post'),array('type'=>'blogcomment','blogpost'=>'post','depth'=>1) 86 | ,array('type'=>'blogcomment','blogpost'=>'post','depth'=>2)); 87 | $result = $conn->storeDocs($new_docs); 88 | print_r($result); 89 | print "===========================\n"; 90 | 91 | 92 | /* run in the examples directory or change the filename */ 93 | print "Store attachment to DB\n"; 94 | $result = $conn->storeAttachment("PHP_LOGO","./php.gif","php.gif","image/gif"); 95 | print_r($result); 96 | print "===========================\n"; 97 | 98 | 99 | print "Copy document to another document\n"; 100 | $result = $conn->copyDoc("Blogpost65","Blogpost66"); 101 | print_r($result); 102 | print "===========================\n"; 103 | 104 | 105 | print "Get all documents in DB\n"; 106 | $result = $conn->getAllDocs(); 107 | print_r($result); 108 | print "===========================\n"; 109 | 110 | 111 | print "Run a temp view query\n"; 112 | $view = '{"map" : "function(doc) { if (doc.title==\'New content\') { emit(null, doc); } }"}'; 113 | $result = $conn->getTempView($view); 114 | print_r($result); 115 | print "===========================\n"; 116 | 117 | 118 | print "Delete a document\n"; 119 | $conn->deleteDoc("Blogpost65",$last_result->rev); 120 | $result = $conn->getLastResponse(true); 121 | print_r($result); 122 | print "===========================\n"; 123 | 124 | 125 | print "Compacting Database :"; 126 | if($conn->compactDatabase()) 127 | print "PASS\n"; 128 | else 129 | print "FAIL\n"; 130 | 131 | print "===========================\n"; 132 | 133 | 134 | print "Getting updated Database info\n"; 135 | $result = $conn->getDatabaseInfo(); 136 | print_r($result); 137 | print "===========================\n"; 138 | 139 | 140 | print "Create the replica database - test_replica_database :"; 141 | if($conn->createDatabase("test_replica_database")) 142 | print "PASS\n"; 143 | else 144 | print "FAIL\n"; 145 | 146 | 147 | print "Start Database replication\n"; 148 | $result = $conn->startReplication("test_database","test_replica_database"); 149 | print_r($conn->getLastResponse(true)); 150 | print "===========================\n"; 151 | 152 | 153 | #print "Sleeping 5 seconds to allow replication to start\n"; 154 | #sleep(5); 155 | #print "===========================\n"; 156 | 157 | 158 | print "Drop the database :"; 159 | if($conn->deleteDatabase("test_database")) 160 | print "PASS\n"; 161 | else 162 | print "FAIL\n"; 163 | 164 | print "===========================\n"; 165 | 166 | 167 | print "Drop the replica database :"; 168 | if($conn->deleteDatabase("test_replica_database")) 169 | print "PASS\n"; 170 | else 171 | print "FAIL\n"; 172 | 173 | print_r($conn->getLastResponse(true)); 174 | print "===========================\n"; 175 | } catch(CouchdbClientException $e) { 176 | echo $e->getMessage(); 177 | } 178 | unset($conn); 179 | ?> 180 | -------------------------------------------------------------------------------- /examples/php.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/akissa/php-couchdb/1dee18101e23f48d61c372990fc122daf1dbfb1a/examples/php.gif -------------------------------------------------------------------------------- /package2.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | couchdb 11 | pecl.php.net 12 | PHP extension to access CouchDB servers 13 | 14 | The CouchDB extension allows PHP developers to easily 15 | manipulate CouchDB documents stored on CouchDB servers 16 | using an object-oriented API. The extension implements 17 | most of the CouchDB API with the ultimate goal being 18 | full support. The server JSON responses are automatically 19 | decoded into native PHP objects or arrays. 20 | 21 | 22 | Andrew Colin Kissa 23 | topdog 24 | topdog@fedoraproject.org 25 | yes 26 | 27 | 2009-10-23 28 | 29 | 0.0.2 30 | 0.0.2 31 | 32 | 33 | alpha 34 | alpha 35 | 36 | PHP 37 | 38 | - Rewrite to follow PHP Coding standards 39 | - Added Support for builtin encoding and decoding 40 | - Added Support for built in attachment handling 41 | - Support the full CouchDB API 42 | - Add support for authentication 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 5.2.10 65 | 66 | 67 | 1.4.0a1 68 | 69 | 70 | 71 | couchdb 72 | 73 | 74 | 75 | 2009-10-08 76 | 77 | 0.0.1 78 | 0.0.1 79 | 80 | 81 | alpha 82 | alpha 83 | 84 | 85 | - First alpha version 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /php_couchdb.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2009 | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Andrew Colin Kissa | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_COUCHDB_H 22 | #define PHP_COUCHDB_H 23 | 24 | 25 | extern zend_module_entry couchdb_module_entry; 26 | #define phpext_couchdb_ptr &couchdb_module_entry 27 | 28 | #define PHP_COUCHDB_NAME "couchdb" 29 | #define PHP_COUCHDB_VERSION "0.0.2" 30 | #define COUCHDB_CLASS "CouchdbClient" 31 | #define COUCHDB_EXCEPTION_CLASS "CouchdbClientException" 32 | 33 | #define TC_ME(func, arg_info, flags) PHP_ME(CouchdbClient, func, arg_info, flags) 34 | #define TC_MALIAS(func, alias, arg_info, flags) PHP_MALIAS(CouchdbClient, func, alias, arg_info, flags) 35 | #define TC_METHOD(func) PHP_METHOD(CouchdbClient, func) 36 | 37 | #define COUCHDB_LAST_RAW_RES "couchdb_last_raw_res" 38 | #define COUCHDB_URL "couchdb_url" 39 | #define COUCHDB_DB "couchdb_db" 40 | #define COUCHDB_USER "couchdb_user" 41 | #define COUCHDB_PASSWORD "couchdb_password" 42 | #define COUCHDB_POST "POST" 43 | #define COUCHDB_GET "GET" 44 | #define COUCHDB_PUT "PUT" 45 | #define COUCHDB_DELETE "DELETE" 46 | #define COUCHDB_COPY "COPY" 47 | #define COUCHDB_CHANGES "/_changes" 48 | #define COUCHDB_CONFIG "/_config" 49 | #define COUCHDB_STATS "/_stats" 50 | #define COUCHDB_SESSION "/_session" 51 | #define COUCHDB_ACTIVE_TASK "/_active_tasks" 52 | #define COUCHDB_ALL_DOCS "/_all_docs" 53 | #define COUCHDB_ALL_DOCS_SEQ "/_all_docs_by_seq" 54 | #define COUCHDB_ALL_DBS "/_all_dbs" 55 | #define COUCHDB_BULK_DOCS "/_bulk_docs" 56 | #define COUCHDB_TEMP_VIEW "/_temp_view" 57 | #define COUCHDB_GET_UUIDS "/_uuids" 58 | #define COUCHDB_COMPACT "/_compact" 59 | #define COUCHDB_REPLICATE "/_replicate" 60 | #define COUCHDB_CA_PATH "couchdb_ca_path" 61 | #define COUCHDB_CA_INFO "couchdb_ca_info" 62 | #define COUCHDB_ACCEPT_HEADERS "Accept: application/json,text/html,text/plain,*/*" 63 | #define COUCHDB_STATUS_OK 200 64 | #define COUCHDB_STATUS_CREATED 201 65 | #define COUCHDB_STATUS_ACCEPTED 202 66 | #define COUCHDB_STATUS_NOTMOD 304 67 | #define COUCHDB_STATUS_NOTFOUND 404 68 | #define COUCHDB_STATUS_CONFLICT 409 69 | #define COUCHDB_STATUS_IERROR 500 70 | #define COUCHDB_STATUS_END 206 71 | #define COUCHDB_MAX_HEADER_LEN 512L 72 | 73 | #define COUCHDB_DB_NONE 0 74 | #define COUCHDB_DB_INFO 1 75 | #define COUCHDB_DB_COMPACT 2 76 | #define COUCHDB_DB_DELETE 3 77 | 78 | #define COUCHDB_EMPTY_PARAMS "Method parameters can not be empty strings" 79 | #define COUCHDB_COOKIE_PARAMS "user_name and password must be supplied for cookie based authentication" 80 | #define COUCHDB_COOKIE_AUTH_FAILURE "Cookie authentication failed" 81 | #define COUCHDB_DOC_PARAM_TYPE "Expects parameter 1 to be a JSON encoded string, array or stdClass object" 82 | #define COUCHDB_INVALID_JSON_STRING "The string paramter supplied is not valid JSON" 83 | #define COUCHDB_JSON_ENCODE_FAIL "JSON encoding failed" 84 | #define COUCHDB_JSON_ENCODE_NULL "JSON encoding returned a null value" 85 | #define COUCHDB_JSON_INVALID "The JSON is invalid" 86 | #define COUCHDB_FILE_OPEN_FAIL "The file %s could not be opened" 87 | #define COUCHDB_FILE_EMPTY "The file %s is empty" 88 | #define COUCHDB_FILE_READ_FAIL "The file %s could not be read" 89 | #define COUCHDB_DB_DESELECT_FAIL "Unselecting of the database failed" 90 | #define COUCHDB_INVALID_URI "The uri parameter is invalid" 91 | #define COUCHDB_INVALID_SCHEME "The url scheme %s you supplied is not supported" 92 | #define COUCHDB_COOKIE_NOT_GOT "Server did not send any cookie" 93 | #define COUCHDB_SERVER_FAIL "HTTP request failed with Error message: %s" 94 | #define COUCHDB_DB_NOT_SET "The database name has not been set, use selectDB() to set the database name" 95 | 96 | #endif /* PHP_COUCHDB_H */ 97 | 98 | /* 99 | * Local variables: 100 | * tab-width: 4 101 | * c-basic-offset: 4 102 | * End: 103 | * vim600: noet sw=4 ts=4 fdm=marker 104 | * vim<600: noet sw=4 ts=4 105 | */ 106 | --------------------------------------------------------------------------------