/******************************************************************************* * *N {schobj_privilege.c} -- demonstrates the permission control on table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *P Purpose: * This sample C program demonstrates how to grant and revoke privileges to * and from specific users * * Scenarios: * (1) user1 and user2 connect to SDE server * (2) user1 creates a sample table * (3) user1 inserts some rows into the table * (4) user2 tries to access the sample table * (5) user1 grants the select privilege to user2 * (6) user2 tries to query the table again * (7) user2 tries to modify table: insert, delete & update * (8) user1 grants the insert/delete/update privileges to user2 * (9) user2 tries to modify table again: insert, delete & update * (10) user1 revokes all privileges from user2 * (11) user2 tries to access the sample table again * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * How to compile:: * Please refer section "Build C Samples" in the SDE sample * * *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Usage: * schobj_privilege {server} {instance} {database} {user1} {password1} * {user2} {password2} {keyword} * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: *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 <stdio.h> #include <stdlib.h> #include <string.h> #include "sdetype.h" #include "sdeerno.h" typedef enum { S_DM_BY_ROWID, S_DM_BY_WHERE } S_DM_MODE; /* 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 rc; }} #if defined(WIN32) #define SLEEP(n) _sleep(n*1000) #else #define SLEEP(n) sleep(n) #endif /*****************************/ /* 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_table(SE_CONNECTION connection,CHAR *table,CHAR *keyword); static LONG S_insert_rows(SE_CONNECTION handle,const CHAR *table, int num_of_row,BOOL buf_write_mode); static LONG S_update_row(SE_CONNECTION handle,const CHAR *table, S_DM_MODE update_mode, LONG rowid); static LONG S_delete_rows(SE_CONNECTION connection,const CHAR *table,S_DM_MODE, LONG delete_count,const LONG *delete_list); static LONG S_query_table(SE_CONNECTION connection, const CHAR *table,const CHAR* where); /************************************/ /* Global variables Prototypes */ /***********************************/ static CHAR ROWID_COL[SE_MAX_COLUMN_LEN]; //NEXT_INT16_VALUE -- We will used it to track value for the int16_col. static SHORT NEXT_INT16_VALUE=1; LONG main(int argc, char *argv[]){ CHAR *server, *user1, *passwd1, *user2, *passwd2, *database, *instance, *keyword; SE_CONNECTION conn1,conn2; SE_ERROR error; LONG result; CHAR table[SE_MAX_TABLE_LEN+1]; LONG delete_list[10]; LONG delete_count; CHAR where[128]; LONG permissions; CHAR qualified_table_name[SE_QUALIFIED_TABLE_NAME+1]; SE_REGINFO registration; // parse arguments if(argc<9){ printf("Usage %s <server> <instance> <database> <user1> <passwd1> <user2> <passwd2> <keyword>\n\n",argv[0]); exit(1); } server=argv[1]; instance=argv[2]; database=argv[3]; user1=argv[4]; passwd1=argv[5]; user2=argv[6]; passwd2=argv[7]; keyword=argv[8]; strcpy(ROWID_COL,"ROWID_COL"); strcpy(table,"SAMPLE_TBLPRIV"); strcpy(where,""); NEXT_INT16_VALUE=1; /*USER1 connect to SDE server*/ printf("\n%s trying to connect to %s:%s\n",user1,server,instance); result = SE_connection_create( server, instance, database, user1, passwd1, &error, &conn1 ); check_rc_return_on_failure (conn1,NULL,result,"SE_connection_create"); printf("\tConnected\n"); /*USER2 connect to SDE server*/ printf("\n%s trying to connect to %s:%s\n",user2,server,instance); result = SE_connection_create( server, instance, database, user2, passwd2, &error, &conn2 ); check_rc_return_on_failure (conn2,NULL,result,"SE_connection_create"); printf("\tConnected\n"); /*USER1 create sample table*/ printf("\n%s creating table... \n",user1); result=S_create_table(conn1,table,keyword); if(result!=SE_SUCCESS) exit(1); // retrieve table's registration result = SE_reginfo_create (®istration); check_rc_return_on_failure (conn1,NULL,result,"SE_reginfo_create"); result = SE_registration_get_info (conn1,table,registration); check_rc_return_on_failure (conn1,NULL,result,"SE_registration_get_info"); result=SE_reginfo_get_table_name(registration,qualified_table_name); check_rc_return_on_failure (conn1,NULL,result,"SE_registration_get_info"); /*USER1 insert 10 rows into the sample table*/ printf("\n%s inserts 5 rows into the table...\n",user1); result=S_insert_rows(conn1,table,5,FALSE); if(result!=SE_SUCCESS) exit(1); /*USER2 trying to query the table*/ printf("\n%s trying to query the table....\n",user2); result=S_query_table(conn2,qualified_table_name,where); if(result==SE_NO_PERMISSIONS ){ printf("\t%s doesn't have the permission to query %s\n",user2,qualified_table_name); } /*USER1 grant select privilege to USER2*/ printf("\n%s grants select privilege to %s\n",user1, user2); permissions=SE_SELECT_PRIVILEGE; result=SE_table_grant_access(conn1,table,permissions,TRUE,user2); check_rc_return_on_failure (conn1,NULL,result,"SE_table_grant_access"); SLEEP(2); /*Showing user2's permission on the table*/ printf("\n%s currently has the following permission to table %s:\n\t",user2,qualified_table_name); result=SE_table_get_permissions(conn2,qualified_table_name,&permissions); if(result==SE_NO_PERMISSIONS){ printf("No permission to access table\n",qualified_table_name); }else{ if((permissions | SE_SELECT_PRIVILEGE) == SE_SELECT_PRIVILEGE) printf("[SELECT] "); if((permissions | SE_INSERT_PRIVILEGE) == SE_INSERT_PRIVILEGE ) printf("[INSERT] "); if((permissions | SE_DELETE_PRIVILEGE) == SE_DELETE_PRIVILEGE) printf("[DELETE] "); if((permissions | SE_UPDATE_PRIVILEGE) == SE_UPDATE_PRIVILEGE) printf("[UPDATE] "); printf("\n"); } /*USER2 trying to query the table again*/ printf("\n%s trying to query the table again....\n",user2); result=S_query_table(conn2,qualified_table_name,where); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to query %s\n",user2,table); } /*USER2 trying to insert some rows into the table*/ printf("\n\n%s trying to insert 5 rowss into the table....\n",user2); result=S_insert_rows(conn2,qualified_table_name,5,FALSE); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have to permission to edit table %s\n",user2,qualified_table_name); }else printf("\tDone\n"); /*USER2 trying to delete some rows from the table*/ printf("\n%s trying to delete a row from the table....\n",user2); delete_count=1; delete_list[0]=1; result=S_delete_rows(conn2,qualified_table_name,S_DM_BY_ROWID,delete_count, delete_list); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to edit %s\n",user2,qualified_table_name); }else printf("\tDone\n"); /*USER2 trying to delete some rows from the table*/ printf("\n%s trying to update some rows in the table....\n",user2); delete_count=1; delete_list[0]=1; result=S_update_row(conn2,qualified_table_name,S_DM_BY_ROWID, 7); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to edit table %s\n",user2,qualified_table_name); }else printf("\tDone\n"); /*grant all privilege to user2*/ printf("\n%s grant slelect, insert, delete and update privilege to %s\n",user1, user2); permissions=SE_SELECT_PRIVILEGE|SE_INSERT_PRIVILEGE|SE_DELETE_PRIVILEGE|SE_UPDATE_PRIVILEGE; result=SE_table_grant_access(conn1,table,permissions,TRUE,user2); check_rc_return_on_failure (conn1,NULL,result,"SE_table_grant_access"); SLEEP(2); /*Showing user2's permission on the table*/ printf("\n%s currently has the following permission to table %s:\n\t",user2,qualified_table_name); result=SE_table_get_permissions(conn2,qualified_table_name,&permissions); if( result==SE_NO_PERMISSIONS){ printf("No permission to access table\n",qualified_table_name); }else{ if(permissions | SE_SELECT_PRIVILEGE ) printf("[SELECT] "); if(permissions | SE_INSERT_PRIVILEGE ) printf("[INSERT] "); if(permissions | SE_DELETE_PRIVILEGE ) printf("[DELETE] "); if(permissions | SE_UPDATE_PRIVILEGE ) printf("[UPDATE] "); printf("\n"); } /*USER2 trying to insert some rows into the table*/ printf("\n%s trying to insert 5 rows into the table....\n",user2); result=S_insert_rows(conn2,qualified_table_name,5,FALSE); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to edit table %s\n",user2,qualified_table_name); }else printf("\tDone\n"); /*USER2 trying to delete some rows from the table*/ printf("\n%s trying to delete a row from the table....\n",user2); delete_count=1; delete_list[0]=1; result=S_delete_rows(conn2,qualified_table_name,S_DM_BY_ROWID,delete_count, delete_list); if(result==SE_NO_PERMISSIONS ){ printf("\t%s doesn't have the permission to edit %s\n",user2,qualified_table_name); }else printf("\tDone\n"); /*USER2 trying to delete some rows from the table*/ printf("\n%s trying to update some rows in the table....\n",user2); delete_count=1; delete_list[0]=1; result=S_update_row(conn2,qualified_table_name,S_DM_BY_ROWID, 7); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to edit table %s\n",user2,qualified_table_name); }else printf("\tDone\n"); /*USER2 trying to query the table again*/ printf("\n%s trying to query the table again after editing....\n",user2); result=S_query_table(conn2,qualified_table_name,where); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to query %s\n",user2,qualified_table_name); } /*revoke all privileges from users2*/ printf("\n\nrevoke all privileges from %s...\n",user2); permissions=SE_SELECT_PRIVILEGE|SE_INSERT_PRIVILEGE|SE_DELETE_PRIVILEGE|SE_UPDATE_PRIVILEGE; result=SE_connection_start_transaction(conn1); check_rc_return_on_failure( conn1, NULL, result, "SE_connection_start_transaction" ); result=SE_table_revoke_access(conn1,table,permissions,user2); check_rc_return_on_failure (conn1,NULL,result,"SE_table_revoke_access"); SE_connection_commit_transaction(conn1); check_rc_return_on_failure (conn1,NULL,result,"SE_connection_commit_transaction"); SLEEP(2); /*USER2 trying to query the table again*/ printf("\n%s trying to query the table again....\n",user2); result=S_query_table(conn2,qualified_table_name,where); if(result==SE_NO_PERMISSIONS){ printf("\t%s doesn't have the permission to query %s\n",user2,qualified_table_name); } /*delete the sample table*/ result=SE_table_delete(conn1,table); check_rc_return_on_failure( conn1, NULL, result, "SE_table_delete" ); SE_connection_free(conn2); SE_connection_free(conn1); return SE_SUCCESS; } /*********************************************************************** * *N {S_create_table} - create a sample table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Create a sample table *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * <connection> == (SE_CONNECTION) The connection handle. * <table > == (CHAR*) the table name * <keyword > == (CHAR*) the keyword for table creation *E ***********************************************************************/ static LONG S_create_table(SE_CONNECTION connection,CHAR *table,CHAR *keyword) { SHORT number_of_columns; SE_COLUMN_DEF column_definitions[8]; LONG result; SE_REGINFO registration; CHAR reg_desc[128]; //setup the column definition number_of_columns = 7; strcpy(column_definitions[0].column_name,"STR_COL"); column_definitions[0].sde_type = SE_STRING_TYPE; column_definitions[0].size = 60; column_definitions[0].decimal_digits = -1; column_definitions[0].nulls_allowed = FALSE; strcpy(column_definitions[1].column_name,"INT16_COL"); column_definitions[1].sde_type = SE_INT16_TYPE; column_definitions[1].size = 0; column_definitions[1].decimal_digits = 0; column_definitions[1].nulls_allowed = TRUE; strcpy (column_definitions[2].column_name,"INT32_COL"); column_definitions[2].sde_type = SE_INT32_TYPE; column_definitions[2].size = 0; column_definitions[2].decimal_digits = 0; column_definitions[2].nulls_allowed = TRUE; strcpy (column_definitions[3].column_name,"FLOAT32_COL"); column_definitions[3].sde_type = SE_FLOAT32_TYPE; column_definitions[3].size = 0; column_definitions[3].decimal_digits = 0; column_definitions[3].nulls_allowed = TRUE; strcpy (column_definitions[4].column_name,"FLOAT64_COL"); column_definitions[4].sde_type = SE_FLOAT64_TYPE; column_definitions[4].size = 0; column_definitions[4].decimal_digits = 0; column_definitions[4].nulls_allowed = TRUE; strcpy (column_definitions[5].column_name,"DATE_COL"); column_definitions[5].sde_type = SE_DATE_TYPE; column_definitions[5].size = 0; column_definitions[5].decimal_digits = 0; column_definitions[5].nulls_allowed = TRUE; strcpy (column_definitions[6].column_name,"BLOB_COL"); column_definitions[6].sde_type = SE_BLOB_TYPE; column_definitions[6].size = 0; column_definitions[6].decimal_digits = 0; column_definitions[6].nulls_allowed = TRUE; //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"); /* Add 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"); strcpy(reg_desc,"BASE TABLE FOR qa_layer_data"); result = SE_reginfo_set_description (registration,reg_desc ); check_rc_return_on_failure (connection,NULL,result,"SE_reginfo_set_description"); result = SE_reginfo_set_rowid_column (registration,ROWID_COL, 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"); SE_reginfo_free(registration); return(SE_SUCCESS); } /*********************************************************************** * *N {S_insert_rows} - insert rows into a layer * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Insert rows into a layer *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * <handle> == (SE_CONNECTION) The connection handle. * <table > == (CHAR*) the layer name * <num_of_row> == (LONG) number of rows to be inserted * <buf_write_mode>== (BOOL) using buffer writers or not *E ***********************************************************************/ static LONG S_insert_rows(SE_CONNECTION handle,const CHAR *table, int num_of_row,BOOL buf_write_mode) { SE_STREAM stream; LONG result,row; SHORT number_of_columns; CHAR **base_columns; LONG part_offsets[1]; CHAR str_val[32]; char ansi_str[32]; SHORT int16_val; SE_INT32 int32_val; FLOAT float32_val; LFLOAT float64_val; struct tm date_val; SE_BLOB_INFO blob_val; SHORT str_ind,int16_ind, float32_ind, int32_ind, float64_ind, date_ind,blob_ind; LONG blob_size,count,i; number_of_columns = 7; base_columns = (CHAR **) malloc (number_of_columns * sizeof(CHAR *)); for(i=0;i<number_of_columns;i++) base_columns[i]=(CHAR *) malloc (SE_MAX_COLUMN_LEN * sizeof(CHAR)); /* Set up for insert. */ strcpy( base_columns[0],"STR_COL"); strcpy( base_columns[1],"INT16_COL"); strcpy( base_columns[2],"INT32_COL"); strcpy( base_columns[3],"FLOAT32_COL"); strcpy( base_columns[4],"FLOAT64_COL"); strcpy( base_columns[5],"DATE_COL"); strcpy( base_columns[6],"BLOB_COL"); result = SE_stream_create (handle,&stream); check_rc_return_on_failure (handle,NULL,result,"SE_stream_create"); result = SE_stream_insert_table (stream,table,number_of_columns, (const CHAR **)base_columns); if(result==SE_NO_PERMISSIONS){ SE_stream_free(stream); for(i=0;i<number_of_columns;i++) free(base_columns[i]); free(base_columns); return result; }else check_rc_return_on_failure (NULL,stream,result,"SE_stream_insert_table"); result = SE_stream_set_write_mode (stream,buf_write_mode); check_rc_return_on_failure (NULL,stream,result,"SE_stream_set_write_mode"); /*initialize the bindings*/ result = SE_stream_bind_input_column (stream,1,str_val,&str_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,2,&int16_val,&int16_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,3,&int32_val,&int32_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,4,&float32_val,&float32_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,5,&float64_val,&float64_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,6,&date_val,&date_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,7,&blob_val,&blob_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); /* Perform the insert. */ str_ind = SE_IS_NOT_NULL_VALUE; int16_ind = SE_IS_NOT_NULL_VALUE; int32_ind = SE_IS_NOT_NULL_VALUE; float32_ind = SE_IS_NOT_NULL_VALUE; float64_ind = SE_IS_NOT_NULL_VALUE; date_ind = SE_IS_NOT_NULL_VALUE; blob_ind = SE_IS_NOT_NULL_VALUE; memset (&date_val, 0, sizeof(struct tm)); part_offsets[0]=1; for (row = 0;row < num_of_row ;row++) { int16_val=(SHORT)NEXT_INT16_VALUE; int32_val=NEXT_INT16_VALUE; float32_val =(FLOAT)NEXT_INT16_VALUE*1; float64_val =(LFLOAT)NEXT_INT16_VALUE*1.0 ; date_val.tm_mday = 1; date_val.tm_mon = 1; date_val.tm_year = 91; sprintf (ansi_str, "Inserted row %d", NEXT_INT16_VALUE); strcpy(str_val,ansi_str); //init blob content blob_size =(row+1)*100; blob_val.blob_length = blob_size; blob_val.blob_buffer = (char*)malloc(blob_size); count=0; while( count < blob_size) { blob_val.blob_buffer[count] ='i'; count++; } result = SE_stream_execute (stream); if(result!=SE_SUCCESS){ free(blob_val.blob_buffer); free(base_columns); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); } free(blob_val.blob_buffer); NEXT_INT16_VALUE++; } if(buf_write_mode){ result = SE_stream_flush_buffered_writes (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_flush_buffered_writes"); } //free resources result = SE_stream_free(stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_free"); for(i=0;i<number_of_columns;i++) free(base_columns[i]); free(base_columns); return(SE_SUCCESS); } /*********************************************************************** * *N {S_update_row} - update specified row a table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * update specified row a table *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * <handle> == (SE_CONNECTION) The connection handle. * <table > == (CHAR*) the tabke name * <update_mode> == (S_DM_MODE) update mode: by rowid or by whereclause * <rowid> == (LONG) the row to updated *E ***********************************************************************/ static LONG S_update_row(SE_CONNECTION handle,const CHAR *table, S_DM_MODE update_mode, LONG rowid) { SE_STREAM stream; LONG result,i; SHORT number_of_columns; CHAR **base_columns; CHAR str_val[32]; char ansi_str[32]; SE_INT32 int32_val; SHORT str_ind,int32_ind; CHAR where_clause[128]; number_of_columns = 2; base_columns = (CHAR **) malloc (number_of_columns * sizeof(CHAR *)); for(i=0;i<number_of_columns;i++) base_columns[i]=(CHAR *) malloc (SE_MAX_COLUMN_LEN * sizeof(CHAR)); /* Set up for update. */ strcpy( base_columns[0],"STR_COL"); strcpy( base_columns[1],"INT32_COL"); result = SE_stream_create (handle,&stream); check_rc_return_on_failure (handle,NULL,result,"SE_stream_create"); if(update_mode==S_DM_BY_ROWID){ result = SE_stream_update_row(stream, (const CHAR *)table, (LONG*)&rowid, number_of_columns,(const CHAR **)base_columns); if(result==SE_NO_PERMISSIONS){ SE_stream_free(stream); for(i=0;i<number_of_columns;i++) free(base_columns[i]); free(base_columns); return result; }else check_rc_return_on_failure (NULL,stream,result,"SE_stream_update_row"); }else{ sprintf(ansi_str,"%s = %d","ROWID_COL",rowid); strcpy(where_clause,ansi_str); result = SE_stream_update_table(stream, (const CHAR *)table, number_of_columns, (const CHAR **)base_columns,(const CHAR*)where_clause); if(result==SE_NO_PERMISSIONS){ SE_stream_free(stream); for(i=0;i<number_of_columns;i++) free(base_columns[i]); free(base_columns); return result; }else check_rc_return_on_failure (NULL,stream,result,"SE_stream_update_table"); } result = SE_stream_bind_input_column (stream,1,str_val,&str_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); result = SE_stream_bind_input_column (stream,2,&int32_val,&int32_ind); check_rc_return_on_failure (NULL,stream,result,"SE_stream_bind_input_column"); /* Perform the insert. */ str_ind = SE_IS_NOT_NULL_VALUE; int32_ind = SE_IS_NOT_NULL_VALUE; int32_val=rowid*100; sprintf (ansi_str, "updated row %d",rowid); strcpy(str_val,ansi_str); result = SE_stream_execute (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_execute"); //free resources result = SE_stream_free(stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_free"); for(i=0;i<number_of_columns;i++) free(base_columns[i]); free(base_columns); return(SE_SUCCESS); } /*********************************************************************** * *N {S_delete_rows} - delete specified rows from table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Delete specified rows from test table *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * <handle> == (SE_CONNECTION) The connection handle. * <table > == (CHAR*) the layer name * <delete_mode> == (S_DM_MODE) delete mode: by id list or by whereclause * <delete_count> == (LONG) number of rows to be deleted * <delete_list> == (LONG*) an array of rowids to be deleted *E ***********************************************************************/ static LONG S_delete_rows(SE_CONNECTION connection, const CHAR *table, S_DM_MODE delete_mode, LONG delete_count, const LONG *delete_list) { SE_STREAM stream; LONG result,i; CHAR where[256]; char ansi_str[256]; //delete the rows result = SE_stream_create (connection,&stream); check_rc_return_on_failure (connection,NULL,result,"SE_stream_create"); if (delete_count > 0) { if(delete_mode==S_DM_BY_ROWID){ if(delete_count==1){ result = SE_stream_delete_row (stream,table,delete_list[0]); if(result==SE_NO_PERMISSIONS){ SE_stream_free(stream); return result; }else if(result!= SE_SUCCESS && result!=SE_NO_ROWS_DELETED) check_rc_return_on_failure (NULL,stream,result,"SE_stream_delete_row"); }else{ result = SE_stream_delete_by_id_list (stream,table, (LONG *)delete_list,delete_count); if(result!= SE_SUCCESS && result!=SE_NO_ROWS_DELETED) check_rc_return_on_failure (NULL,stream,result,"SE_stream_delete_by_id_list"); } }else{ sprintf(ansi_str,"%s IN (","ROWID_COL"); for(i=0;i<delete_count;i++){ if(i==0) sprintf(ansi_str,"%s%d",ansi_str,delete_list[i]); else sprintf(ansi_str,"%s,%d",ansi_str,delete_list[i]); } sprintf(ansi_str,"%s)",ansi_str); strcpy(where,ansi_str); result = SE_stream_delete_from_table (stream,table,where); if(result==SE_NO_PERMISSIONS){ SE_stream_free(stream); return result; }else if(result!= SE_SUCCESS && result!=SE_NO_ROWS_DELETED || result==SE_TABLE_NOREGISTERED) check_rc_return_on_failure (NULL,stream,result,"SE_stream_delete_from_table"); } } /* Done, clean up and commit. */ result = SE_stream_free (stream); check_rc_return_on_failure (NULL,stream,result,"SE_stream_free"); /* Done. */ return (SE_SUCCESS); } /*********************************************************************** * *N {S_query_table} : query rows of a table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Query the rows of a table *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * <connection> == (SE_CONNECTION) The connection handle. * <table > == (CHAR*) the result layer name * <where > == (CHAR*) the where clause *E ***********************************************************************/ static LONG S_query_table(SE_CONNECTION connection, const CHAR *table,const CHAR* where){ LONG result,num_of_column,rowid; CHAR **columns; CHAR str_col[32]; SHORT int16_col; SE_INT32 int32_col; FLOAT float32_col; LFLOAT float64_col; struct tm date_col; SHORT str_ind,int16_ind, float32_ind, int32_ind, float64_ind, date_ind,blob_ind, rowid_ind; SE_BLOB_INFO blob_val; SE_QUERYINFO qinfo; SE_STREAM query_stream; LONG feteched_row=0,i; CHAR orderby[128]; char ansi_str[128]; //setup the definition num_of_column = 8; columns = (CHAR **) malloc (num_of_column * sizeof(CHAR *)); for(i=0;i<num_of_column;i++) columns[i]=(CHAR *) malloc (SE_MAX_COLUMN_LEN * sizeof(CHAR)); strcpy( columns[0],"ROWID_COL"); strcpy( columns[1],"STR_COL"); strcpy( columns[2],"INT16_COL"); strcpy( columns[3],"INT32_COL"); strcpy( columns[4],"FLOAT32_COL"); strcpy( columns[5],"FLOAT64_COL"); strcpy( columns[6],"DATE_COL"); strcpy( columns[7],"BLOB_COL"); //setup the query result=SE_stream_create(connection, &query_stream); check_rc_return_on_failure (connection,NULL,result,"SE_stream_create"); result = SE_queryinfo_create(&qinfo); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_create"); result = SE_queryinfo_set_tables (qinfo, 1, &table, NULL); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_tables"); result = SE_queryinfo_set_columns (qinfo, num_of_column, (const CHAR **)columns); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_columns"); result = SE_queryinfo_set_where_clause(qinfo,where); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_where_clause"); strcpy(orderby,"order by INT16_COL"); result = SE_queryinfo_set_by_clause(qinfo,orderby); check_rc_return_on_failure (connection,NULL,result,"SE_queryinfo_set_by_clause"); result = SE_stream_query_with_info (query_stream,qinfo); if(result==SE_TABLE_NOEXIST || result==SE_NO_PERMISSIONS || result==SE_TABLE_NOREGISTERED){ SE_queryinfo_free(qinfo); SE_stream_free(query_stream); for(i=0;i<num_of_column;i++) free(columns[i]); free(columns); return result; }else check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_query_with_info"); // setup the binds blob_val.blob_length = 100000; blob_val.blob_buffer = (char*)malloc(100000); result = SE_stream_bind_output_column (query_stream,1,&rowid,&rowid_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,2,str_col,&str_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,3,&int16_col,&int16_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,4,&int32_col,&int32_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,5,&float32_col,&float32_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,6,&float64_col,&float64_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,7,&date_col,&date_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); result = SE_stream_bind_output_column (query_stream,8,&blob_val,&blob_ind); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_bind_output_column"); // execute the query result = SE_stream_execute (query_stream); check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_execute"); // fetch and print the results while(result==SE_SUCCESS){ result = SE_stream_fetch (query_stream); if(result!=SE_FINISHED){ check_rc_return_on_failure (NULL,query_stream,result,"SE_stream_fetch"); printf("\n----------------------------------------------------------------------\n"); printf("%-10s = %-10d","ROW ID",rowid); printf("%-10s = %-20s\n","STR_COL",str_col); printf("%-10s = %-10d","INT16_COL",int16_col); printf("%-10s = %-20d\n","INIT32_COL",int32_col); printf("%-10s = %-10.1f","FLT32_COL",float32_col); printf("%-10s = %-10.1f\n","FLT64_COL",float64_col); sprintf(ansi_str,"%c%c...",blob_val.blob_buffer[0],blob_val.blob_buffer[1]); printf("%-10s = %-10s","BLOB_COL",ansi_str); } } //free resource free(blob_val.blob_buffer); SE_queryinfo_free(qinfo); SE_stream_free(query_stream); for(i=0;i<num_of_column;i++) free(columns[i]); free(columns); return (SE_SUCCESS); } /*********************************************************************** * *N {check_rc_} - check the returned code * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *P Purpose: * Check returned sde error code and print the error messages. ***********************************************************************/ void check_rc_(SE_CONNECTION Connection, SE_STREAM Stream, LONG rc, char *comment, LONG line_no, char* file_name) { SE_ERROR error; CHAR error_string [SE_MAX_MESSAGE_LENGTH]; LONG temp_rc=SE_FAILURE; if ((rc != SE_SUCCESS) && (rc != SE_FINISHED)) { error_string[0] = '\0'; SE_error_get_string (rc, error_string); printf ("%s encountered a %d error:\"%s\" \nat line %ld in file %s\n",comment, rc,error_string, line_no, file_name); /*Print extended error info, if any */ if ((SE_DB_IO_ERROR == rc) | (SE_INVALID_WHERE == rc) | (SE_SSA_FUNCTION_ERROR == rc)) { if (NULL != Stream) { /* Assume this is a stream error */ temp_rc = SE_stream_get_ext_error (Stream, &error); }else if (NULL != Connection) { /*Assume this is a connection error */ temp_rc = SE_connection_get_ext_error (Connection, &error); } if (SE_SUCCESS == temp_rc) { printf("Extended error code: %d, extended error string:\n%s\n", error.ext_error, error.err_msg1); } } /*End SE_DB_IO_ERROR */ } }