/******************************************************************************* * *N {logfile_sample.c} -- demonstrates usage of logile * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *P Purpose: * This sample C program demonstrates how to create logfile; how to add IDs * into the logfile; and how to apply logfile in query. * * High-level overview - demostrate "select in selection" using logfile: * (1) Prepare a layer with 30 rows; * (2) Perform an attribute query and store the selection result into a * logfile (Add ROWID's into the logfile ). * ROW1-ROW20 will be selected * (3) Perform a spatial query without using the logfile; ROW11-ROW30 will be selected in this step * (4) Perform a spatial query(with the same filter as step 3) on the * selection result of step (2) by using the logfile. * ROW11-ROW20 will be selected in this step * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * How to compile:: * Please refer section "Build C Samples" in the SDE sample * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Usage: * logfile_sample {server} {instance} {database} {user} {password} {keywords} * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *X Legalese: * * Copyright © 2007 ESRI * * All rights reserved under the copyright laws of the United States and * applicable international laws, treaties, and conventions. * * You may freely redistribute and use this sample code, with or without * modification, provided you include the original copyright notice and use * restrictions. * * Disclaimer: THE SAMPLE CODE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ESRI OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) SUSTAINED BY YOU OR A THIRD PARTY, HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT ARISING IN ANY WAY OUT OF THE USE OF THIS SAMPLE CODE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * For additional information, contact: * Environmental Systems Research Institute, Inc. * Attn: Contracts and Legal Services Department * 380 New York Street * Redlands, California, 92373 * USA * * email: contracts@esri.com * *E ****************************************************************************/ #include #include #include #include #include "sdetype.h" #include "sdeerno.h" #define INTCOL "INTCOL" #define STRCOL "STRCOL" #define SHPCOL "SHPCOL" #define ROWIDCOL "ROWIDCOL" #define MAX_ROW 30 typedef enum { LOGFILE_USAGE_STORE_RESULT/*Store query result to a logfile*/, LOGFILE_USAGE_QUERY_LOGFILE/*Apply a exited logfile to the query*/, LOGFILE_USAGE_NONE/*Query without any logfile usage*/ } LOGFILE_USAGE; /* Function macros */ #define check_rc_return_on_failure(c,s,rc,f) \ {if(rc!= SE_SUCCESS) {check_rc_(c,s,rc,f,__LINE__,__FILE__);return SE_FAILURE; }} /* Local Function Prototypes */ void check_rc_(SE_CONNECTION Connection, SE_STREAM Stream, LONG rc, char *comment, LONG line_no, char* file_name); static LONG S_create_layer(SE_CONNECTION connection,CHAR *table,CHAR *keyword); static LONG S_insert_rows(SE_CONNECTION handle,const CHAR *table,LONG num_of_rows); static LONG S_query_layer(SE_CONNECTION connection, const CHAR *table, const CHAR *where, SE_FILTER *spfilter, LOGFILE_USAGE logfile_usage, CHAR **logfilename); LONG main(int argc, char *argv[]){ CHAR *server, *user, *passwd, *database, *instance, *keyword; SE_CONNECTION conn; SE_ERROR error; LONG result; CHAR layername[SE_MAX_TABLE_LEN+1]; CHAR where[1024]; CHAR *logfilename=NULL; SE_LAYERINFO layer; SE_COORDREF coordref; SE_ENVELOPE env; SE_SHAPE filter_shape; SE_FILTER spfilter; if(argc<7){ printf("Usage %s ",argv[0]); exit(1); } server=argv[1]; instance=argv[2]; database=argv[3]; user=argv[4]; passwd=argv[5]; keyword=argv[6]; strcpy(layername,"logfile_sample"); //Connect to the sde server result = SE_connection_create( server, instance, database, user, passwd, &error, &conn ); check_rc_return_on_failure (conn,NULL,result,"SE_connection_create"); printf("Conn: connected to %s:%s as %s\n",server,instance,user); /*Create the sample layer*/ printf("\nCreating sample layer......\n"); result=S_create_layer(conn,layername,keyword); if(result!=SE_SUCCESS) return result; /*Insert 30 rows into the sample layer*/ printf("\nInsert 30 rows into the layer......\n"); result=S_insert_rows(conn,layername,30); if(result!=SE_SUCCESS) return result; /* Perform an attribute query and store the selection result into a logfile: ROW1-ROW20 will be selected */ printf("\nQuery the layer( INTCOL>=1 AND INTCOL<=20) and store the result to a logfile ......\n"); strcpy(where,"INTCOL>=1 AND INTCOL<=20"); result=S_query_layer(conn,layername,where,NULL,LOGFILE_USAGE_STORE_RESULT,&logfilename); if(result!=SE_SUCCESS) return result; /*Prepare a spatial filter*/ //Prepare the filter shape result = SE_layerinfo_create (NULL,&layer); check_rc_return_on_failure (conn,NULL,result,"SE_layerinfo_create"); result = SE_coordref_create (&coordref); check_rc_return_on_failure (conn,NULL,result,"SE_coordref_create"); result = SE_layer_get_info (conn,layername,SHPCOL,layer); check_rc_return_on_failure (conn,NULL,result,"SE_layer_get_info"); result = SE_layerinfo_get_coordref (layer,coordref); check_rc_return_on_failure (conn,NULL,result,"SE_layerinfo_get_coordref"); result = SE_shape_create (coordref,&filter_shape); check_rc_return_on_failure (conn,NULL,result,"SE_shape_create"); env.minx=115.0; env.miny=115.0; env.maxx=300.0; env.maxy=300.0; result = SE_shape_generate_rectangle(&env,filter_shape); //Init the spatial filter strcpy(spfilter.table,layername); strcpy(spfilter.column,SHPCOL); spfilter.filter_type = SE_SHAPE_FILTER; spfilter.truth = TRUE; spfilter.filter.shape = filter_shape; spfilter.method=SM_ENVP; /* Query with the spatial filter but without using the logfile logfile: ROW10-ROW30 will be selected */ printf("\nQuery the layer with a spatial filter......\n"); strcpy(where,""); result=S_query_layer(conn,layername,where,&spfilter,LOGFILE_USAGE_NONE,NULL); if(result!=SE_SUCCESS) return result; /* Query with the spatial filter with the logfile applied logfile: ROW10-ROW20 will be selected */ printf("\nQuery the layer with the same spatial filter using the logfile......\n"); result=S_query_layer(conn,layername,where,&spfilter,LOGFILE_USAGE_QUERY_LOGFILE,&logfilename); if(result!=SE_SUCCESS) return result; //Clean up if(logfilename!=NULL){ SE_log_delete (conn,logfilename); free(logfilename); } SE_table_delete(conn,layername); SE_connection_free(conn); return SE_SUCCESS; } /*********************************************************************** * *N {S_create_layer} - create a test layer with provided specification * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Create a sample layer with provided specification *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. * == (CHAR*) the base table name * == (CHAR*) the keyword for table creation *E ***********************************************************************/ static LONG S_create_layer(SE_CONNECTION connection,CHAR *table,CHAR *keyword) { SE_LAYERINFO layer; SHORT number_of_columns; SE_COLUMN_DEF column_definitions[3]; SE_COORDREF coordref; LONG result; SE_REGINFO registration; LONG layer_type; /* Create the base table. */ number_of_columns = 2; strcpy (column_definitions[0].column_name,INTCOL); column_definitions[0].sde_type = SE_INT32_TYPE; column_definitions[0].size = 0; column_definitions[0].decimal_digits = 0; column_definitions[0].nulls_allowed = TRUE; strcpy(column_definitions[1].column_name,STRCOL); column_definitions[1].sde_type = SE_STRING_TYPE; column_definitions[1].size = 128; column_definitions[1].decimal_digits = -1; column_definitions[1].nulls_allowed = FALSE; //delete the table if already existed result = SE_table_delete(connection,table); if(result!=SE_TABLE_NOEXIST) check_rc_return_on_failure (connection,NULL,result,"SE_table_delete"); //create the base table result = SE_table_create (connection,table,number_of_columns, column_definitions,keyword); check_rc_return_on_failure (connection,NULL,result,"SE_table_create"); /* Alter the registration of the table to have an SDE maintained rowid */ result = SE_reginfo_create (®istration); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_create"); result = SE_registration_get_info (connection,table,registration); check_rc_return_on_failure (connection,NULL,result,"SE_registration_get_info"); result = SE_reginfo_set_creation_keyword (registration,keyword); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_set_creation_keyword"); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_set_description"); result = SE_reginfo_set_rowid_column (registration,ROWIDCOL, SE_REGISTRATION_ROW_ID_COLUMN_TYPE_SDE); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_set_rowid_column"); result = SE_registration_alter (connection,registration); check_rc_return_on_failure (connection,NULL,result,"SE_registration_alter"); /* Add the spatial column to the table that will containt polygons*/ layer_type=SE_AREA_TYPE_MASK | SE_NIL_TYPE_MASK; result = SE_coordref_create (&coordref); check_rc_return_on_failure (connection,NULL,result,"SE_coordref_create"); result = SE_coordref_set_xy (coordref,0.0,0.0,10.0); check_rc_return_on_failure (connection,NULL,result,"SE_coordref_set_xy"); SE_coordref_set_precision (coordref,64); check_rc_return_on_failure (connection,NULL,result,"SE_coordref_set_precision"); result = SE_layerinfo_create (coordref,&layer); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_create"); result = SE_layerinfo_set_grid_sizes (layer,100.0,0.0,0.0); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_grid_sizes"); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_description"); result = SE_layerinfo_set_shape_types (layer,layer_type); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_shape_types"); result = SE_layerinfo_set_spatial_column (layer,table,SHPCOL); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_spatial_column"); result = SE_layerinfo_set_creation_keyword (layer,keyword); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_creation_keyword"); result=SE_layerinfo_set_minimum_id(layer,11); check_rc_return_on_failure (connection,NULL,result,"SE_layerinfo_set_minimum_id"); result = SE_layer_create (connection,layer,100,10); check_rc_return_on_failure (connection,NULL,result,"SE_layer_create"); SE_layerinfo_free(layer); SE_coordref_free(coordref); return(SE_SUCCESS); } /*********************************************************************** * *N {S_insert_rows} - insert rows into the table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Insert rows into the sample table. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * == (SE_CONNECTION) The connection handle. *
== (CHAR*) the layer name * == (LONG) number of rows to be inserted *E ***********************************************************************/ static LONG S_insert_rows(SE_CONNECTION handle,const CHAR *table,LONG num_of_rows) { SE_STREAM stream; LONG result,row,i; SHORT number_of_columns; CHAR **base_columns; SE_LAYERINFO layer; SE_COORDREF coordref; SE_SHAPE shape; SE_POINT points[5]; LONG part_offsets[1]; SE_INT32 intval; CHAR strval[128]; /*Init columns names for insert */ number_of_columns = 3; base_columns = (CHAR **) malloc (number_of_columns * sizeof(CHAR *)); for(i=0;i == (SE_CONNECTION) The connection handle. *
== (CHAR*) the layer name * == (const CHAR*) the where clause * == (SE_FILTER) The spatial filter for query * == (LOGFILE_USAGE) logfile usage: LOGFILE_USAGE_STORE_RESULT : Store query result to a logfile; LOGFILE_USAGE_QUERY_LOGFILE:Apply a exited logfile to the query; LOGFILE_USAGE_NONE :Query without any logfile usage * == (CHAR*) The logfile name *E ***********************************************************************/ static LONG S_query_layer(SE_CONNECTION connection, const CHAR *table, const CHAR *where, SE_FILTER *spfilter, LOGFILE_USAGE logfile_usage, CHAR **logfilename) { LONG result,i,fetched_rows=0,rowid,intval; CHAR **columns; SE_QUERYINFO qinfo; SE_STREAM query_stream; CHAR orderby[128]; SHORT num_of_column; SE_LAYERINFO layer; SE_COORDREF coordref; SE_SHAPE shape; CHAR strval[128]; SE_LOGINFO loginfo; SE_LOG log; LONG idlist[MAX_ROW];//to simplify, we just use a static array here. if(logfile_usage==LOGFILE_USAGE_STORE_RESULT){ /*Init a logfile if we need store the query result*/ if(logfilename==NULL){ printf("\tInvalid parameter name found.\n"); return SE_FAILURE; } if(*logfilename==NULL){//make a logfile name as needed *logfilename=(CHAR *) malloc ((SE_MAX_LOGFILE_NAME_LEN+1) * sizeof(CHAR)); result = SE_log_make_name (connection, *logfilename); check_rc_return_on_failure (connection,NULL,result,"SE_log_make_name"); }else{//delete a existed logfile name as needed result = SE_log_delete( connection, *logfilename ); check_rc_return_on_failure (connection,NULL,result,"SE_log_delete"); } /*Prepare the logfile for ID storing*/ result = SE_loginfo_create (&loginfo); check_rc_return_on_failure (connection,NULL,result,"SE_loginfo_create"); result = SE_loginfo_set_name (loginfo,*logfilename); check_rc_return_on_failure (connection,NULL,result,"SE_loginfo_set_name"); result = SE_loginfo_set_target_object(loginfo, SE_LOG_FOR_TABLE, (CHAR*)table,"SHPCOL"); check_rc_return_on_failure (connection,NULL,result,"SE_loginfo_set_target_object"); result = SE_loginfo_set_persistence(loginfo, FALSE); check_rc_return_on_failure (connection,NULL,result,"SE_loginfo_set_persistence"); result = SE_log_open_log (connection, loginfo, SE_OUTPUT_MODE, &log); check_rc_return_on_failure (connection,NULL,result,"SE_log_open_log"); printf("\tLogfile %s is ready for ID storing.\n",*logfilename); }else if (logfile_usage==LOGFILE_USAGE_QUERY_LOGFILE){ if(logfilename!=NULL && *logfilename!=NULL){ result = SE_loginfo_create (&loginfo); check_rc_return_on_failure (connection,NULL,result,"SE_loginfo_create"); //We will do a logfile retrieve to make sure the logfile existing result=SE_log_get_by_name (connection,*logfilename,loginfo); check_rc_return_on_failure (connection,NULL,result,"SE_log_get_by_name"); printf("\tQuerying use logfile %s\n",*logfilename); }else{ printf("\tInvalid logfile name found.\n"); return SE_FAILURE; } }else if(logfile_usage!=LOGFILE_USAGE_NONE){ if(logfilename==NULL){ printf("\tInvalid LOGFILE_USAGE value provided.\n"); return SE_FAILURE; } } /*Prepare the query stream*/ //Init the columns for the query num_of_column = 4; columns = (CHAR **) malloc (num_of_column * sizeof(CHAR *)); for(i=0;i