Ignore:
Timestamp:
Jun 11, 2015, 3:07:11 PM (9 years ago)
Author:
djay
Message:

Better concurrency gesture for asynchronous requests, add db backend support for status informations.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/zoo-project/zoo-kernel/sqlapi.c

    r651 r652  
    11/*
    22 * Author : David Saggiorato
    3  *
    4  *  Copyright 2008-2009 GeoLabs SARL. All rights reserved.
     3 *          Gérald Fenoy
     4 *  Copyright 2015 GeoLabs SARL. All rights reserved.
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a copy
     
    2323 */
    2424
     25#ifdef RELY_ON_DB
     26#include "ogr_api.h"
     27#include "ogrsf_frmts.h"
     28#include "ogr_p.h"
     29
    2530#include "sqlapi.h"
    2631#include <fcgi_stdio.h>
    27 #include <uuid/uuid.h>
    2832#include <stdlib.h>
    2933
    3034/**
    31  * Generate a UUID.
    32  * ref: https://www.ietf.org/rfc/rfc4122.txt / 4.2
    33  *
    34  * @return a new char* containing the UUID, make sure to free the returned ressource
    35  * once used.
    36  */
    37 char *get_uuid(){
    38   char *res=(char*)malloc(37*sizeof(char));
    39   uuid_t uuid;
    40   uuid_generate_time(uuid);
    41   char * rest;
    42   uuid_unparse(uuid,rest);
    43   sprintf(res,"%s", rest);
     35 * Global GDALDataset pointer
     36 */
     37OGRDataSource *zoo_DS = NULL;
     38
     39/**
     40 * Global OGRLayer pointer pointing to the lastest result set
     41 */
     42OGRLayer *zoo_ResultSet = NULL;
     43
     44/**
     45 * Create a GDAL / OGR string for connecting to the db backend
     46 * (do not support active_schema)
     47 *
     48 * @param conf the maps containing the setting of the main.cfg file
     49 */
     50char* createInitString(maps* conf){
     51  char* res=NULL;
     52  char keywords[5][9]={
     53    "dbname",
     54    "host",
     55    "port",
     56    "user",
     57    "password"
     58  };
     59  int i=0;
     60  maps* cconf=getMaps(conf,"database");
     61  int len=0;
     62  for(i=0;i<5;i++){
     63    map* tmp=getMap(cconf->content,keywords[i]);
     64    if(tmp!=NULL){
     65      if(res==NULL){
     66        res=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+4)*sizeof(char));
     67        sprintf(res,"%s='%s'",keywords[i],tmp->value);
     68        len+=strlen(res);
     69      }else{
     70        char* res1=(char*)malloc((strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
     71        sprintf(res1," %s='%s'",keywords[i],tmp->value);
     72        res=(char*)realloc(res,(len+strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
     73        memcpy(res+len,res1,(strlen(keywords[i])+strlen(tmp->value)+5)*sizeof(char));
     74        len+=strlen(res1);
     75        res[len]=0;
     76        free(res1);
     77      }
     78    }
     79  }
     80  map* tmp=getMap(cconf->content,"type");
     81  if(tmp!=NULL){
     82    char* fres=(char*)malloc((strlen(res)+strlen(tmp->value)+2)*sizeof(char));
     83    sprintf(fres,"%s:%s",tmp->value,res);
     84    free(res);
     85    return fres;
     86  }
    4487  return res;
    4588}
     89
     90/**
     91 * Connect to the db backend.
     92 *
     93 * @param conf the maps containing the setting of the main.cfg file
     94 * @see createInitString
     95 */
     96void init_sql(maps* conf){
     97  char* sqlInitString=createInitString(conf);
     98  OGRSFDriver *poDriver = NULL;
     99  OGRRegisterAll();
     100  zoo_DS = OGRSFDriverRegistrar::Open(sqlInitString,false,&poDriver);
     101  if( zoo_DS == NULL ){
     102#ifdef DEBUG
     103    fprintf(stderr,"sqlInitString: %s FAILED !\n",sqlInitString);
     104    fflush(stderr);
     105#endif
     106    free(sqlInitString);
     107    setMapInMaps(conf,"lenv","message","Failed to connect to the database backend");
     108    return;
     109  }
     110#ifdef DEBUG
     111  fprintf(stderr,"sqlInitString: %s SUCEED !\n",sqlInitString);
     112  fflush(stderr);
     113#endif
     114  free(sqlInitString);
     115}
     116
     117/**
     118 * Close any connection to the db backend.
     119 *
     120 * @param conf the maps containing the setting of the main.cfg file
     121 */
     122void close_sql(maps* conf){
     123  if( zoo_ResultSet != NULL )
     124    zoo_DS->ReleaseResultSet( zoo_ResultSet );
     125  if(zoo_DS!=NULL){
     126    OGRDataSource::DestroyDataSource( zoo_DS );
     127    zoo_DS=NULL;
     128  }
     129}
     130
     131/**
     132 * Call OGRCleanupAll.
     133 *
     134 */
     135void end_sql(){
     136  OGRCleanupAll();
     137}
     138
     139/**
     140 * Execute a SQL query to the SQL Database Backend.
     141 *
     142 * @param conf the maps containing the setting of the main.cfg file
     143 * @param sqlQuery the SQL query to run
     144 * @return -1 in case of failure and 1 if the query succeed.
     145 */
     146int execSql(maps* conf,const char* sqlQuery){
     147  zoo_ResultSet = zoo_DS->ExecuteSQL( sqlQuery, NULL, NULL);
     148  if( zoo_ResultSet != NULL ){
     149    return 1;
     150  }
     151  return -1;
     152}
     153
     154/**
     155 * Clean any memory allocated by executing a request
     156 *
     157 * @param conf the maps containing the setting of the main.cfg file
     158 * @param sqlQuery the SQL query to run
     159 * @return -1 in case of failure and 1 if the query succeed.
     160 */
     161void cleanUpResultSet(const maps* conf){
     162  if( zoo_ResultSet != NULL ){
     163    zoo_DS->ReleaseResultSet( zoo_ResultSet );
     164    zoo_ResultSet=NULL;
     165  }
     166}
     167
     168/**
     169 * Record a file stored during ZOO-Kernel execution
     170 *
     171 * @param conf the maps containing the setting of the main.cfg file
     172 * @param filename the file's name
     173 * @param type the type (Intput,Output,Response)
     174 * @param name the maps containing the setting of the main.cfg file
     175 */
     176void recordStoredFile(maps* conf,const char* filename,const char* type,const char* name){
     177  map *uusid=getMapFromMaps(conf,"lenv","usid");
     178  map *schema=getMapFromMaps(conf,"database","schema");
     179  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(uusid->value)+strlen(filename)+strlen(type)+(name!=NULL?strlen(name):2)+68+1)*sizeof(char));
     180  if(name!=NULL)
     181    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s','%s');",schema->value,uusid->value,filename,type,name);
     182  else
     183    sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s',NULL);",schema->value,uusid->value,filename,type);
     184  execSql(conf,sqlQuery);
     185  cleanUpResultSet(conf);
     186}
     187
     188/**
     189 * Insert the reference tuple corresponding to the running service
     190 *
     191 * @param conf the maps containing the setting of the main.cfg file
     192 */
     193void recordServiceStatus(maps* conf){
     194  map *sid=getMapFromMaps(conf,"lenv","sid");
     195  map *osid=getMapFromMaps(conf,"lenv","osid");
     196  map *uusid=getMapFromMaps(conf,"lenv","usid");
     197  map *schema=getMapFromMaps(conf,"database","schema");
     198  char *sqlQuery=(char*)malloc((strlen(schema->value)+
     199                                strlen(uusid->value)+
     200                                strlen(osid->value)+
     201                                strlen(sid->value)+56+1)*sizeof(char));
     202  sprintf(sqlQuery,
     203          "INSERT INTO %s.services (uuid,sid,osid)"
     204          "VALUES ('%s','%s','%s');",
     205          schema->value,
     206          uusid->value,sid->value,osid->value);
     207  execSql(conf,sqlQuery);
     208  cleanUpResultSet(conf);
     209}
     210
     211/**
     212 * Store the content of the result file
     213 *
     214 * @param conf the maps containing the setting of the main.cfg file
     215 * @param filename the file's name
     216 */
     217void recordResponse(maps* conf,char* filename){
     218  FILE *file = fopen (filename, "rb");
     219  fseek (file, 0, SEEK_END);
     220  long flen = ftell (file);
     221  fseek (file, 0, SEEK_SET);
     222  char *tmps = (char *) malloc ((flen + 1) * sizeof (char));
     223  fread (tmps, flen, 1, file);
     224  tmps[flen]=0;
     225  fclose(file);
     226  map *sid=getMapFromMaps(conf,"lenv","usid");
     227  map *schema=getMapFromMaps(conf,"database","schema");
     228  char *sqlQuery=(char*)malloc((strlen(schema->value)+flen+strlen(sid->value)+51+1)*sizeof(char));
     229  sprintf(sqlQuery,"UPDATE %s.services set response=$$%s$$ where uuid=$$%s$$;",schema->value,tmps,sid->value);
     230  execSql(conf,sqlQuery);
     231  cleanUpResultSet(conf);
     232}
     233
     234/**
     235 * Update the current status of the running service.
     236 *
     237 * @param conf the map containing the setting of the main.cfg file
     238 * @return 0 on success, -2 if shmget failed, -1 if shmat failed
     239 */
     240int _updateStatus(maps* conf){
     241  map *sid=getMapFromMaps(conf,"lenv","usid");
     242  map *p=getMapFromMaps(conf,"lenv","status");
     243  map *msg=getMapFromMaps(conf,"lenv","message");
     244  map *schema=getMapFromMaps(conf,"database","schema");
     245  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
     246  sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
     247  fflush(stderr);
     248  if( zoo_DS == NULL )
     249    init_sql(conf);
     250  execSql(conf,sqlQuery);
     251  cleanUpResultSet(conf);
     252  return 0;
     253}
     254
     255/**
     256 * Get the ongoing status of a running service
     257 *
     258 * @param conf the maps containing the setting of the main.cfg file
     259 * @param pid the service identifier (usid key from the [lenv] section)
     260 * @return the reported status char* (MESSAGE|POURCENTAGE)
     261 */
     262char* _getStatus(maps* conf,char* pid){
     263  map *schema=getMapFromMaps(conf,"database","schema");
     264  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
     265  sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
     266  if( zoo_DS == NULL )
     267    init_sql(conf);
     268  execSql(conf,sqlQuery);
     269  OGRFeature  *poFeature = NULL;
     270  const char *tmp1;
     271  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
     272    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
     273      if( poFeature->IsFieldSet( iField ) ){
     274        tmp1=strdup(poFeature->GetFieldAsString( iField ));
     275      }
     276      else
     277        tmp1=NULL;
     278    }
     279    OGRFeature::DestroyFeature( poFeature );
     280  }
     281  cleanUpResultSet(conf);
     282  return (char*)tmp1;
     283}
     284
     285/**
     286 * Read the cache file of a running service
     287 *
     288 * @param conf the maps containing the setting of the main.cfg file
     289 * @param pid the service identifier (usid key from the [lenv] section)
     290 * @return the reported status char* (temporary/final result)
     291 */
     292char* _getStatusFile(maps* conf,char* pid){
     293  map *schema=getMapFromMaps(conf,"database","schema");
     294  char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
     295  sprintf(sqlQuery,"select response from %s.services where uuid=$$%s$$;",schema->value,pid);
     296  if( zoo_DS == NULL )
     297    init_sql(conf);
     298  execSql(conf,sqlQuery);
     299  OGRFeature  *poFeature = NULL;
     300  const char *tmp1;
     301  int hasRes=-1;
     302  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
     303    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
     304      if( poFeature->IsFieldSet( iField ) ){
     305        tmp1=strdup(poFeature->GetFieldAsString( iField ));
     306        hasRes=1;
     307      }
     308      else
     309        tmp1=NULL;
     310    }
     311    OGRFeature::DestroyFeature( poFeature );
     312  }
     313  if(hasRes<0)
     314    tmp1=NULL;
     315  cleanUpResultSet(conf);
     316  return (char*)tmp1;
     317}
     318
     319/**
     320 * Stop handling status repport.
     321 *
     322 * @param conf the map containing the setting of the main.cfg file
     323 */
     324void unhandleStatus(maps* conf){
     325  map *sid=getMapFromMaps(conf,"lenv","usid");
     326  char *sqlQuery=(char*)malloc((strlen(sid->value)+52+1)*sizeof(char));
     327  sprintf(sqlQuery,"UPDATE services set end_time=now() where uuid=$$%s$$;",sid->value);
     328  execSql(conf,sqlQuery);
     329  cleanUpResultSet(conf);
     330  close_sql(conf);
     331  end_sql();
     332}
     333
     334#endif
Note: See TracChangeset for help on using the changeset viewer.

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png