Index: trunk/zoo-project/zoo-kernel/sqlapi.c
===================================================================
--- trunk/zoo-project/zoo-kernel/sqlapi.c	(revision 786)
+++ trunk/zoo-project/zoo-kernel/sqlapi.c	(revision 917)
@@ -1,5 +1,5 @@
 /*
- * Author : David Saggiorato
- *          Gérald Fenoy
+ * Authors : David Saggiorato
+ *           Gérald Fenoy
  *  Copyright 2015 GeoLabs SARL. All rights reserved.
  *
@@ -23,5 +23,4 @@
  */
 
-#ifdef RELY_ON_DB
 #include "ogr_api.h"
 #include "ogrsf_frmts.h"
@@ -44,5 +43,5 @@
 OGRDataSource 
 #endif
- *zoo_DS = NULL;
+ **zoo_DS = NULL;
 
 /**
@@ -52,22 +51,29 @@
 
 /**
- * Create a GDAL / OGR string for connecting to the db backend
- * (do not support active_schema)
- * 
- * @param conf the maps containing the setting of the main.cfg file
- */
-char* createInitString(maps* conf){
+ * Create a GDAL / OGR string for connecting to a db backend defined in the
+ * key section.
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param key the name of the section containing the connection setting
+ * @return the OGR connection string
+ */
+char* _createInitString(maps* conf,const char* key){
   char* res=NULL;
-  char keywords[5][9]={
+  char keywords[6][14]={
     "dbname",
     "host",
     "port",
     "user",
-    "password"
+    "password",
+    "active_schema"    
   };
   int i=0;
-  maps* cconf=getMaps(conf,"database");
+  maps* cconf=getMaps(conf,key);
+  if(cconf==NULL){
+    fprintf(stderr,"%s %d\n",__FILE__,__LINE__);
+    return "-1";
+  }
   int len=0;
-  for(i=0;i<5;i++){
+  for(i=0;i<6;i++){
     map* tmp=getMap(cconf->content,keywords[i]);
     if(tmp!=NULL){
@@ -98,35 +104,91 @@
 
 /**
- * Connect to the db backend.
+ * Create a GDAL / OGR string for connecting to the db backend
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @return the OGR connection string
+ */
+char* createInitString(maps* conf){
+  return _createInitString(conf,"database");
+}
+
+/**
+ * Connect to a db backend.
  * 
  * @param conf the maps containing the setting of the main.cfg file
  * @see createInitString
  */
-void init_sql(maps* conf){
-  char* sqlInitString=createInitString(conf);
+int _init_sql(maps* conf,const char* key){
+  char* sqlInitString=_createInitString(conf,key);
+#ifdef SQL_DEBUG
+  fprintf(stderr,"Try to connect to: %s %s !\n",key,sqlInitString);
+  fflush(stderr);  
+#endif
+  if(strncmp(sqlInitString,"-1",2)==0)
+    return -1;
   OGRSFDriver *poDriver = NULL;
   OGRRegisterAll();
-
+  int zoo_ds_nb=0;
+  map* dsNb=getMapFromMaps(conf,"lenv","ds_nb");
+  if(dsNb==NULL){
+    setMapInMaps(conf,"lenv","ds_nb","1");
+  }else{
+    zoo_ds_nb=atoi(dsNb->value);
+    char* tmp=(char*)malloc(11*sizeof(char));
+    sprintf(tmp,"%d",zoo_ds_nb+1);
+    setMapInMaps(conf,"lenv","ds_nb",(const char*)tmp);
+    free(tmp);
+  }
+  if(zoo_DS==NULL)
+    zoo_DS=
 #if GDAL_VERSION_MAJOR >= 2
-  zoo_DS = (GDALDataset*) GDALOpenEx( sqlInitString,
+      (GDALDataset**) malloc(sizeof(GDALDataset*))
+#else
+      (OGRDataSource**) malloc(sizeof(OGRDataSource*))
+#endif
+      ;
+  else
+    zoo_DS=      
+#if GDAL_VERSION_MAJOR >= 2
+      (GDALDataset**)realloc(zoo_DS,(zoo_ds_nb+1)*sizeof(GDALDataset*))
+#else
+      (OGRDataSource**)realloc(zoo_DS,(zoo_ds_nb+1)*sizeof(OGRDataSource*))
+#endif
+      ;
+  
+#if GDAL_VERSION_MAJOR >= 2
+  zoo_DS[zoo_ds_nb] = (GDALDataset*) GDALOpenEx( sqlInitString,
 				      GDAL_OF_UPDATE | GDAL_OF_VECTOR,
 				      NULL, NULL, NULL );
 #else
-  zoo_DS = OGRSFDriverRegistrar::Open(sqlInitString,false,&poDriver);
-#endif
-  if( zoo_DS == NULL ){
-#ifdef DEBUG
+  zoo_DS[zoo_ds_nb] = OGRSFDriverRegistrar::Open(sqlInitString,false,&poDriver);
+#endif
+  if( zoo_DS[zoo_ds_nb] == NULL ){
+#ifdef SQL_DEBUG
     fprintf(stderr,"sqlInitString: %s FAILED !\n",sqlInitString);
     fflush(stderr);
 #endif
     free(sqlInitString);
-    setMapInMaps(conf,"lenv","message","Failed to connect to the database backend");
-    return;
-  }
-#ifdef DEBUG
+    setMapInMaps(conf,"lenv","dbIssue","1");
+    setMapInMaps(conf,"lenv","message",_("Failed to connect to the database backend"));
+    return -2;
+  }
+#ifdef SQL_DEBUG
   fprintf(stderr,"sqlInitString: %s SUCEED !\n",sqlInitString);
   fflush(stderr);
 #endif
   free(sqlInitString);
+  zoo_ds_nb++;
+  return zoo_ds_nb;
+}
+
+/**
+ * Connect to the db backend.
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @see createInitString
+ */
+int init_sql(maps* conf){
+  return _init_sql(conf,"database");
 }
 
@@ -136,14 +198,16 @@
  * @param conf the maps containing the setting of the main.cfg file
  */
-void close_sql(maps* conf){
-  if( zoo_ResultSet != NULL )
-    zoo_DS->ReleaseResultSet( zoo_ResultSet );
-  if(zoo_DS!=NULL){
+void close_sql(maps* conf,int cid){
+  if( zoo_ResultSet != NULL ){
+    zoo_DS[cid]->ReleaseResultSet( zoo_ResultSet );
+    zoo_ResultSet=NULL;
+  }
+  if(zoo_DS!=NULL && zoo_DS[cid]!=NULL){
 #if GDAL_VERSION_MAJOR >= 2
-    GDALClose(zoo_DS);
-#else
-    OGRDataSource::DestroyDataSource( zoo_DS );
-#endif
-    zoo_DS=NULL;
+    GDALClose(zoo_DS[cid]);
+#else
+    OGRDataSource::DestroyDataSource( zoo_DS[cid] );
+#endif
+    zoo_DS[cid]=NULL;
   }
 }
@@ -158,4 +222,30 @@
 
 /**
+ * Fetch a tuple set by executing a SQL query to the Database Backend.
+ * 
+ * @param conf the maps containing the setting of the main.cfg file
+ * @param sqlQuery the SQL query to run
+ * @return NULL in case of failure or an OGRLayer pointer if the query succeed.
+ */
+OGRLayer *fetchSql(maps* conf,int cid,const char* sqlQuery){
+  if(zoo_DS==NULL || zoo_DS[cid]==NULL)
+    return NULL;
+  OGRLayer *res=NULL;
+#ifdef SQL_DEBUG
+  fprintf(stderr,"************************* %s %s %d\n\n",sqlQuery,__FILE__,__LINE__);
+  fflush(stderr);
+#endif
+  res = zoo_DS[cid]->ExecuteSQL( sqlQuery, NULL, NULL);
+  return res;
+}
+
+void cleanFetchSql(maps* conf,int cid,OGRLayer *objects){
+  if( objects != NULL ){
+    zoo_DS[cid]->ReleaseResultSet( objects );
+    objects=NULL;
+  }
+}
+
+/**
  * Execute a SQL query to the SQL Database Backend.
  * 
@@ -164,10 +254,13 @@
  * @return -1 in case of failure and 1 if the query succeed.
  */
-int execSql(maps* conf,const char* sqlQuery){
-  zoo_ResultSet = zoo_DS->ExecuteSQL( sqlQuery, NULL, NULL);
+int execSql(maps* conf,int cid,const char* sqlQuery){
+  int res=-1;
+  if(zoo_DS == NULL || zoo_DS[cid]==NULL)
+    return -1;
+  zoo_ResultSet = zoo_DS[cid]->ExecuteSQL( sqlQuery, NULL, NULL);
   if( zoo_ResultSet != NULL ){
-    return 1;
-  }
-  return -1;
+    res=1;
+  }
+  return res;
 }
 
@@ -179,9 +272,18 @@
  * @return -1 in case of failure and 1 if the query succeed.
  */
-void cleanUpResultSet(const maps* conf){
+void cleanUpResultSet(const maps* conf,int cid){
   if( zoo_ResultSet != NULL ){
-    zoo_DS->ReleaseResultSet( zoo_ResultSet );
+    zoo_DS[cid]->ReleaseResultSet( zoo_ResultSet );
     zoo_ResultSet=NULL;
   }
+}
+
+#ifdef RELY_ON_DB
+int getCurrentId(maps* conf){
+  int res=0;
+  map* dsNb=getMapFromMaps(conf,"lenv","ds_nb");
+  if(dsNb!=NULL)
+    res=atoi(dsNb->value);
+  return res;
 }
 
@@ -195,4 +297,5 @@
  */
 void recordStoredFile(maps* conf,const char* filename,const char* type,const char* name){
+  int zoo_ds_nb=getCurrentId(conf);
   map *uusid=getMapFromMaps(conf,"lenv","usid");
   map *schema=getMapFromMaps(conf,"database","schema");
@@ -202,7 +305,7 @@
   else
     sprintf(sqlQuery,"INSERT INTO %s.files (uuid,filename,nature,name) VALUES ('%s','%s','%s',NULL);",schema->value,uusid->value,filename,type);
-  execSql(conf,sqlQuery);
-  free(sqlQuery);
-  cleanUpResultSet(conf);
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
+  free(sqlQuery);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
 }
 
@@ -213,4 +316,5 @@
  */
 void recordServiceStatus(maps* conf){
+  int zoo_ds_nb=getCurrentId(conf);
   map *sid=getMapFromMaps(conf,"lenv","sid");
   map *osid=getMapFromMaps(conf,"lenv","osid");
@@ -230,7 +334,7 @@
 	  osid->value,
 	  wpsStatus[2]);
-  execSql(conf,sqlQuery);
-  free(sqlQuery);
-  cleanUpResultSet(conf);
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
+  free(sqlQuery);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
 }
 
@@ -242,4 +346,5 @@
  */
 void recordResponse(maps* conf,char* filename){
+  int zoo_ds_nb=getCurrentId(conf);
   FILE *file = fopen (filename, "rb");
   fseek (file, 0, SEEK_END);
@@ -254,8 +359,8 @@
   char *sqlQuery=(char*)malloc((strlen(schema->value)+flen+strlen(sid->value)+57+1)*sizeof(char));
   sprintf(sqlQuery,"INSERT INTO %s.responses (content,uuid) VALUES ($$%s$$,$$%s$$);",schema->value,tmps,sid->value);
-  execSql(conf,sqlQuery);
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
   free(sqlQuery);
   free(tmps);
-  cleanUpResultSet(conf);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
 }
 
@@ -267,4 +372,5 @@
  */
 int _updateStatus(maps* conf){
+  int zoo_ds_nb=getCurrentId(conf);
   map *sid=getMapFromMaps(conf,"lenv","usid");
   map *p=getMapFromMaps(conf,"lenv","status");
@@ -273,9 +379,10 @@
   char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(msg->value)+strlen(p->value)+strlen(sid->value)+64+1)*sizeof(char));
   sprintf(sqlQuery,"UPDATE %s.services set status=$$%s$$,message=$$%s$$ where uuid=$$%s$$;",schema->value,p->value,msg->value,sid->value);
-  fflush(stderr);
-  if( zoo_DS == NULL )
+  if( zoo_DS == NULL || zoo_DS[zoo_ds_nb-1]==NULL ){
     init_sql(conf);
-  execSql(conf,sqlQuery);
-  cleanUpResultSet(conf);
+    zoo_ds_nb++;
+  }
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   free(sqlQuery);
   return 0;
@@ -290,10 +397,21 @@
  */
 char* _getStatus(maps* conf,char* pid){
+  int zoo_ds_nb=getCurrentId(conf);
+  int created=-1;
   map *schema=getMapFromMaps(conf,"database","schema");
   char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
   sprintf(sqlQuery,"select status||'|'||message from %s.services where uuid=$$%s$$;",schema->value,pid);
-  if( zoo_DS == NULL )
+  if( zoo_ds_nb==
+#ifdef META_DB
+      1
+#else
+      0
+#endif
+      ){
     init_sql(conf);
-  execSql(conf,sqlQuery);
+    zoo_ds_nb++;
+    created=1;
+  }
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
   OGRFeature  *poFeature = NULL;
   const char *tmp1;
@@ -301,5 +419,5 @@
     for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
       if( poFeature->IsFieldSet( iField ) ){
-	tmp1=strdup(poFeature->GetFieldAsString( iField ));
+	tmp1=zStrdup(poFeature->GetFieldAsString( iField ));
       }
       else
@@ -308,5 +426,5 @@
     OGRFeature::DestroyFeature( poFeature );
   }
-  cleanUpResultSet(conf);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   free(sqlQuery);
   return (char*)tmp1;
@@ -321,29 +439,40 @@
  */
 char* _getStatusFile(maps* conf,char* pid){
-  map *schema=getMapFromMaps(conf,"database","schema");
+  int zoo_ds_nb=getCurrentId(conf);
+  map *schema=getMapFromMaps(conf,"database","schema");
+  OGRFeature  *poFeature = NULL;
+  const char *tmp1=NULL;
+  int hasRes=-1;
   char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+82+1)*sizeof(char));
   sprintf(sqlQuery,
 	  "select content from %s.responses where uuid=$$%s$$"
 	  " order by creation_time desc limit 1",schema->value,pid);
-  if( zoo_DS == NULL )
+  if( zoo_ds_nb==
+#ifdef META_DB
+      1
+#else
+      0
+#endif
+      ){
     init_sql(conf);
-  execSql(conf,sqlQuery);
-  OGRFeature  *poFeature = NULL;
-  const char *tmp1;
-  int hasRes=-1;
-  while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
-    for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
-      if( poFeature->IsFieldSet( iField ) ){
-	tmp1=strdup(poFeature->GetFieldAsString( iField ));
-	hasRes=1;
+    zoo_ds_nb++;
+  }
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
+  if(zoo_ResultSet!=NULL){
+      while( (poFeature = zoo_ResultSet->GetNextFeature()) != NULL ){
+	for( int iField = 0; iField < poFeature->GetFieldCount(); iField++ ){
+	  if( poFeature->IsFieldSet( iField ) ){
+	    tmp1=zStrdup(poFeature->GetFieldAsString( iField ));
+	    hasRes=1;
+	  }
+	  else
+	    tmp1=NULL;
+	}
+	OGRFeature::DestroyFeature( poFeature );
       }
-      else
-	tmp1=NULL;
-    }
-    OGRFeature::DestroyFeature( poFeature );
   }
   if(hasRes<0)
     tmp1=NULL;
-  cleanUpResultSet(conf);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   free(sqlQuery);
   return (char*)tmp1;
@@ -357,16 +486,25 @@
  */
 void removeService(maps* conf,char* pid){
+  int zoo_ds_nb=getCurrentId(conf);
   map *schema=getMapFromMaps(conf,"database","schema");
   char *sqlQuery=(char*)
     malloc((strlen(pid)+strlen(schema->value)+38+1)
 	   *sizeof(char));
-  if( zoo_DS == NULL )
+  if( zoo_ds_nb==
+#ifdef META_DB
+      1
+#else
+      0
+#endif
+      ){
     init_sql(conf);
+    zoo_ds_nb++;
+  }
   sprintf(sqlQuery,
 	  "DELETE FROM %s.services where uuid=$$%s$$;",
 	  schema->value,pid);
-  execSql(conf,sqlQuery);
-  cleanUpResultSet(conf);
-  close_sql(conf);
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
+  close_sql(conf,zoo_ds_nb-1);
   free(sqlQuery);
   end_sql();
@@ -379,4 +517,5 @@
  */
 void unhandleStatus(maps* conf){
+  int zoo_ds_nb=getCurrentId(conf);
   map *schema=getMapFromMaps(conf,"database","schema");
   map *sid=getMapFromMaps(conf,"lenv","usid");
@@ -392,9 +531,9 @@
 	  " where uuid=$$%s$$;",
 	  schema->value,(fstate!=NULL?fstate->value:"Failed"),sid->value);
-  execSql(conf,sqlQuery);
-  cleanUpResultSet(conf);
-  close_sql(conf);
-  free(sqlQuery);
-  end_sql();
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
+  //close_sql(conf,zoo_ds_nb-1);
+  free(sqlQuery);
+  //end_sql();
 }
 
@@ -407,4 +546,5 @@
  */
 char* getStatusId(maps* conf,char* pid){
+  int zoo_ds_nb=getCurrentId(conf);
   map *schema=getMapFromMaps(conf,"database","schema");
   char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
@@ -412,7 +552,10 @@
 	  "select osid from %s.services where uuid=$$%s$$",
 	  schema->value,pid);
-  if( zoo_DS == NULL )
+  if( zoo_ds_nb==0 ){
     init_sql(conf);
-  execSql(conf,sqlQuery);
+    zoo_ds_nb++;
+  }
+  if(execSql(conf,zoo_ds_nb-1,sqlQuery)<0)
+    return NULL;
   OGRFeature  *poFeature = NULL;
   const char *tmp1;
@@ -431,4 +574,5 @@
     tmp1=NULL;
   free(sqlQuery);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   return (char*)tmp1;
 }
@@ -441,4 +585,5 @@
  */
 void readFinalRes(maps* conf,char* pid,map* statusInfo){
+  int zoo_ds_nb=getCurrentId(conf);
   map *schema=getMapFromMaps(conf,"database","schema");
   char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+58+1)*sizeof(char));
@@ -448,5 +593,5 @@
   if( zoo_DS == NULL )
     init_sql(conf);
-  execSql(conf,sqlQuery);
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
   OGRFeature  *poFeature = NULL;
   int hasRes=-1;
@@ -461,4 +606,5 @@
     OGRFeature::DestroyFeature( poFeature );
   }
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   if(hasRes<0)
     addToMap(statusInfo,"Status","Failed");
@@ -476,10 +622,13 @@
 int isRunning(maps* conf,char* pid){
   int res=0;
+  int zoo_ds_nb=getCurrentId(conf);
   map *schema=getMapFromMaps(conf,"database","schema");
   char *sqlQuery=(char*)malloc((strlen(schema->value)+strlen(pid)+73+1)*sizeof(char));
   sprintf(sqlQuery,"select count(*) as t from %s.services where uuid=$$%s$$ and end_time is null;",schema->value,pid);
-  if( zoo_DS == NULL )
+  if( zoo_ds_nb == 0 ){
     init_sql(conf);
-  execSql(conf,sqlQuery);
+    zoo_ds_nb++;
+  }
+  execSql(conf,zoo_ds_nb-1,sqlQuery);
   OGRFeature  *poFeature = NULL;
   const char *tmp1;
@@ -494,5 +643,5 @@
     OGRFeature::DestroyFeature( poFeature );
   }
-  cleanUpResultSet(conf);
+  cleanUpResultSet(conf,zoo_ds_nb-1);
   free(sqlQuery);
   return res;
