Ticket #15: tinyows_ticket15.patch

File tinyows_ticket15.patch, 17.0 kB (added by nsavard, 3 years ago)

patch to fix insert transaction response

  • Makefile.in

     
    11# compiler flags  
    22CC=@CC@ 
    33CFLAGS=@CFLAGS@ -ansi -pedantic -Wall 
    4 PGFLAGS=-lpq -I`pg_config --includedir` -L`pg_config --libdir` 
    5 XMLFLAGS=-lxml2 `xml2-config --cflags`  
    64 
     5# postgresql ... required 
     6POSTGIS_INC=@POSTGIS_INC@ 
     7POSTGIS_LIB=@POSTGIS_LIB@ 
     8PGFLAGS=$(POSTGIS_INC) $(POSTGIS_LIB) 
     9# libxml2 ... required 
     10XML2_INC=@XML2_INC@ 
     11XML2_LIB=@XML2_LIB@ 
     12XMLFLAGS=$(XML2_INC) $(XML2_LIB) 
    713# install path 
    814PREFIX=@prefix@ 
    915 
  • configure.in

     
    11AC_INIT() 
    22 
    3 AC_CHECK_PROG(HAVE_LIBXML, xml2-config, yes, no) 
    4 if test [ $HAVE_LIBXML = no ]; then  
    5         AC_MSG_ERROR(libxml2 must be installed) 
     3dnl --------------------------------------------------------------------- 
     4dnl Look for libxml2 
     5dnl --------------------------------------------------------------------- 
     6 
     7AC_MSG_CHECKING(for libxml2) 
     8 
     9AC_ARG_WITH(xml2-config, 
     10[  --with-xml2-config=PATH Specify path to xml2-config.],,) 
     11 
     12if test "$with_xml2_config" != "no" ; then 
     13 
     14  if test "`basename xx/$with_xml2_config`" = "xml2-config" ; then 
     15    LIBXML2_CONFIG="$with_xml2_config" 
     16    if test -f "$LIBXML2_CONFIG" -a -x "$LIBXML2_CONFIG" ; then 
     17      AC_MSG_RESULT([yes, user supplied xml2-config ($LIBXML2_CONFIG)]) 
     18    else 
     19      AC_MSG_ERROR(['$LIBXML2_CONFIG' is not an executable.  Make sure you use --with-xml2-config=/path/to/xml2-config]) 
     20    fi 
     21  else 
     22    AC_PATH_PROG(LIBXML2_CONFIG, xml2-config, no) 
     23  fi 
     24 
     25  if test "$LIBXML2_CONFIG" = "no" ; then 
     26   AC_MSG_ERROR([couldn't find xml2-config, try using --with-xml2-config=PATH]) 
     27  fi 
     28 
     29  XML2_VER=`$LIBXML2_CONFIG --version` 
     30 
     31  AC_MSG_RESULT([        found libxml2 version $XML2_VER]) 
     32 
     33  XML2_INC=`$LIBXML2_CONFIG --cflags` 
     34  XML2_LIB=`$LIBXML2_CONFIG --libs` 
     35 
    636fi 
    737 
    8 AC_CHECK_PROG(HAVE_PGSQL, pg_config, yes, no) 
    9 if test [ $HAVE_PGSQL = no ]; then  
    10         AC_MSG_ERROR(postgresql must be installed) 
     38AC_SUBST(XML2_INC,    $XML2_INC) 
     39AC_SUBST(XML2_LIB,    $XML2_LIB) 
     40 
     41dnl --------------------------------------------------------------------------- 
     42dnl Try to find PostgreSQL if PostGIS support requested. 
     43dnl --------------------------------------------------------------------------- 
     44 
     45AC_MSG_CHECKING(if PostGIS support requested) 
     46 
     47AC_ARG_WITH(postgis,[  --with-postgis[[=ARG]]    Include PostGIS Support (ARG=yes/path to pg_config)],,) 
     48 
     49if test "$with_postgis" = "no" -o "$with_postgis" = "" ; then 
     50  PG_CONFIG="no" 
     51elif test "$with_postgis" = "yes" ; then 
     52  AC_PATH_PROG(PG_CONFIG, pg_config, no) 
     53else 
     54  AC_MSG_RESULT(yes) 
     55  PG_CONFIG=$with_postgis 
    1156fi 
    1257 
     58if test "$PG_CONFIG" = "no" ; then 
     59  POSTGIS_ENABLED= 
     60  POSTGIS_INC= 
     61  POSTGIS_LIB= 
     62else 
     63  if test -f "$PG_CONFIG" -a -x "$PG_CONFIG" ; then 
     64    AC_MSG_RESULT([yes, user supplied pg_config ($PG_CONFIG)]) 
     65  else 
     66    AC_MSG_ERROR(['$PG_CONFIG' is not an executable.  Make sure you use --with-postgis=/path/to/pg_config]) 
     67  fi 
     68 
     69  POSTGIS_LIB="-L`$PG_CONFIG --libdir` -lpq" 
     70  POSTGIS_INC="-I`$PG_CONFIG --includedir`" 
     71fi 
     72 
     73AC_SUBST(POSTGIS_ENABLED,$POSTGIS_ENABLED) 
     74AC_SUBST(POSTGIS_INC,$POSTGIS_INC) 
     75AC_SUBST(POSTGIS_LIB,$POSTGIS_LIB) 
     76 
    1377AC_CHECK_FUNCS() 
    1478 
    1579AC_OUTPUT(Makefile src/ows_define.h) 
  • src/wfs/wfs_transaction.c

     
    299299        assert(n != NULL); 
    300300 
    301301        content = xmlNodeGetContent(n); 
    302         /*if the value is a string, must be in quotation marks */ 
    303         if (check_regexp((char *) content, 
    304                   "^[A-Za-z]") == 1 
    305            || check_regexp((char *) content, ".*-.*") == 1) 
    306                 buffer_add_str(value, "'"); 
    307  
     302        /*Value must be in quotation marks because of spaces*/ 
     303        buffer_add_str(value, "'"); 
    308304        buffer_add_str(value, (char *) content); 
     305        buffer_add_str(value, "'"); 
    309306 
    310         if (check_regexp((char *) content, 
    311                   "^[A-Za-z]") == 1 
    312            || check_regexp((char *) content, ".*-.*") == 1) 
    313                 buffer_add_str(value, "'"); 
    314307 
    315308        xmlFree(content); 
    316309 
     
    352345static buffer *wfs_insert_xml(ows * o, wfs_request * wr, xmlNodePtr n) 
    353346{ 
    354347        buffer *values, *column, *layer_name, *result, *sql, *id, *tmp; 
     348    buffer *current_pkey, *last_pkey, *target_layer; 
    355349        list *fid; 
    356350        filter_encoding *fe; 
    357351        xmlNodePtr node, elemt; 
    358352        xmlChar *content; 
     353    array *current_layer_pkey; 
     354    array_node *an; 
     355    int nkey, nlast_pkey; 
     356    unsigned int fid_list_size, current_fid_list_size; 
    359357 
    360358        assert(o != NULL); 
    361359        assert(wr != NULL); 
     
    363361 
    364362        sql = buffer_init(); 
    365363        fid = list_init(); 
     364    fid_list_size = 0; 
     365    current_fid_list_size = 0; 
    366366        content = NULL; 
    367367 
    368368        /* retrieve handle attribute to report it in transaction response */ 
     
    386386        while (n->type != XML_ELEMENT_NODE) 
    387387                n = n->next; 
    388388 
     389    current_layer_pkey = array_init(); 
     390 
    389391        /* insert elements layer by layer */ 
    390392        for (; n; n = n->next) 
    391393        { 
     
    468470                                                        /* retrieve the id of the inserted feature  
    469471                                                           to report it in transaction response */ 
    470472                                                        list_add(fid, tmp); 
     473                            current_fid_list_size = current_fid_list_size + 1; 
    471474                                                } 
    472475                                        } 
    473476                                        xmlFree(content); 
     
    490493 
    491494                buffer_add_str(sql, "; "); 
    492495 
     496        /* If there is no fid in the request, get and store the value of pkey 
     497           of the last row for this layer */ 
     498        if( (current_fid_list_size == fid_list_size) &&  
     499            (!array_is_key(current_layer_pkey, layer_name->buf)) ) 
     500        { 
     501            current_pkey = ows_psql_get_current_pkey(o, layer_name); 
     502 
     503            target_layer = buffer_init(); 
     504            buffer_copy(target_layer, layer_name); 
     505            array_add(current_layer_pkey, target_layer, current_pkey); 
     506        } 
     507        { 
     508            fid_list_size = current_fid_list_size; 
     509        } 
     510 
    493511                buffer_free(values); 
    494512                buffer_free(id); 
    495513                buffer_free(layer_name); 
    496514        } 
    497515 
    498         /* list of featureid inserted to be used during transaction response */ 
    499         wr->insert_results = mlist_init(); 
    500         mlist_add(wr->insert_results, fid); 
    501516 
    502517        /* run the request to insert all features at the same time */ 
    503518        result = wfs_execute_transaction_request(o, wr, sql); 
    504519        buffer_free(sql); 
    505520 
     521    /* Add the pkey of the new inserted to be output in the response */ 
     522    for (an = current_layer_pkey->first; an != NULL; /* empty */ ) 
     523        { 
     524        last_pkey = ows_psql_get_current_pkey(o, an->key); 
     525        nlast_pkey = atoi(last_pkey->buf); 
     526        for (nkey = atoi(an->value->buf) + 1; nkey <= nlast_pkey;  
     527             nkey++ ) 
     528        { 
     529            tmp = buffer_init(); 
     530                buffer_copy(tmp, an->key); 
     531                    buffer_add_str(tmp, "."); 
     532            buffer_add_int(tmp, nkey); 
     533            list_add(fid, tmp); 
     534        } 
     535                an = an->next; 
     536        buffer_empty(last_pkey); 
     537        } 
     538        /* list of featureid inserted to be used during transaction response */ 
     539        wr->insert_results = mlist_init(); 
     540        mlist_add(wr->insert_results, fid); 
     541 
     542    array_free(current_layer_pkey); 
    506543        return result; 
    507544} 
    508545 
    509  
    510546/* 
    511547 * Delete features in database 
    512548 * Method GET / KVP 
     
    743779                                        buffer_add_str(property_name, (char *) content); 
    744780                                        xmlFree(content); 
    745781                                        wfs_request_remove_namespaces(o, property_name); 
     782                    buffer_add_str(sql, "\""); 
    746783                                        buffer_copy(sql, property_name); 
     784                    buffer_add_str(sql, "\""); 
    747785                                } 
    748786 
    749787                                buffer_add_str(sql, " = "); 
  • src/ows_api.h

     
    145145buffer *ows_psql_timestamp_to_xml_datetime (char *date); 
    146146char *ows_psql_to_xsd (buffer * type); 
    147147buffer *ows_psql_type (ows * o, buffer * layer_name, buffer * property); 
     148buffer *ows_psql_get_current_pkey(ows * o, buffer * layer_name); 
    148149void ows_request_check (ows * o, ows_request * or, const array * cgi, const char *query); 
    149150void ows_request_flush (ows_request * or, FILE * output); 
    150151void ows_request_free (ows_request * or); 
     
    191192void wms_request_flush (wms_request * wr, FILE * output); 
    192193void wms_request_free (wms_request * wr); 
    193194wms_request *wms_request_init (); 
     195char *ows_get_config_path (); 
     196char *ows_get_schema_path (char *schema_type); 
  • src/ows/ows_request.c

     
    240240        list_node *srid; 
    241241        bool srsname; 
    242242        int valid; 
     243    char *schema_path; 
    243244 
    244245        assert(o != NULL); 
    245246        assert(or != NULL); 
     
    392393                        if (ows_version_get(or->version) == 100) 
    393394                        { 
    394395                                if (buffer_cmp(b, "Transaction")) 
    395                                         valid = ows_schema_validation(WFS_SCHEMA_100_TRANS_PATH, 
    396                                             xmlstring); 
     396                { 
     397                        schema_path = ows_get_schema_path(WFS_SCHEMA_100_TRANS); 
     398                    valid = ows_schema_validation(schema_path, xmlstring); 
     399                } 
    397400                                else 
    398                                         valid = ows_schema_validation(WFS_SCHEMA_100_BASIC_PATH,  
    399                                             xmlstring); 
     401                { 
     402                        schema_path = ows_get_schema_path(WFS_SCHEMA_100_BASIC); 
     403                                valid = ows_schema_validation(schema_path, xmlstring); 
     404                } 
    400405                        } 
    401406                        else 
    402                                 valid = ows_schema_validation(WFS_SCHEMA_110_PATH, xmlstring); 
     407            { 
     408                    schema_path = ows_get_schema_path(WFS_SCHEMA_110); 
     409                        valid = ows_schema_validation(schema_path, xmlstring); 
     410            } 
     411            free(schema_path); 
    403412                } 
    404413                buffer_free(xmlstring); 
    405414                if (valid != 0) 
  • src/ows/ows_psql.c

     
    647647} 
    648648 
    649649 
     650/*  
     651 * Return the pkey value of the last inserted feature from table matching  
     652 * layer name 
     653 */ 
     654buffer *ows_psql_get_current_pkey(ows * o, buffer * layer_name) 
     655{ 
     656        buffer *sql; 
     657        PGresult *res; 
     658        buffer *b, *request_name, *parameters, *sequence_name; 
     659 
     660        assert(o != NULL); 
     661        assert(layer_name != NULL); 
     662 
     663        sql = buffer_init(); 
     664        b = buffer_init(); 
     665    sequence_name = buffer_init(); 
     666 
     667        /* retrieve the sequence name for the layer */ 
     668    buffer_add_str(sql, "SELECT $1"); 
     669        buffer_add_str(sql, "|| '_' || column_name || '_seq' as sequence_name "); 
     670        buffer_add_str(sql, 
     671           "FROM information_schema.constraint_column_usage "); 
     672        buffer_add_str(sql, "WHERE table_name = $1 AND constraint_name = ("); 
     673 
     674        buffer_add_str(sql, "SELECT c.conname "); 
     675        buffer_add_str(sql, "FROM pg_class r, pg_constraint c "); 
     676        buffer_add_str(sql, "WHERE r.oid = c.conrelid AND relname = $1 "); 
     677        buffer_add_str(sql, "AND c.contype = 'p')"); 
     678 
     679    /* initialize the request's name and parameters */ 
     680        request_name = buffer_init(); 
     681        buffer_add_str(request_name, "sequence_name"); 
     682        parameters = buffer_init(); 
     683        buffer_add_str(parameters, "(text)"); 
     684 
     685        /* check if the request has already been executed */ 
     686        if (!in_list(o->psql_requests, request_name)) 
     687                ows_psql_prepare(o, request_name, parameters, sql); 
     688 
     689        /* execute the request */ 
     690        buffer_empty(sql); 
     691        buffer_add_str(sql, "EXECUTE sequence_name('"); 
     692        buffer_copy(sql, layer_name); 
     693        buffer_add_str(sql, "')"); 
     694 
     695        res = PQexec(o->pg, sql->buf); 
     696        buffer_free(parameters); 
     697        buffer_free(request_name); 
     698 
     699    if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0) 
     700        { 
     701                PQclear(res); 
     702                return b; 
     703        } 
     704 
     705        buffer_add_str(sequence_name, PQgetvalue(res, 0, 0)); 
     706        PQclear(res); 
     707 
     708    /*Get the last value of the pkey for this layer*/ 
     709    buffer_empty(sql); 
     710    buffer_add_str(sql, "SELECT last_value FROM "); 
     711    buffer_copy(sql, sequence_name); 
     712 
     713        res = PQexec(o->pg, sql->buf); 
     714        buffer_free(sql); 
     715 
     716    if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) == 0) 
     717        { 
     718                PQclear(res); 
     719                return b; 
     720        } 
     721 
     722        buffer_add_str(b, PQgetvalue(res, 0, 0)); 
     723        PQclear(res); 
     724 
     725        return b; 
     726} 
     727 
    650728/* 
    651729 * vim: expandtab sw=4 ts=4 
    652730 */ 
  • src/ows/ows.c

     
    2929#include "ows.h" 
    3030#include "../ows_define.h" 
    3131 
     32char *ows_strdup(char *s) 
     33{ 
     34  char  *s1; 
    3235 
     36  if(!s) 
     37    return(NULL); 
     38  s1 = (char *)malloc(strlen(s) + 1); 
     39  if(!s1) 
     40    return(NULL); 
     41 
     42  strcpy(s1,s); 
     43  return(s1); 
     44} 
     45/* 
     46 * Return config file path 
     47 */ 
     48char *ows_get_config_path() 
     49{ 
     50    const char *config_path = OWS_CONFIG_FILE_PATH; 
     51    const char *config_env_var = getenv("TINYOWS_CONFIG_FILE"); 
     52 
     53    if(config_env_var != NULL) 
     54    { 
     55        return ows_strdup((char*) config_env_var); 
     56    } 
     57    else 
     58    { 
     59        return ows_strdup((char*) config_path); 
     60    } 
     61} 
     62 
     63/* 
     64 * Return schema dir 
     65 */ 
     66char *ows_get_schema_path(char *schema_type) 
     67{ 
     68     
     69    char *schema_dir = NULL; 
     70    const char *schema_env_var = getenv("TINYOWS_SCHEMA_DIR"); 
     71 
     72    if(schema_env_var != NULL) 
     73    { 
     74       schema_dir = (char *) malloc(sizeof(char *) * (strlen(schema_env_var) +  
     75          strlen(schema_type) + 2 )); 
     76       sprintf(schema_dir, "%s/%s", schema_env_var, schema_type);  
     77    } 
     78    else 
     79    { 
     80        if( !strcmp(schema_type, WFS_SCHEMA_100_BASIC)) 
     81        { 
     82             schema_dir = (char *) malloc( sizeof(char *) *  
     83                (strlen(WFS_SCHEMA_100_BASIC_PATH) )); 
     84             sprintf(schema_dir, "%s", WFS_SCHEMA_100_BASIC_PATH);  
     85        } 
     86        else if(!strcmp(schema_type, WFS_SCHEMA_100_TRANS)) 
     87        { 
     88             schema_dir = (char *) malloc( sizeof(char *) *  
     89                (strlen(WFS_SCHEMA_100_TRANS_PATH) )); 
     90             sprintf(schema_dir, "%s", WFS_SCHEMA_100_TRANS_PATH);  
     91        } 
     92        else if(!strcmp(schema_type, WFS_SCHEMA_110)) 
     93        { 
     94             schema_dir = (char *) malloc( sizeof(char *) *  
     95                (strlen(WFS_SCHEMA_110_PATH) )); 
     96             sprintf(schema_dir, "%s", WFS_SCHEMA_110_PATH);  
     97        } 
     98    } 
     99    return ows_strdup(schema_dir); 
     100} 
     101 
     102 
     103 
    33104/*  
    34105 * Connect the ows to the database specified in configuration file 
    35106 */ 
     
    202273 
    203274 
    204275void ows_usage(ows * o) { 
     276    char *config_path; 
     277    char *schema_path; 
     278 
    205279    printf("TinyOWS should be called by CGI throw a Web Server !\n\n"); 
    206280    printf("___________\n"); 
    207     printf("Config File Path: %s\n", OWS_CONFIG_FILE_PATH); 
     281    config_path = ows_get_config_path(); 
     282    printf("Config File Path: %s\n", config_path); 
    208283    printf("PostGIS dsn: '%s'\n", o->pg_dsn->buf); 
    209284    printf("___________\n"); 
    210     printf("WFS 1.0.0 Basic Schema Path: %s\n", WFS_SCHEMA_100_BASIC_PATH); 
    211     printf("WFS 1.0.0 Transactional Schema Path: %s\n",  
    212         WFS_SCHEMA_100_TRANS_PATH); 
    213     printf("WFS 1.1.0 Schema Path: %s\n", WFS_SCHEMA_110_PATH); 
     285    schema_path = ows_get_schema_path(WFS_SCHEMA_100_BASIC); 
     286    printf("WFS 1.0.0 Basic Schema Path: %s\n", schema_path); 
     287    schema_path = ows_get_schema_path(WFS_SCHEMA_100_TRANS); 
     288    printf("WFS 1.0.0 Transactional Schema Path: %s\n", schema_path); 
     289    schema_path = ows_get_schema_path(WFS_SCHEMA_110); 
     290    printf("WFS 1.1.0 Schema Path: %s\n", schema_path); 
    214291    printf("___________\n"); 
     292 
     293    free(config_path); 
     294    free(schema_path); 
     295    
    215296} 
    216297 
    217298 
    218299int main(int argc, char *argv[]) 
    219300{ 
    220         char *query; 
     301        char *query, *config_path; 
    221302        ows *o; 
    222303 
    223304        o = ows_init(); 
     
    228309        /* retrieve the query in HTTP request */ 
    229310        query = cgi_getback_query(o); 
    230311 
     312    config_path = ows_get_config_path(); 
     313 
    231314    if (query == NULL || strlen(query) == 0) { 
    232315            if (argc > 1 && (strncmp(argv[1], "--help", 6) == 0 
    233316                     || strncmp(argv[1], "-h", 2) == 0)) { 
    234                     ows_parse_config(o, OWS_CONFIG_FILE_PATH); 
     317                    ows_parse_config(o, config_path); 
    235318            ows_usage(o); 
    236319        } else ows_error(o, OWS_ERROR_INVALID_PARAMETER_VALUE, 
    237320                           "Service Unknown", "service"); 
     321 
     322       return EXIT_SUCCESS; 
    238323    } 
    239324 
    240325    /*  
     
    277362        o->psql_requests = list_init(); 
    278363 
    279364        /* Parse the configuration file and initialize ows struct */ 
    280         ows_parse_config(o, OWS_CONFIG_FILE_PATH); 
     365        ows_parse_config(o, config_path); 
    281366 
    282367        /* Connect the ows to the database */ 
    283368        ows_pg(o, o->pg_dsn->buf); 
  • src/ows_define.h.in

     
    3232 
    3333#define OWS_CONFIG_FILE_PATH        "@prefix@/tinyows/config.xml" 
    3434 
    35 #define WFS_SCHEMA_100_BASIC_PATH   "@prefix@/tinyows/schema/wfs/1.0.0/WFS-basic.xsd" 
    36 #define WFS_SCHEMA_100_TRANS_PATH   "@prefix@/tinyows/schema/wfs/1.0.0/WFS-transaction.xsd" 
    37 #define WFS_SCHEMA_110_PATH         "@prefix@/tinyows/schema/wfs/1.1.0/wfs.xsd" 
     35#define WFS_SCHEMA_100_BASIC        "wfs/1.0.0/WFS-basic.xsd" 
     36#define WFS_SCHEMA_100_BASIC_PATH   "@prefix@/tinyows/schema/" WFS_SCHEMA_100_BASIC 
     37#define WFS_SCHEMA_100_TRANS        "wfs/1.0.0/WFS-transaction.xsd" 
     38#define WFS_SCHEMA_100_TRANS_PATH   "@prefix@/tinyows/schema/" WFS_SCHEMA_100_TRANS 
     39#define WFS_SCHEMA_110              "wfs/1.1.0/wfs.xsd" 
     40#define WFS_SCHEMA_110_PATH         "@prefix@/tinyows/schema/" WFS_SCHEMA_110 
    3841 
    3942#endif /* OWS_DEFINE_H */ 
    4043