Fix CQL stuff does not compile against older YAZ PHPYAZ-27
[phpyaz-moved-to-github.git] / php_yaz.c
index 0964cbd..b8ebf59 100644 (file)
--- a/php_yaz.c
+++ b/php_yaz.c
@@ -1,19 +1,6 @@
-/*
-   +----------------------------------------------------------------------+
-   | PHP Version 5                                                        |
-   +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2011 The PHP Group                                |
-   +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,       |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.php.net/license/3_01.txt.                                  |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
-   +----------------------------------------------------------------------+
-   | Author: Adam Dickmeiss <adam@indexdata.dk>                           |
-   +----------------------------------------------------------------------+
+/* This file is part of PHP YAZ.
+ * Copyright (C) Index Data 2004-1014
+ * See the file LICENSE for details.
  */
 
 #ifdef HAVE_CONFIG_H
 #if HAVE_YAZ
 
 #include "ext/standard/info.h"
-#include "php_yaz.h"
 
 #include <yaz/yaz-version.h>
 
+#include "php_yaz.h"
+
 #ifndef YAZ_VERSIONL
-#error YAZ version 3.0 or later must be used.
-#elif YAZ_VERSIONL < 0x030000
-#error YAZ version 3.0 or later must be used.
+#error YAZ version 3.0.2 or later must be used.
+#elif YAZ_VERSIONL < 0x030020
+#error YAZ version 3.0.2 or later must be used.
 #endif
 
 #ifdef PHP_WIN32
 #include <yaz/marcdisp.h>
 #include <yaz/yaz-util.h>
 #include <yaz/yaz-ccl.h>
+#include <yaz/cql.h>
 #include <yaz/oid_db.h>
 #include <yaz/zoom.h>
+#include <yaz/pquery.h>
+
+#if YAZ_VERSIONL >= 0x050100
+#include <yaz/rpn2cql.h>
+#endif
 
 #ifndef ODR_INT_PRINTF
 #define ODR_INT_PRINTF "%d"
@@ -58,6 +52,9 @@ typedef struct Yaz_AssociationInfo *Yaz_Association;
 
 struct Yaz_AssociationInfo {
        CCL_bibset bibset;
+#if YAZ_VERSIONL >= 0x050100
+       cql_transform_t ct;
+#endif
        ZOOM_connection zoom_conn;
        ZOOM_resultset zoom_set;
        ZOOM_scanset zoom_scan;
@@ -85,6 +82,9 @@ static Yaz_Association yaz_association_mk()
        p->order = 0;
        p->persistent = 0;
        p->bibset = ccl_qual_mk();
+#if YAZ_VERSIONL >= 0x050100
+       p->ct = cql_transform_create();
+#endif
        p->time_stamp = 0;
        return p;
 }
@@ -95,6 +95,9 @@ static void yaz_association_destroy(Yaz_Association p)
                return;
        }
 
+#if YAZ_VERSIONL >= 0x050100
+       cql_transform_close(p->ct);
+#endif
        ZOOM_resultset_destroy(p->zoom_set);
        ZOOM_scanset_destroy(p->zoom_scan);
        ZOOM_package_destroy(p->zoom_package);
@@ -163,6 +166,10 @@ zend_function_entry yaz_functions [] = {
        PHP_FE(yaz_present, NULL)
        PHP_FE(yaz_ccl_conf, NULL)
        PHP_FE(yaz_ccl_parse, third_argument_force_ref)
+#if YAZ_VERSIONL >= 0x050100
+       PHP_FE(yaz_cql_parse, third_argument_force_ref)
+       PHP_FE(yaz_cql_conf, NULL)
+#endif
        PHP_FE(yaz_database, NULL)
        PHP_FE(yaz_sort, NULL)
        PHP_FE(yaz_schema, NULL)
@@ -305,7 +312,7 @@ PHP_FUNCTION(yaz_connect)
        const char *preferredMessageSize = 0;
        int persistent = 1;
        int piggyback = 1;
-       Yaz_Association as;
+       Yaz_Association as = 0;
        int max_links = YAZSG(max_links);
 
        otherInfo[0] = otherInfo[1] = otherInfo[2] = 0;
@@ -808,7 +815,6 @@ static Z_GenericRecord *marc_to_grs1(const char *buf, ODR o)
        int base_address;
        int length_data_entry;
        int length_starting;
-       int length_implementation;
        int max_elements = 256;
        Z_GenericRecord *r = odr_malloc(o, sizeof(*r));
        r->elements = odr_malloc(o, sizeof(*r->elements) * max_elements);
@@ -824,7 +830,6 @@ static Z_GenericRecord *marc_to_grs1(const char *buf, ODR o)
 
        length_data_entry = atoi_n(buf + 20, 1);
        length_starting = atoi_n(buf + 21, 1);
-       length_implementation = atoi_n(buf + 22, 1);
 
        for (entry_p = 24; buf[entry_p] != ISO2709_FS; ) {
                entry_p += 3 + length_data_entry + length_starting;
@@ -1522,7 +1527,7 @@ PHP_FUNCTION(yaz_get_option)
        }
        get_assoc(INTERNAL_FUNCTION_PARAM_PASSTHRU, pval_id, &p);
        if (p) {
-               const char *name_str, *v;
+               const char *v;
                v = option_get(p, name);
                if (!v) {
                        v = "";
@@ -1933,6 +1938,137 @@ PHP_FUNCTION(yaz_ccl_parse)
 }
 /* }}} */
 
+
+#if YAZ_VERSIONL >= 0x050100
+
+/* {{{ proto bool yaz_cql_parse(resource id, string cql, array res, bool rev)
+   Parse a CQL query */
+PHP_FUNCTION(yaz_cql_parse)
+{
+       zval *pval_id, *pval_res = 0;
+       char *query;
+       int query_len;
+       Yaz_Association p;
+       zend_bool reverse = 0;
+
+       if (ZEND_NUM_ARGS() != 4 ||
+               zend_parse_parameters(4 TSRMLS_CC, "zszb",
+                                                         &pval_id, &query, &query_len, &pval_res, &reverse)
+               == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       zval_dtor(pval_res);
+       array_init(pval_res);
+       get_assoc(INTERNAL_FUNCTION_PARAM_PASSTHRU, pval_id, &p);
+       if (p) {
+               if (reverse) {
+            ODR odr = odr_createmem(ODR_ENCODE);
+            YAZ_PQF_Parser pp = yaz_pqf_create();
+            Z_RPNQuery *rpn = yaz_pqf_parse(pp, odr, query);
+                       WRBUF wrbuf_cql = wrbuf_alloc();
+                       int r;
+                       if (!rpn) {
+                               add_assoc_long(pval_res, "errorcode", 0);
+                               add_assoc_string(pval_res, "addinfo",
+                                                                (char *) "PQF syntax error", 1);
+                               RETVAL_FALSE;
+                       } else if ((r = cql_transform_rpn2cql_stream(p->ct, wrbuf_vp_puts,
+                                                                                                                wrbuf_cql, rpn))) {
+                               add_assoc_long(pval_res, "errorcode", r);
+                               RETVAL_FALSE;
+                       } else {
+                               add_assoc_string(pval_res, "cql",
+                                                                (char *) wrbuf_cstr(wrbuf_cql), 1);
+                               RETVAL_TRUE;
+                       }
+                       wrbuf_destroy(wrbuf_cql);
+                       yaz_pqf_destroy(pp);
+            odr_destroy(odr);
+               } else {
+                       CQL_parser cp = cql_parser_create();
+                       int r = cql_parser_string(cp, query);
+                       if (r) {
+                               add_assoc_long(pval_res, "errorcode", 0);
+                               add_assoc_string(pval_res, "addinfo",
+                                                                (char *) "syntax error", 1);
+                               RETVAL_FALSE;
+                       } else {
+                               WRBUF wrbuf_addinfo = wrbuf_alloc();
+                               WRBUF wrbuf_pqf = wrbuf_alloc();
+                               r = cql_transform_r(p->ct, cql_parser_result(cp), wrbuf_addinfo,
+                                                                       wrbuf_vp_puts, wrbuf_pqf);
+                               if (r) {
+                                       add_assoc_long(pval_res, "errorcode", r);
+                                       if (wrbuf_len(wrbuf_addinfo))
+                                               add_assoc_string(pval_res, "addinfo",
+                                                                                (char *) wrbuf_cstr(wrbuf_addinfo), 1);
+                                       RETVAL_FALSE;
+                               } else {
+                                       wrbuf_chop_right(wrbuf_pqf);
+                                       add_assoc_string(pval_res, "rpn",
+                                                                        (char *) wrbuf_cstr(wrbuf_pqf), 1);
+                                       RETVAL_TRUE;
+                               }
+                               wrbuf_destroy(wrbuf_pqf);
+                               wrbuf_destroy(wrbuf_addinfo);
+                       }
+                       cql_parser_destroy(cp);
+               }
+       } else {
+               RETVAL_FALSE;
+       }
+       release_assoc(p);
+}
+/* }}} */
+
+#endif
+
+#if YAZ_VERSIONL >= 0x050100
+/* {{{ proto void yaz_cql_conf(resource id, array package)
+   Configure CQL package */
+PHP_FUNCTION(yaz_cql_conf)
+{
+       zval *pval_id, *pval_package;
+       Yaz_Association p;
+
+       if (ZEND_NUM_ARGS() != 2 ||
+               zend_parse_parameters(2 TSRMLS_CC, "za", &pval_id, &pval_package)
+               == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       get_assoc(INTERNAL_FUNCTION_PARAM_PASSTHRU, pval_id, &p);
+       if (p) {
+               HashTable *ht = Z_ARRVAL_PP(&pval_package);
+               HashPosition pos;
+               zval **ent;
+               char *key;
+
+               cql_transform_close(p->ct);
+               p->ct = cql_transform_create();
+
+               for (zend_hash_internal_pointer_reset_ex(ht, &pos);
+                       zend_hash_get_current_data_ex(ht, (void**) &ent, &pos) == SUCCESS;
+                       zend_hash_move_forward_ex(ht, &pos)
+               ) {
+                       ulong idx;
+#if PHP_API_VERSION > 20010101
+                       int type = zend_hash_get_current_key_ex(ht, &key, 0, &idx, 0, &pos);
+#else
+                       int type = zend_hash_get_current_key_ex(ht, &key, 0, &idx, &pos);
+#endif
+                       if (type != HASH_KEY_IS_STRING || Z_TYPE_PP(ent) != IS_STRING) {
+                               continue;
+                       }
+
+                       cql_transform_define_pattern(p->ct, key, (*ent)->value.str.val);
+               }
+       }
+       release_assoc(p);
+}
+/* }}} */
+#endif
+
 /* {{{ proto bool yaz_database (resource id, string databases)
    Specify the databases within a session */
 PHP_FUNCTION(yaz_database)