Index: fdo/trunk/Providers/PostGIS/Inc/PostGIS/Override/ClassDefinition.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Inc/PostGIS/Override/ClassDefinition.h	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Inc/PostGIS/Override/ClassDefinition.h	(working copy)
@@ -67,6 +67,10 @@
     // ClassDefinition custom interface
     //
 
+    /// ticket #310 - class naming convention wihout ~ - eric barby
+    /// Set schema name (physical schame of postgres).
+    FDOPOSTGIS_API void SetSchemaName(FdoString* value);
+
     /// Get name of schema (FDO datastore).
     /// The name is NOT wrapped with quotes here.
     FDOPOSTGIS_API FdoStringP GetSchemaName() const;
@@ -104,6 +108,10 @@
 private:
 
     typedef FdoPhysicalClassMapping BaseType;
+
+    /// ticket #310 - class naming convention wihout ~ - eric barby
+    /// The schema of this element
+    FdoStringP    m_schema;
     
     PropertyDefinitionCollection::Ptr mProperties;
 };
Index: fdo/trunk/Providers/PostGIS/Src/Overrides/ClassDefinition.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Overrides/ClassDefinition.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Overrides/ClassDefinition.cpp	(working copy)
@@ -98,6 +98,12 @@
 // ClassDefinition custom interface
 ///////////////////////////////////////////////////////////////////////////////
 
+//ticket #310 - class naming convention wihout ~ - eric barby
+void ClassDefinition::SetSchemaName(FdoString* value)
+{
+  m_schema = value;
+}
+
 FdoStringP ClassDefinition::GetSchemaName() const
 {
     // NOTE: We need this dirty const_cast hack due to lack of
@@ -105,13 +111,17 @@
     // This note also applies to functions below.
 
     FdoStringP name(const_cast<ClassDefinition*>(this)->GetName());
-    return name.Left(L"~");
+    /// ticket #310 - class naming convention wihout ~ - eric barby
+    /// return name.Left(L"~");
+    return m_schema;
 }
 
 FdoStringP ClassDefinition::GetTableName() const
 {
     FdoStringP name(const_cast<ClassDefinition*>(this)->GetName());
-    return name.Right(L"~");
+    /// ticket #310 - class naming convention wihout ~ - eric barby
+    /// return name.Right(L"~");
+    return name;
 }
 
 FdoStringP ClassDefinition::GetTablePath() const
@@ -119,9 +129,18 @@
     FdoStringP schema(const_cast<ClassDefinition*>(this)->GetSchemaName());
     FdoStringP table(const_cast<ClassDefinition*>(this)->GetTableName());
 
-    FdoStringP path = FdoStringP::Format(L"\"%s\".\"%s\"",
-        static_cast<FdoString*>(schema), static_cast<FdoString*>(table));
-
+    /// ticket #310 - class naming convention wihout ~ - eric barby
+    /// just in case schema is empty
+    FdoStringP path;
+    if (schema.GetLength() && table.GetLength()) 
+    {
+      path = FdoStringP::Format(L"\"%s\".\"%s\"",
+          static_cast<FdoString*>(schema), static_cast<FdoString*>(table));
+    } 
+    else
+    {
+      path = table;
+    }
     return path;
 }
 
Index: fdo/trunk/Providers/PostGIS/Src/Provider/ApplySchemaCommand.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/ApplySchemaCommand.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/ApplySchemaCommand.cpp	(working copy)
@@ -52,8 +52,10 @@
 
 void ApplySchemaCommand::SetFeatureSchema(FdoFeatureSchema* schema)
 {
+  if (mFeatureSchema != schema) {
     mFeatureSchema = schema;
     FDO_SAFE_ADDREF(mFeatureSchema.p);
+  }
 }
 
 FdoPhysicalSchemaMapping* ApplySchemaCommand::GetPhysicalMapping()
@@ -78,6 +80,29 @@
     mIgnoreStates = ignoreStates;
 }
 
+ov::ClassDefinition* ApplySchemaCommand::GetClassDefinition(FdoStringP className) const
+{
+    ov::ClassDefinition* phClass = NULL;
+    try {
+      FdoPtr<FdoIdentifier> cid(FdoIdentifier::Create(className));
+      SchemaDescription*  schemaDesc = mConn->DescribeSchema();
+      if (schemaDesc && schemaDesc->IsDescribed()) 
+      {
+        phClass = schemaDesc->FindClassMapping(cid);
+      }
+    }
+    catch (FdoException* e)
+    {
+      FDOLOG_WRITE(L"ERROR: Describe operation for '%s' failed. %s"
+          , static_cast<FdoString*>(className)
+          , e->ToString());
+
+      phClass = NULL;
+      e->Release();
+    }
+    return phClass;
+}
+
 void ApplySchemaCommand::Execute()
 {
     FDOLOG_MARKER("ApplySchemaCommand::+Execute");
@@ -92,134 +117,305 @@
     //
     // Read and parse feature classes to SQL commands
     //
+  {
+
     FdoPtr<FdoClassCollection> featureClasses(mFeatureSchema->GetClasses());
-
     FdoInt32 const classesSize = featureClasses->GetCount();
+    // eric barby
+    // First pass to check if table exist before creating it
+    // or to check if table is empty before dropping it
     for (FdoInt32 i = 0; i < classesSize; i++)
     {
         FdoPtr<FdoClassDefinition> classDef(featureClasses->GetItem(i));
-        FdoPtr<FdoPropertyDefinitionCollection> props(classDef->GetProperties());
+        switch ( classDef->GetElementState() )
+         {
+         case FdoSchemaElementState_Added:
+           //eric barby - test if table exist before creating it
+           if (!TestingCreateTable(GetClassDefinition(classDef->GetName()))) {
+              FdoStringP msg = FdoStringP::Format(L"[PostGIS] ApplySchemaCommand: Add class error! class '%s' already exist!", classDef->GetName());
+              FDOLOG_WRITE("ERROR: %s", static_cast<FdoString*>(msg));
+              throw FdoCommandException::Create(msg);
+           }
+           break;
+         //ticket #106 - cannot delete a feature class - eric barby
+         case FdoSchemaElementState_Deleted:
+           //eric barby - test if table is empty before dropping it
+           if (!TestingDropTable(GetClassDefinition(classDef->GetName()))) {
+              FdoStringP msg = FdoStringP::Format(L"[PostGIS] ApplySchemaCommand: Delete class '%s' error! table in not empty!", classDef->GetName());
+              FDOLOG_WRITE("ERROR: %s", static_cast<FdoString*>(msg));
+              throw FdoCommandException::Create(msg);
+           }
+           break;
+         }
+    }
 
-        if (NULL != props && props->GetCount() > 0)
-        {
-            std::string sep;
-            std::string sqlColumns;
+    for (FdoInt32 i = 0; i < classesSize; i++)
+    {
+        FdoPtr<FdoClassDefinition> classDef(featureClasses->GetItem(i));
+         switch ( classDef->GetElementState() )
+         {
+         case FdoSchemaElementState_Added:
+             CreateTable(classDef);
+             break;
+         //ticket #106 - cannot delete a feature class - eric barby
+         case FdoSchemaElementState_Deleted:
+             DropTable(classDef);
+             break;
+         case FdoSchemaElementState_Detached:
+             break;            
+         case FdoSchemaElementState_Modified:
+         case FdoSchemaElementState_Unchanged:
+             break;
+         }
+     }
+     mFeatureSchema->AcceptChanges();
 
-            //
-            // Read properties and parse details: name, data type, size.
-            // 
-            FdoInt32 const propsSize = props->GetCount();
-            for (FdoInt32 j = 0; j < propsSize; j++)
-            {
-                FdoPtr<FdoPropertyDefinition> propDef(props->GetItem(j));
-                if (FdoPropertyType_DataProperty == propDef->GetPropertyType())
-                {
-                    FdoStringP propName(propDef->GetName());
-                    std::string sqlType(details::PgTypeFromFdoProperty(propDef));
-                    if (sqlType.empty())
-                    {
-                        throw FdoCommandException::Create(L"ApplySchemaCommand::Execute: Unkown data property type"); 
-                    }
+  } 
+  {
+    FdoPtr<FdoClassCollection> featClasses(mFeatureSchema->GetClasses());
+    FdoInt32 const classesSize = featClasses->GetCount();
+    for (FdoInt32 i = 0; i < classesSize; i++)
+    {
+        FdoPtr<FdoClassDefinition> classDef(featClasses->GetItem(i));
+        if (classDef->GetElementState() != FdoSchemaElementState_Unchanged) {
+          std::string tableName(static_cast<char const*>(FdoStringP(classDef->GetName()).Lower()));
+          FDOLOG_WRITE("Error of ClassDefinition State of '%s'", tableName);
+        }
+    }
+  }
+ }
 
-                    sqlColumns += sep;
-                    
-                    // Ticket #115
-                    //sqlColumns += static_cast<char const*>(propName.Lower());
-                    sqlColumns += details::QuoteSqlName<std::string>(static_cast<char const*>(propName.Lower()));
-                    
-                    sqlColumns += " " + sqlType;
-                    sep = ",";
-                }
-            }
 
-            //
-            // Read identity properties used to build PRIMARY KEY
-            //
-            sep = "";
-            std::string sqlPrimaryKey;
-            FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity(classDef->GetIdentityProperties());
-            FdoInt32 const propsIdSize = propsIdentity->GetCount();
-            for (FdoInt32 j = 0; j < propsIdSize; j++)
+///////////////////////////////////////////////////////////////////////////////
+// Private operations
+///////////////////////////////////////////////////////////////////////////////
+
+//eric barby - test if table exist before creating it
+bool ApplySchemaCommand::TestingCreateTable(ov::ClassDefinition* phClass) const
+{
+    FDOLOG_MARKER("ApplySchemaCommand::-check before CreateTable");
+    if (NULL == phClass) return true;
+    // 
+    // before CREATE TABLE command
+    // 
+
+    FdoStringP sql = 
+    FdoStringP::Format(L"SELECT schemaname, tablename FROM pg_tables WHERE schemaname='%s' AND tablename ='%s'"
+                       , static_cast<FdoString*>(phClass->GetSchemaName())
+                       , static_cast<FdoString*>(phClass->GetTableName() ));
+    
+    FdoPtr<FdoISQLCommand> Cmd = static_cast<FdoISQLCommand*>(mConn->CreateCommand(FdoCommandType_SQLCommand));
+    assert(NULL != Cmd);
+    
+    Cmd->SetSQLStatement(sql);
+    FdoPtr<FdoISQLDataReader> reader = Cmd->ExecuteReader();
+    assert(NULL != reader);
+
+    bool hasTuples = reader->ReadNext();
+    return !hasTuples;
+}
+
+//ticket #106 - cannot delete a feature class - eric barby
+//eric barby - test if table is empty before dropping it
+bool ApplySchemaCommand::TestingDropTable(ov::ClassDefinition* phClass) const
+{
+    assert(NULL != mFeatureSchema);
+    FDOLOG_MARKER("ApplySchemaCommand::-check before DropTable");
+    if (NULL == phClass) return false;
+    //
+    // before DROP TABLE command
+    // 
+    FdoStringP  sql = FdoStringP::Format(L"SELECT COUNT(*) AS nb FROM %s", static_cast<FdoString*>(phClass->GetTableName()));
+    
+    FdoPtr<FdoISQLCommand> Cmd = static_cast<FdoISQLCommand*>(mConn->CreateCommand(FdoCommandType_SQLCommand));
+    assert(NULL != Cmd);
+    
+    Cmd->SetSQLStatement(sql);
+    FdoPtr<FdoISQLDataReader> reader = Cmd->ExecuteReader();
+    assert(NULL != reader);
+
+    bool  hasData=false;
+    if (reader->ReadNext()) 
+    {
+      if (reader->GetInt16(L"nb") > 0)
+        hasData = true;
+    }
+
+    return !hasData;
+}
+
+void ApplySchemaCommand::CreateTable(FdoPtr<FdoClassDefinition> classDef) const
+{
+    FDOLOG_MARKER("ApplySchemaCommand::-CreateTable");
+
+    FdoPtr<FdoPropertyDefinitionCollection> props(classDef->GetProperties());
+
+    // TODO do not use Lower if ClassName starting and ending by ""
+    FdoStringP className(static_cast<char const*>(FdoStringP(classDef->GetName()).Lower()));
+    std::string   schemaName, tableName;
+    // TODO check a SchemaMapping...
+
+    ov::ClassDefinition* phClass;
+    phClass = this->GetClassDefinition(classDef->GetName());
+    if (phClass) 
+    {
+        //schemaName = static_cast<char const*>(phClass->GetSchemaName());
+        schemaName = static_cast<char const*>(mConn->GetPgCurrentSchema());
+        tableName  = static_cast<char const*>(phClass->GetTableName() );
+    } 
+    else 
+    if ( className.Contains(L"~"))
+    {
+        schemaName = className.Left(L"~");
+        tableName  = className.Right(L"~");
+    } 
+    else
+    { 
+        schemaName = mConn->GetPgCurrentSchema();
+        tableName  = className;
+        //eric barby - table naming convention without ~
+        //className  = FdoStringP(schemaName.c_str()) + L"~" + FdoStringP(tableName.c_str());
+        className  = FdoStringP(tableName.c_str());
+        classDef->SetName(className);
+    }
+    if (!schemaName.length())
+    {
+      schemaName = static_cast<char const*>(phClass->GetSchemaName());
+      schemaName = static_cast<char const*>(mConn->GetPgCurrentSchema());
+    }
+
+    if (NULL != props && props->GetCount() > 0)
+    {
+        std::string sep;
+        std::string sqlColumns;
+
+        //
+        // Read properties and parse details: name, data type, size.
+        // 
+        FdoInt32 const propsSize = props->GetCount();
+        for (FdoInt32 j = 0; j < propsSize; j++)
+        {
+            FdoPtr<FdoPropertyDefinition> propDef(props->GetItem(j));
+            if (FdoPropertyType_DataProperty == propDef->GetPropertyType())
             {
-                FdoPtr<FdoDataPropertyDefinition> propId(propsIdentity->GetItem(j));
-                FdoStringP propName(propId->GetName());
-
-                if (sqlPrimaryKey.empty())
+                FdoStringP propName(propDef->GetName());
+                std::string sqlType(details::PgTypeFromFdoProperty(propDef));
+                if (sqlType.empty())
                 {
-                    sqlPrimaryKey = ", PRIMARY KEY(";
+                    throw FdoCommandException::Create(L"ApplySchemaCommand::Execute: Unkown data property type"); 
                 }
 
-                sqlPrimaryKey += sep;
-
-                // Ticket #115: do we need to quote PK names?
-                sqlPrimaryKey += static_cast<char const*>(propName.Lower());
+                sqlColumns += sep;
+                
+                // Ticket #115
+                //sqlColumns += static_cast<char const*>(propName.Lower());
+                //sqlColumns += details::QuoteSqlName<std::string>(static_cast<char const*>(propName.Lower()));
+                sqlColumns += static_cast<char const*>(propName.Lower());                
+                sqlColumns += " " + sqlType;
                 sep = ",";
             }
+        }
 
-            if (!sqlPrimaryKey.empty())
+        //
+        // Read identity properties used to build PRIMARY KEY
+        //
+        sep = "";
+        std::string sqlPrimaryKey;
+        FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity(classDef->GetIdentityProperties());
+        FdoInt32 const propsIdSize = propsIdentity->GetCount();
+        for (FdoInt32 j = 0; j < propsIdSize; j++)
+        {
+            FdoPtr<FdoDataPropertyDefinition> propId(propsIdentity->GetItem(j));
+            FdoStringP propName(propId->GetName());
+
+            if (sqlPrimaryKey.empty())
             {
-                sqlPrimaryKey += ")";
+                sqlPrimaryKey = ", PRIMARY KEY(";
             }
 
-            //
-            // CREATE TABLE command
-            // 
-            std::string tableName(static_cast<char const*>(FdoStringP(classDef->GetName()).Lower()));
+            sqlPrimaryKey += sep;
 
-            std::string sqlCreate("CREATE TABLE ");
-            sqlCreate += details::QuoteSqlName(tableName);
-            sqlCreate += " ( ";
-            sqlCreate += sqlColumns;
-            if (!sqlPrimaryKey.empty())
-            {
-                sqlCreate += sqlPrimaryKey;
-            }
-            sqlCreate += " )";
+            // Ticket #115: do we need to quote PK names?
+            sqlPrimaryKey += static_cast<char const*>(propName.Lower());
+            sep = ",";
+        }
 
-            FDOLOG_WRITE("SQL:\n\t%s", sqlCreate.c_str());
+        if (!sqlPrimaryKey.empty())
+        {
+            sqlPrimaryKey += ")";
+        }
 
-            mConn->PgExecuteCommand(sqlCreate.c_str());
+        //
+        // CREATE TABLE command
+        // 
 
-            //
-            // Register geometric property as PostGIS geometry column 
-            //
-            if (FdoClassType_FeatureClass == classDef->GetClassType())
-            {
-                FdoFeatureClass* featClass = static_cast<FdoFeatureClass*>(classDef.p);
+        std::string sqlCreate("CREATE TABLE ");
+        sqlCreate += details::QuoteSqlName(tableName);
+        sqlCreate += " ( ";
+        sqlCreate += sqlColumns;
+        if (!sqlPrimaryKey.empty())
+        {
+            sqlCreate += sqlPrimaryKey;
+        }
+        sqlCreate += " )";
 
-                AddGeometryColumn(tableName, featClass->GetGeometryProperty());
+        FDOLOG_WRITE("SQL:\n\t%s", sqlCreate.c_str());
 
-                // Create GiST index for table-column pair.
-                CreateSpatialIndex(tableName, featClass->GetGeometryProperty());
-            }
+        mConn->PgExecuteCommand(sqlCreate.c_str());
 
-            //
-            // CREATE SEQUENCE for single column, integral type PRIMARY KEY
-            //
-            if (1 == propsIdSize)
+        //
+        // Register geometric property as PostGIS geometry column 
+        //
+        if (FdoClassType_FeatureClass == classDef->GetClassType())
+        {
+            FdoFeatureClass* featClass = static_cast<FdoFeatureClass*>(classDef.p);
+
+            AddGeometryColumn(tableName, featClass->GetGeometryProperty());
+
+            // Create GiST index for table-column pair.
+            CreateSpatialIndex(tableName, featClass->GetGeometryProperty());
+        }
+
+        //
+        // CREATE SEQUENCE for single column, integral type PRIMARY KEY
+        //
+        if (1 == propsIdSize)
+        {
+            FdoPtr<FdoDataPropertyDefinition> propId = propsIdentity->GetItem(0);
+            assert(NULL != propId);
+
+            if (propId->GetIsAutoGenerated()
+                && (FdoDataType_Int16 == propId->GetDataType() 
+                    || FdoDataType_Int32 == propId->GetDataType()
+                    || FdoDataType_Int64 == propId->GetDataType()))
             {
-                FdoPtr<FdoDataPropertyDefinition> propId = propsIdentity->GetItem(0);
-                assert(NULL != propId);
-
-                if (propId->GetIsAutoGenerated()
-                    && (FdoDataType_Int16 == propId->GetDataType() 
-                        || FdoDataType_Int32 == propId->GetDataType()
-                        || FdoDataType_Int64 == propId->GetDataType()))
-                {
-                    CreateSequence(tableName, propId);
-                }
+                CreateSequence(tableName, propId);
             }
+        }
 
-            // TODO: Add class description as a COMMENT
+        // TODO: Add class description as a COMMENT
 
-
-        } // if (NULL != props && props->GetCount() > 0)
-    }
+        // Physical mapping for the feature class
+        if (NULL == phClass) {
+          ov::PhysicalSchemaMapping *schemaMapping=mConn->GetPhysicalSchemaMapping();
+          if (schemaMapping) {
+            ov::ClassCollection::Ptr phClasses(schemaMapping->GetClasses());
+            ov::ClassDefinition::Ptr classDef = ov::ClassDefinition::Create();
+            classDef->SetName(className);
+            classDef->SetSchemaName(FdoStringP(schemaName.c_str()));
+            try {
+              phClasses->Add(classDef);
+            }
+            catch (FdoException* e)
+            {
+              FDOLOG_WRITE("Error Do not append ClassDefinition / Schema Mapping for class");
+              e->Release();
+            }
+          }
+        }
+    } // if (NULL != props && props->GetCount() > 0)
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Private operations
-///////////////////////////////////////////////////////////////////////////////
 
 void ApplySchemaCommand::AddGeometryColumn(std::string const& table,
                                            FdoPtr<FdoGeometricPropertyDefinition> prop) const
@@ -250,19 +446,29 @@
     else if (prop->GetHasElevation() && prop->GetHasMeasure())
         dimension = 4;
 
-    std::string type(ewkb::PgGeometryTypeFromFdoType(prop->GetGeometryTypes(), isXYM));
+  // ticket #311 - mismatch FdoGeometricTypes and and FdoGeometryType in class creation - eric barby
+  // error prop->GetGeometryTypes() return the FdoGeometricTypes that can be stored in this geometric property. 
+  // PgGeometryTypeFromFdoType(...) use a FdoGeometryType!!!
+  //std::string type(ewkb::PgGeometryTypeFromFdoType(prop->GetGeometryTypes(), isXYM));
+    FdoInt32    length;
+    std::string type;
+    FdoGeometryType *fdoTypes = prop->GetSpecificGeometryTypes(length);
+    if (fdoTypes)
+      type = ewkb::PgGeometryTypeFromFdoType(fdoTypes, length, isXYM);
+    else 
+      type = ewkb::PgGeometryTypeFromFdoType(prop->GetGeometryTypes(), isXYM);
 
     // Execute SQL
-    std::string sql("SELECT AddGeometryColumn(current_schema()::text,");
-    sql += details::QuoteSqlValue(table) + ",";
-    sql += details::QuoteSqlValue(column) + ",";
-    sql += str(boost::format("%d") % srid);
-    sql += "," + details::QuoteSqlValue(type) + ",";
-    sql += str(boost::format("%d") % dimension);
-    sql += ")";
+    std::stringstream sqlStm; 
+    sqlStm << "SELECT AddGeometryColumn(current_schema()::text,"
+           << ((std::string)details::QuoteSqlValue(table))  << ","
+           << ((std::string)details::QuoteSqlValue(column)) << ","
+           <<  srid << ","
+           << ((std::string)details::QuoteSqlValue(type)) << ","
+           << dimension << ")";
 
+    std::string sql(sqlStm.str());
     FDOLOG_WRITE("SQL:\n\t%s", sql.c_str());
-
     mConn->PgExecuteCommand(sql.c_str());
 }
 
@@ -320,4 +526,76 @@
     mConn->PgExecuteCommand(sql.c_str());
 }
 
+// ticket #106 - cannot delete a feature class - eric barby
+void ApplySchemaCommand::DropTable(FdoPtr<FdoClassDefinition> classDef) const
+{
+    assert(NULL != mFeatureSchema);
+    FDOLOG_MARKER("ApplySchemaCommand::-DropTable");
+    //
+    // DROP TABLE command
+    // 
+    ov::ClassDefinition* phClass;
+    phClass = this->GetClassDefinition(classDef->GetName());
+    if (NULL == phClass) {
+        FdoStringP msg = FdoStringP::Format(L"[PostGIS] ApplySchemaCommand: Delete class '%s' error! ClassDefinition not fount!", classDef->GetName());
+        FDOLOG_WRITE("ERROR: %s", static_cast<FdoString*>(msg));
+        throw FdoCommandException::Create(msg);
+    }
+    std::string   schemaName(static_cast<char const*>(phClass->GetSchemaName()));
+    std::string   tableName (static_cast<char const*>(phClass->GetTableName() ));
+
+    std::string sqlDrop("DROP TABLE ");
+    sqlDrop += tableName;
+
+    FDOLOG_WRITE("SQL:\n\t%s", sqlDrop.c_str());
+
+    mConn->PgExecuteCommand(sqlDrop.c_str());
+
+    FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity(classDef->GetIdentityProperties());
+    FdoInt32 const propsIdSize = propsIdentity->GetCount();
+    //
+    // DROP SEQUENCE for single column, integral type PRIMARY KEY
+    //
+    if (1 == propsIdSize)
+    {
+        FdoPtr<FdoDataPropertyDefinition> propId = propsIdentity->GetItem(0);
+        assert(NULL != propId);
+
+        if (propId->GetIsAutoGenerated()
+            && (FdoDataType_Int16 == propId->GetDataType() 
+                || FdoDataType_Int32 == propId->GetDataType()
+                || FdoDataType_Int64 == propId->GetDataType()))
+        {
+            std::string column(static_cast<char const*>(FdoStringP(propId->GetName()).Lower()));
+            std::string sequence = details::MakeSequenceName(tableName, column);
+
+            std::string sql("DROP SEQUENCE " + sequence);
+            mConn->PgExecuteCommand(sql.c_str());
+        }
+    }
+ 
+    //
+    // Drop geometric property as PostGIS geometry column 
+    //
+    if (FdoClassType_FeatureClass == classDef->GetClassType())
+    {
+        FdoFeatureClass* featClass = static_cast<FdoFeatureClass*>(classDef.p);
+        if (featClass) {
+          FdoPtr<FdoGeometricPropertyDefinition> propGeom(featClass->GetGeometryProperty());
+          std::string geomCol(static_cast<char const*>(FdoStringP(propGeom->GetName()).Lower()));
+          // DELETE FROM geometry_column WHERE tableName AND geomCol;
+          std::string sql("DELETE FROM geometry_columns "
+                          " WHERE  f_table_schema = '" + schemaName + "'"
+                             " AND f_table_name = '" + tableName + "'");
+          mConn->PgExecuteCommand(sql.c_str());
+          // DROP Spatial Index ?
+        }
+    }
+    
+    //
+    // remove a Physical mapping of the feature class
+    //
+}
+
 }} // namespace fdo::postgis
+
Index: fdo/trunk/Providers/PostGIS/Src/Provider/ApplySchemaCommand.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/ApplySchemaCommand.h	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/ApplySchemaCommand.h	(working copy)
@@ -133,7 +133,27 @@
     // Private operations
     //
 
+    // ticket #106 - cannot delete a feature class - eric barby
+    // for testing before action...
+    bool TestingCreateTable(ov::ClassDefinition* phClass) const;
+    bool TestingDropTable  (ov::ClassDefinition* phClass) const;
 
+    // This function creates a feature table
+    // It is a simple proxy around SQL command:
+    // CREATE TABLE <table_name> ( <column_name> <type>, ... [, <primary key>])
+    // \param
+    // classDef - definition of feature class
+    //
+    void CreateTable(FdoPtr<FdoClassDefinition> classDef) const;
+
+    // This function drop a feature table, sequence and update geometry_columns
+    // It is a simple proxy around SQL command:
+    // DROP TABLE <table_name> 
+    // classDef - definition of feature class
+    //
+    void DropTable(FdoPtr<FdoClassDefinition> classDef) const;
+
+
     // This function registers geometry column in PostGIS meta-schema.
     // It is a simple proxy around SQL command:
     // AddGeometryColumn(<schema_name>,<table_name>,<column_name>,<srid>,<type>,<dimension>)
@@ -154,6 +174,9 @@
     void CreateSpatialIndex(std::string const& table, FdoPtr<FdoGeometricPropertyDefinition> prop) const;
 
     void CreateSequence(std::string const& table, FdoPtr<FdoDataPropertyDefinition> prop) const;
+
+    ov::ClassDefinition* GetClassDefinition(FdoStringP className) const;
+
 };
 
 }} // namespace fdo::postgis
Index: fdo/trunk/Providers/PostGIS/Src/Provider/Command.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/Command.h	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/Command.h	(working copy)
@@ -109,6 +109,13 @@
     // cursor declaration.
     void PgGenerateExecParams(details::pgexec_params_t& pgParams);
 
+    // Find Property definition in collection...
+    FdoPropertyDefinition *GetPropDefinition(FdoPropertyDefinitionCollection *propsDef, FdoStringP name);
+
+    // Find SRID in propertydef
+    FdoInt32 GetSRID(FdoPropertyDefinitionCollection *propsDef);
+
+
 }; // class Command
 
 template <typename T>
@@ -338,6 +345,57 @@
     FDOLOG_WRITE("Number of parameters: %u", pgParams.size());
 }
 
+
+// Find Property definition in collection...
+template <typename T>
+FdoPropertyDefinition* Command<T>::GetPropDefinition(FdoPropertyDefinitionCollection *propsDef, FdoStringP name)
+{
+  FdoInt32    i;
+  FdoPropertyDefinition *propDef, *propDefRt=NULL;
+  if (NULL == propsDef || !name.GetLength()) return NULL;
+  for (i=0; i<propsDef->GetCount(); i++) {
+    if ((propDef = propsDef->GetItem(i))) {
+      if (name == propDef->GetName())
+        return propDef;
+      if (!name.ICompare(propDef->GetName()))
+        propDefRt = propDef;
+    }
+  }
+  return propDefRt;
+}
+
+// Find SRID in propertydef
+template <typename T>
+FdoInt32 Command<T>::GetSRID(FdoPropertyDefinitionCollection *propsDef)
+{
+  FdoInt32    i, currentSrid=0;
+  FdoPropertyDefinition *propDef;
+
+  if (NULL == propsDef) return 0;
+  for (i=0; !currentSrid && i<propsDef->GetCount(); i++) {
+    if ((propDef = propsDef->GetItem(i))) {
+      if (FdoPropertyType_GeometricProperty == propDef->GetPropertyType())
+      {
+        // TODO: It won't work with multiple-geometric properties
+        FdoGeometricPropertyDefinition* geom = NULL;
+        geom = static_cast<FdoGeometricPropertyDefinition*>(propDef);
+
+        FdoString* csName = geom->GetSpatialContextAssociation();
+        SpatialContextCollection::Ptr spContexts(mConn->GetSpatialContexts());
+        SpatialContext::Ptr spc(spContexts->FindItem(csName));
+        if (NULL != spc)
+        {
+            currentSrid = spc->GetSRID();
+            currentSrid;
+        }
+
+        FDOLOG_WRITE(L"\t+ %s (SRID=%d)", propDef->GetName(), currentSrid);
+      }
+    }
+  }
+  return currentSrid;
+}
+
 }} // namespace fdo::postgis
 
 #endif // FDOPOSTGIS_COMMAND_H_INCLUDED
Index: fdo/trunk/Providers/PostGIS/Src/Provider/Connection.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/Connection.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/Connection.cpp	(working copy)
@@ -63,9 +63,10 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/classification.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
+//ticket #312 - remove BoostDateTime dependency - eric barby
+// #include <boost/date_time/posix_time/posix_time.hpp>
+#include <time.h> 
 
-
 // External access to connection for client services
 extern "C" FDOPOSTGIS_API FdoIConnection* CreateConnection()
 {
@@ -372,7 +373,8 @@
 
     // TODO: Verify what connection state is required for what commands
     //        || FdoConnectionState_Pending == GetConnectionState())
-    if (FdoConnectionState_Closed == GetConnectionState())
+    if (FdoCommandType_CreateDataStore != type
+     && FdoConnectionState_Closed == GetConnectionState())
     {
         FDOLOG_WRITE("ERROR: Connection is closed or invalid");
         throw FdoConnectionException::Create(
@@ -498,9 +500,11 @@
 {
     FDOLOG_MARKER("Connection::+PgExecuteCommand");
     FDOLOG_WRITE("SQL:\n\t%s", sql);
+    // eric barby - check if connection not closed!
+    // ValidateConnection tolerate closed connection
+    //ValidateConnectionState();
+    ValidateConnectionStateAndNotClosed();
 
-    ValidateConnectionState();
-
     affected = 0;
 
     boost::shared_ptr<PGresult> pgRes(PQexec(mPgConn, sql), PQclear);
@@ -510,7 +514,6 @@
     {
         FdoStringP errCode(PQresStatus(pgStatus));
         FdoStringP errMsg(PQresultErrorMessage(pgRes.get()));
-
         FDOLOG_WRITE(L"SQL command failed: [%s] %s",
             static_cast<FdoString*>(errCode), static_cast<FdoString*>(errMsg));
 
@@ -663,9 +666,22 @@
     //
     // Generate random suffix for cursor name to make name more unique
     //
-    using boost::posix_time::ptime;
-    ptime pt = boost::date_time::microsec_clock<ptime::time_type>::local_time();
-    std::string ptstr(boost::posix_time::to_iso_string(pt));
+    //ticket #312 - remove BoostDateTime dependency - eric barby
+    //using boost::posix_time::ptime;
+    //ptime pt = boost::date_time::microsec_clock<ptime::time_type>::local_time();
+    //std::string ptstr(boost::posix_time::to_iso_string(pt));
+    char        buf[256];
+    clock_t     cl=clock();
+    time_t      rtime;
+    struct tm  *timeinfo;
+    time(&rtime);
+    timeinfo = localtime(&rtime);
+    strftime(buf, 255, "%Y-%m-%d %H:%M:%S", timeinfo);
+    std::string ptstr = str(boost::format("%04d%02d%02dT%02f%02d%02d.%04d") 
+      %(int)(1900+timeinfo->tm_year) %(int)(1+timeinfo->tm_mon) %(int)timeinfo->tm_mday 
+      %(int)timeinfo->tm_hour %(int)timeinfo->tm_min %(int)timeinfo->tm_sec
+      %(int)cl);
+
     fdo::postgis::md5 md5sum(ptstr.c_str());
     std::string suffix(md5sum.digest().hex_str_value());
    
@@ -872,7 +888,29 @@
             "Invalid state of PostgreSQL connection."));
     }
 }
+//Does not tolerate closed connection
+void Connection::ValidateConnectionStateAndNotClosed()
+{
+    bool valid = false;
 
+    if (NULL != mPgConn
+     && (FdoConnectionState_Open == GetConnectionState()
+         || FdoConnectionState_Pending == GetConnectionState()
+         || FdoConnectionState_Busy == GetConnectionState()))
+    {
+        // Check PostgreSQL connection status
+        if (CONNECTION_OK == PQstatus(mPgConn))
+            valid = true;
+    }    
+
+    if (!valid)
+    {
+        FDOLOG_WRITE("ERROR: PostgreSQL connection not opened!");
+        throw FdoException::Create(NlsMsgGet(MSG_POSTGIS_INVALID_PGSQL_CONNECTION_STATE,
+            "PostgreSQL connection do not opend!"));
+    }
+}
+
 void Connection::ValidateConnectionString()
 {
     FdoStringP connStr(GetConnectionString());
Index: fdo/trunk/Providers/PostGIS/Src/Provider/Connection.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/Connection.h	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/Connection.h	(working copy)
@@ -49,6 +49,13 @@
 ///
 class Connection : public FdoIConnection
 {
+    //eric barby - give access to schema description cache
+    friend class InsertCommand;
+    friend class DeleteCommand;
+    friend class ApplySchemaCommand;
+    friend class UpdateCommand;
+    friend class SelectCommand;
+
 public:
 
     /// Type of FDO smart pointer for Connection class.
@@ -256,6 +263,10 @@
     // Check internal state of connection to PostgreSQL server.
     void ValidateConnectionState();
 
+    // eric barby
+    // Check internal state of connection to PostgreSQL server, does not tolerate closed connection
+    void ValidateConnectionStateAndNotClosed();
+
     // Validate connection string assigned to current connection instance.
     // The function throws exception on errors detected.
     void ValidateConnectionString();
Index: fdo/trunk/Providers/PostGIS/Src/Provider/ConnectionCapabilities.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/ConnectionCapabilities.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/ConnectionCapabilities.cpp	(working copy)
@@ -88,7 +88,10 @@
 
 bool ConnectionCapabilities::SupportsTransactions()
 {
-    return true;
+    // ticket #314 (PostGIS provider : check-out/check-in crashes Autodesk Map)
+    // We should investigate on why transaction crashes Autodesk Map
+    //return true;
+  return false;
 }
 
 bool ConnectionCapabilities::SupportsLongTransactions()
Index: fdo/trunk/Providers/PostGIS/Src/Provider/DeleteCommand.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/DeleteCommand.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/DeleteCommand.cpp	(working copy)
@@ -46,17 +46,23 @@
     //
     // Collect schema details required to build SQL command
     //
-    SchemaDescription::Ptr schemaDesc(SchemaDescription::Create());
-    schemaDesc->DescribeSchema(mConn, NULL);
+    // eric barby - faster way of describing schema
+    SchemaDescription *schemaDesc = mConn->DescribeSchema();
+    if (!schemaDesc || !schemaDesc->IsDescribed()) 
+    {
+        throw FdoCommandException::Create(L"[PostGIS] DeleteCommand can not find schema definition");
+    }
+    //SchemaDescription::Ptr schemaDesc(SchemaDescription::Create());
+    //schemaDesc->DescribeSchema(mConn, NULL);
 
     FdoPtr<FdoIdentifier> classIdentifier(GetFeatureClassName());
     FdoPtr<FdoClassDefinition> classDef(schemaDesc->FindClassDefinition(mClassIdentifier));    
-    if (!classDef) 
+    ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier));
+    if (!classDef || !phClass) 
     {
-        throw FdoCommandException::Create(L"[PostGIS] DeleteCommand can not find class definition");
+        throw FdoCommandException::Create(L"[PostGIS] DeleteCommand can not find class definition or class mapping!");
     }
 
-    ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier));
     FdoStringP tablePath(phClass->GetTablePath());
 
     //
Index: fdo/trunk/Providers/PostGIS/Src/Provider/ExpressionProcessor.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/ExpressionProcessor.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/ExpressionProcessor.cpp	(working copy)
@@ -280,17 +280,23 @@
         
         if (dt.IsTime())
         {
-            value = str(boost::format("'%d:%d:%d'") % dt.hour % dt.minute % dt.seconds);
+            // ticket #313 - can't filter,insert or update date/datetime - eric barby
+            //value = str(boost::format("'%d:%d:%d'") % dt.hour % dt.minute % dt.seconds);
+            value = str(boost::format("'%d:%d:%d'") % (int)dt.hour % (int)dt.minute % (int)dt.seconds);
             format = "'HH24:MI:SS'";
         }
         else if (dt.IsDate())
         {
-            value = str(boost::format("'%d-%d-%d'") % dt.month % dt.day % dt.year);
+            // ticket #313 - can't filter,insert or update date/datetime - eric barby
+            //value = str(boost::format("'%d-%d-%d'") % dt.month % dt.day % dt.year);
+            value = str(boost::format("'%d-%d-%d'") % (int)dt.month % (int)dt.day % (int)dt.year);
             format = "'MM-DD-YYYY'";
         }
         else if (dt.IsDateTime())
         {
-            value = str(boost::format("'%d-%d-%d %d:%d:%d'") % dt.month % dt.day % dt.year % dt.month % dt.day % dt.year);
+            // ticket #313 - can't filter,insert or update date/datetime - eric barby
+            //value = str(boost::format("'%d-%d-%d %d:%d:%d'") % dt.month % dt.day % dt.year % dt.month % dt.day % dt.year);
+            value = str(boost::format("'%d-%d-%d %d:%d:%d'") % (int)dt.month % (int)dt.day % (int)dt.year % (int)dt.month % (int)dt.day % (int)dt.year);
             format = "'MM-DD-YYYY HH24:MI:SS'";
         }
         else
Index: fdo/trunk/Providers/PostGIS/Src/Provider/FeatureReader.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/FeatureReader.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/FeatureReader.cpp	(working copy)
@@ -76,7 +76,10 @@
           for(long ind2 =0;ind2<m_Props->GetCount();ind2++)
           {
             FdoPtr<FdoIdentifier> prop2 = m_Props->GetItem(ind2);
-            if( wcscmp(classprop->GetName(),prop2->GetName()) == 0 )
+            //ticket #234 - does not support anything but lowercase identifiers - eric barby
+            // a lowercase comparison of strings... 
+            if(_wcsicmp(classprop->GetName(),prop2->GetName()) == 0 )
+            //if( wcscmp(classprop->GetName(),prop2->GetName()) == 0 )
             {
               found=true;
               break;
Index: fdo/trunk/Providers/PostGIS/Src/Provider/FilterProcessor.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/FilterProcessor.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/FilterProcessor.cpp	(working copy)
@@ -254,20 +254,33 @@
 
     mStatement.append(sql::sepLeftTerm);
     propName->Process(mExprProc);
+    // ticket #233 - in and not in filter does not work - eric barby
+    // left operande name !..
+    std::string columnName, value;
+    mExprProc->ReleaseExpressionText(columnName);
+    mStatement.append(columnName);
     mStatement.append(sql::opIn);
     mStatement.append(sql::sepLeftTerm);
 
     FdoPtr<FdoExpression> expr;
-    FdoInt32 const count = exprCol->GetCount() - 1;
+    FdoInt32 const count = exprCol->GetCount();
     FdoInt32 i = 0;
-    for (i = 0; i < count; i++)
+    for (i = 0; i < count-1; i++)
     {
         expr = exprCol->GetItem(i);
         expr->Process(mExprProc);
+        // ticket #233 - in and not in filter does not work - eric barby
+        // add values!..
+        mExprProc->ReleaseExpressionText(value);
+        mStatement.append(value);
         mStatement.append(sql::sepComma);
     }
     expr = exprCol->GetItem(i);
     expr->Process(mExprProc);
+    // ticket #233 - in and not in filter does not work - eric barby
+    // add values!..
+    mExprProc->ReleaseExpressionText(value);
+    mStatement.append(value);
 
     mStatement.append(sql::sepRightTerm);
     mStatement.append(sql::sepRightTerm);
@@ -283,6 +296,11 @@
 
     mStatement.append(sql::sepLeftTerm);
     propId->Process(mExprProc);
+    // ticket #232 - null and not null filter does not work - eric barby
+    // left operande name !..
+    std::string columnName;
+    mExprProc->ReleaseExpressionText(columnName);
+    mStatement.append(columnName);
     mStatement.append(sql::opIsNull);
     mStatement.append(sql::sepRightTerm);
 
Index: fdo/trunk/Providers/PostGIS/Src/Provider/InsertCommand.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/InsertCommand.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/InsertCommand.cpp	(working copy)
@@ -111,16 +111,23 @@
     //
     // Collect schema details required to build SQL command
     //
-    SchemaDescription::Ptr schemaDesc(SchemaDescription::Create());
-    schemaDesc->DescribeSchema(mConn, NULL);
+    // eric barby - faster with mConn->DescribeSchema() , uses cache
+    SchemaDescription*  schemaDesc = mConn->DescribeSchema();
+    if (!schemaDesc || !schemaDesc->IsDescribed()) 
+    {
+        throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find schema definition");
+    }
+    // SchemaDescription::Ptr schemaDesc(SchemaDescription::Create());
+    // schemaDesc->DescribeSchema(mConn, NULL);
 
+    //ticket #178 - Can't insert in a non-feature class - eric barby
     FdoPtr<FdoClassDefinition> classDef(schemaDesc->FindClassDefinition(mClassIdentifier));
-    if (!classDef) 
+    ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier));
+    if (!classDef || !phClass) 
     {
-        throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find class definition");
+        throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find class definition or class mapping!");
     }
 
-    ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier));
 
     std::string sep;
     std::string columns;
@@ -133,7 +140,9 @@
     // Check auto-generated PRIMARY KEY and configure sequence
     //
     FdoStringP pkColumn;
+    FdoPtr<FdoPropertyDefinitionCollection>     propsDefinition(classDef->GetProperties());
     FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity(classDef->GetIdentityProperties());
+    FdoInt32 currentSrid = GetSRID(propsDefinition);
     if (1 == propsIdentity->GetCount())
     {
         FdoPtr<FdoDataPropertyDefinition> prop(propsIdentity->GetItem(0));
@@ -157,19 +166,51 @@
     for (FdoInt32 i = 0; i < propsSize; i++)
     {
         FdoPtr<FdoPropertyValue> propVal(mProperties->GetItem(i));
-        FdoPtr<FdoIdentifier> propId(propVal->GetName());
+        FdoStringP   pName(propVal->GetName()->GetName());
+        FdoPtr<FdoPropertyDefinition> propDef(GetPropDefinition(propsDefinition, pName));
+        if (propDef) {
+          pName = propDef->GetName();
+        } else {
+          FDOLOG_WRITE(L"can not find porpertyDefinition '%s'", static_cast<FdoString*>(propVal->GetName()->GetName()));
+          //throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find porpertyDefinition!");
+        }
+        // eric barby - propId is not used anymore
+        // FdoPtr<FdoIdentifier> propId(FdoIdentifier::Create(static_cast<FdoString*>(pName)));
+        columns += sep + static_cast<char const*>(pName); // FdoStringP(propId->GetName())
 
-        columns += sep + static_cast<char const*>(FdoStringP(propId->GetName()));
-
-        if (0 == pkColumn.ICompare(propId->GetName()))
+        if (0 == pkColumn.ICompare(pName)) // propId->GetName()
         {
             values += sep + "nextval(\'" + sequence + "\')";
         }
         else
         {
-            FdoPtr<FdoValueExpression> expr(propVal->GetValue());
+            FdoValueExpression *expr=propVal->GetValue();
             expr->Process(expProc);
-            values += sep + expProc->ReleaseBuffer();
+            std::string value = expProc->ReleaseBuffer();
+            if (propDef) {
+              if (FdoPropertyType_DataProperty == propDef->GetPropertyType())
+              {
+                FdoDataPropertyDefinition* dataDef = static_cast<FdoDataPropertyDefinition*>(propDef.p);
+                //ticket #313 - can't filter,insert or update date/datetime - eric barby
+                // eric barby - need to parse date properly
+                if (FdoDataType_DateTime == dataDef->GetDataType()) {
+                  FdoDateTimeValue *dateValuePtr=dynamic_cast<FdoDateTimeValue*>(propVal->GetValue());
+                  if (!dateValuePtr->IsNull()) {
+                    FDOLOG_WRITE(L"convert Date:", dateValuePtr->ToString());
+                    value = static_cast<char const*>(FdoStringP(dateValuePtr->ToString()));
+                  }
+                }
+              } 
+              // bruno scott - geom is not used anywhere, maybe we should delete this line
+              else 
+              if (FdoPropertyType_GeometricProperty == propDef->GetPropertyType())
+              {
+                  // TODO: It won't work with multiple-geometric properties
+                  FdoGeometricPropertyDefinition* geom = NULL;
+                  geom = static_cast<FdoGeometricPropertyDefinition*>(propDef.p);
+              }
+            }
+            values += sep + value;            
         }
         sep = ",";
     }
Index: fdo/trunk/Providers/PostGIS/Src/Provider/PgGeometry.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PgGeometry.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PgGeometry.cpp	(working copy)
@@ -103,7 +103,8 @@
         {
             fdoType = FdoGeometryType_MultiPolygon;
         }
-        else if (0 == pgType.compare(0, 18, "GEOMETRYCOLLECTION"))
+        //ticket #311 - mismatch FdoGeometricTypes and and FdoGeometryType in class creation - eric barby
+        else if (0 == pgType.compare(0, 18, "GEOMETRY")) // "GEOMETRYCOLLECTION"
         {
             fdoType = FdoGeometryType_MultiGeometry;
         }
@@ -169,38 +170,109 @@
     return fdoDim;
 }
 
+// ticket #311 - mismatch FdoGeometricTypes and and FdoGeometryType in class creation - eric barby
+// The type of the spatial object. To restrict the spatial column to a single type,
+// use one of:
+// POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION 
+// or corresponding XYM versions 
+// POINTM, LINESTRINGM, POLYGONM, MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM.
+// For heterogeneous (mixed-type) collections, you can use "GEOMETRY" as the type.
+std::string PgGeometryTypeFromFdoType(FdoGeometryType *fdoTypes, FdoInt32 length, bool isXYM)
+{
+    bool  point=false, line=false, pgone=false, multipoint=false, multiline=false, multipgone=false;
+    FdoGeometryType typeMax = FdoGeometryType_None;
+    std::string pgType = "GEOMETRY";;
+
+    if (fdoTypes && length)
+    { // TODO FdoCommonMiscUtil::ContainsGeomType() do not use a const arguments!
+      point =  FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_Point       );
+      line  = (FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_LineString  )
+            || FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_CurveString ));
+      pgone = (FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_Polygon     )
+            || FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_CurvePolygon));
+      multipoint =  FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_MultiPoint       );
+      multiline  = (FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_MultiLineString  )
+                 || FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_MultiCurveString ));
+      multipgone = (FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_MultiPolygon     )
+                 || FdoCommonMiscUtil::ContainsGeomType(fdoTypes, length, FdoGeometryType_MultiCurvePolygon));
+
+//    if (multipoint && point) point=false;
+//    if (multiline  && line ) line=false;
+//    if (multipgone && pgone) pgone=false;
+      if (point + line + pgone + multipoint + multiline + multipgone == 1) 
+      {
+        if (point)        pgType = "POINT";
+        else if (line)    pgType = "LINESTRING";
+        else if (pgone)   pgType = "POLYGON";
+        else if (multipoint) pgType = "MULTIPOINT";
+        else if (multiline)  pgType = "MULTILINESTRING";
+        else if (multipgone) pgType = "MULTIPOLYGON";
+      //else (!!) pgType = "GEOMETRYCOLLECTION";
+      }
+    }
+    if (isXYM && pgType != "GEOMETRY")
+    {
+        pgType.push_back('M');
+    }
+
+    return pgType;
+}
+
+// ticket #311 - mismatch FdoGeometricTypes and and FdoGeometryType in class creation - eric barby
 std::string PgGeometryTypeFromFdoType(FdoInt32 const& fdoType)
 {
     std::string pgType;
 
+//  Error fdoType(s) is the FdoGeometricTypes that can be stored in this geometric property
+//    See also FdoGeometricPropertyDefinition::GetPropertyType(); member function for detail.
+//    switch (fdoType)
+//    {
+//    case FdoGeometryType_Point:
+//        pgType = "POINT";
+//        break;
+//    case FdoGeometryType_LineString:
+//        pgType = "LINESTRING";
+//        break;
+//    case FdoGeometryType_Polygon:
+//        pgType = "POLYGON";
+//        break;
+//    case FdoGeometryType_MultiPoint:
+//        pgType = "MULTIPOINT";
+//        break;
+//    case FdoGeometryType_MultiLineString:
+//        pgType = "MULTILINESTRING";
+//        break;
+//    case FdoGeometryType_MultiPolygon:
+//        pgType = "MULTIPOLYGON";
+//        break;
+//    case FdoGeometryType_MultiGeometry:
+//        pgType = "GEOMETRYCOLLECTION";
+//        break;
+//    default:
+//        // Also handles FdoGeometryType_None
+//        pgType = "GEOMETRY";
+//    }
+
     switch (fdoType)
     {
-    case FdoGeometryType_Point:
+    case FdoGeometricType_Point:
         pgType = "POINT";
         break;
-    case FdoGeometryType_LineString:
+    case FdoGeometricType_Curve:
         pgType = "LINESTRING";
         break;
-    case FdoGeometryType_Polygon:
+    case FdoGeometricType_Surface:
         pgType = "POLYGON";
         break;
-    case FdoGeometryType_MultiPoint:
-        pgType = "MULTIPOINT";
+    case FdoGeometricType_Solid:
+        pgType = "GEOMETRY";
         break;
-    case FdoGeometryType_MultiLineString:
-        pgType = "MULTILINESTRING";
-        break;
-    case FdoGeometryType_MultiPolygon:
-        pgType = "MULTIPOLYGON";
-        break;
-    case FdoGeometryType_MultiGeometry:
-        pgType = "GEOMETRYCOLLECTION";
-        break;
     default:
         // Also handles FdoGeometryType_None
         pgType = "GEOMETRY";
     }
 
+
     return pgType;
 }
 
Index: fdo/trunk/Providers/PostGIS/Src/Provider/PgGeometry.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PgGeometry.h	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PgGeometry.h	(working copy)
@@ -113,6 +113,11 @@
 // This version accepts flag indicating if XYM dimension is requested.
 std::string PgGeometryTypeFromFdoType(FdoInt32 const& fdoType, bool isXYM);
 
+// ticket #311 - mismatch FdoGeometricTypes and and FdoGeometryType in class creation - eric barby
+// Translate FDO geometry type enumeration to name of PostGIS geometry type.
+// This version accepts flag indicating if XYM dimension is requested.
+std::string PgGeometryTypeFromFdoType(FdoGeometryType *fdoTypes, FdoInt32 length, bool isXYM);
+
 /// Calculate number of ordinates based on given dimensionality.
 ///
 /// \param
Index: fdo/trunk/Providers/PostGIS/Src/Provider/PgTableColumnsReader.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PgTableColumnsReader.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PgTableColumnsReader.cpp	(working copy)
@@ -165,6 +165,41 @@
     return isNullable;
 }
 
+// ticket #171 - Autogenated identity property is mandatory - eric barby
+bool PgTableColumnsReader::IsDefault() const
+{
+  bool   isDefault = false;
+  if (mReader->GetBoolean(L"hasdefault"))
+    isDefault = true;
+  return isDefault;
+}
+
+// ticket #171 - Autogenated identity property is mandatory - eric barby
+FdoStringP PgTableColumnsReader::GetDefault() const
+{
+  FdoStringP   defaultVal = L"";
+  if (IsDefault())
+    defaultVal = mReader->GetString(L"defaultVal");
+  return defaultVal;
+}
+
+// ticket #171 - Autogenated identity property is mandatory - eric barby
+bool PgTableColumnsReader::IsSequence() const
+{
+    if (IsDefault()) {
+      FdoStringP sequence(GetDefault());
+      if (sequence.GetLength() > 0) {
+        FdoStringP const sequenceLow(sequence.Lower());
+        FdoStringP sequenceLeft(sequence.Mid(0,7));
+        if (!sequenceLeft.ICompare("nextval"))
+          return true;
+        if (sequenceLow.Contains(L"nextval")) 
+          return true;
+      }
+    }
+    return false;
+}
+
 bool PgTableColumnsReader::IsPrimaryKey() const
 {
     bool isKey = false;
@@ -194,6 +229,8 @@
     // so it's more portable to use:
     //       a.attnum = ANY (i.indkey)
 
+    // ticket 171 - eric barby - Autogenated identity property is mandatory
+/*
     std::string sql(
         "SELECT a.attnum AS ordinal_position,a.attname AS column_name,"
         "t.typname AS data_type,a.attlen AS character_maximum_length,"
@@ -205,6 +242,20 @@
         "AND c.oid = i.indrelid AND i.indisprimary = 't' "
         "AND t.typname !~ '^geom' "
         "AND c.relname = '" + table + "' AND n.nspname = '" + schema + "' ORDER BY a.attnum;");
+        */
+    std::string sql(
+        "SELECT a.attnum AS ordinal_position, a.attname AS column_name"
+        ",t.typname AS data_type, a.attlen AS character_maximum_length"
+        ",a.atttypmod AS modifier, a.attnotnull AS notnull"
+        ",a.atthasdef AS hasdefault, d.adsrc AS defaultVal"
+        ",a.attnum = ANY (i.indkey) AS isprimarykey, i.indkey AS primKey, i.indisprimary AS indisprimary"
+				" FROM pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.attrelid = d.adrelid"
+        ", pg_type t, pg_namespace n"
+				", pg_class c LEFT OUTER JOIN pg_index i ON i.indrelid = c.oid"
+				" WHERE a.attnum > 0 AND a.attrelid = c.oid"
+				" AND a.atttypid = t.oid AND c.relnamespace = n.oid"
+				" AND t.typname !~ '^geom'"
+				" AND c.relname = '" + table + "' AND n.nspname = '" + schema + "' ORDER BY a.attnum;");
 
     try
     {
Index: fdo/trunk/Providers/PostGIS/Src/Provider/PgTableColumnsReader.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PgTableColumnsReader.h	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PgTableColumnsReader.h	(working copy)
@@ -83,7 +83,19 @@
     
     /// \todo to be documented
     bool GetColumnNullability() const;
-    
+
+    // ticket #171 - Autogenated identity property is mandatory - eric barby
+    // return true if a default value
+    bool PgTableColumnsReader::IsDefault() const;
+
+    // ticket #171 - Autogenated identity property is mandatory - eric barby
+    // return default value
+    FdoStringP PgTableColumnsReader::GetDefault() const;
+
+    // ticket #171 - Autogenated identity property is mandatory - eric barby
+    // Returns true if the column is associated has a sequence
+    bool PgTableColumnsReader::IsSequence() const;
+
     ///
     bool IsPrimaryKey() const;
 
Index: fdo/trunk/Providers/PostGIS/Src/Provider/PgTablesReader.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PgTablesReader.cpp	(revision 0)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PgTablesReader.cpp	(revision 0)
@@ -0,0 +1,468 @@
+//
+// Copyright (C) 2007 Refractions Research, Inc. 
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#include "stdafx.h"
+#include "PostGisProvider.h"
+#include "PgTablesReader.h"
+#include "PgGeometry.h"
+#include "PgUtility.h"
+#include "Connection.h"
+// std
+#include <cassert>
+#include <cstring>
+#include <string>
+// boost
+#include <boost/shared_ptr.hpp>
+#include <boost/lexical_cast.hpp>
+
+// Private utilities
+namespace {
+
+template <typename T>
+T StringConv(char const* value)
+{
+    T ret = T();
+    if (NULL != value && std::strlen(value) > 0)
+    {
+        ret = boost::lexical_cast<T>(value);
+    }
+    return ret;
+}
+
+} // anonymous namespace 
+
+namespace fdo { namespace postgis {
+
+PgTablesReader::PgTablesReader()
+{
+	assert(false);
+}
+
+PgTablesReader::PgTablesReader(Connection* conn)
+    : mConn(conn)
+{
+    FDO_SAFE_ADDREF(mConn.p);
+
+    ValidateConnectionState();
+
+    // Read datastore name representing physical schema in PostgreSQL database.
+    // TODO: Consider replacing it with PostgreSQL function: current_schema()
+    //       Currently, use current_schema() for validation purpose.
+
+    FdoPtr<FdoIConnectionInfo> info = mConn->GetConnectionInfo();
+    FdoPtr<FdoCommonConnPropDictionary> dict = 
+        static_cast<FdoCommonConnPropDictionary*>(info->GetConnectionProperties());
+        
+    FdoStringP dsName = dict->GetProperty(PropertyDatastore);
+    mCurrentSchema = static_cast<char const*>(dsName);
+    
+    // Manually validate current schema
+    // TODO: This validation can be safely removed after testing period
+    //       or leave it if you like it.
+    {
+        boost::shared_ptr<PGresult> pgRes(
+            mConn->PgExecuteQuery("SELECT current_schema()"), PQclear);
+        assert(PGRES_TUPLES_OK == PQresultStatus(pgRes.get()));
+
+        std::string schemaName(PQgetvalue(pgRes.get(), 0, 0));
+        assert(mCurrentSchema == schemaName);
+    }
+}
+
+PgTablesReader::~PgTablesReader()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// FdoIDisposable interface
+///////////////////////////////////////////////////////////////////////////////
+
+void PgTablesReader::Dispose()
+{
+    // This function might throw, do NOT call from the destructor!
+    Close();
+
+    delete this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PgTablesReader interface
+///////////////////////////////////////////////////////////////////////////////
+
+FdoStringP PgTablesReader::GetSchemaName() const
+{
+    return mReader->GetString(L"schemaname");
+}
+
+FdoStringP PgTablesReader::GetTableName() const
+{
+    return mReader->GetString(L"tablename");
+}
+
+    // check if the table has a spatial column
+bool PgTablesReader::CheckSpatialTable() const
+{
+    FDOLOG_MARKER("PgTablesReader::+CheckSpatialTable");
+
+    assert(!mCurrentSchema.empty() && !mTableCached.empty());
+
+    std::string sql("SELECT n.nspname AS schemaname, c.relname AS tablename"
+                    " FROM pg_class c, pg_namespace n, geometry_columns g"
+                    " WHERE c.relkind IN ('r','v') AND c.relname !~ '^(pg_|sql_)'"
+                    " AND c.relnamespace = n.oid AND n.nspname = g.f_table_schema"
+                    " AND c.relname::TEXT = g.f_table_name::TEXT"
+                    " AND n.nspname = '" + mCurrentSchema + "'"
+                    " AND c.relname = '" + mTableCached + "'"
+                    " GROUP BY schemaname, tablename");
+    //BUG ! utiliser QUE des varriable locale
+    // Query spatial tables and attach results to the SQL data reader
+/*--  FdoPtr<FdoISQLCommand> Cmd = static_cast<FdoISQLCommand*>(mConn->CreateCommand(FdoCommandType_SQLCommand));
+    assert(NULL != Cmd);
+    
+    FdoStringP tmp(sql.c_str());
+    Cmd->SetSQLStatement(tmp);
+    
+    FdoPtr<FdoISQLDataReader> reader = Cmd->ExecuteReader();
+    assert(NULL != reader);
+
+    bool hasTuples = reader->ReadNext();
+//  if (NULL != reader) reader->Close();  --*/        
+
+    boost::shared_ptr<PGresult> pgRes(mConn->PgExecuteQuery(sql.c_str()), PQclear);
+    assert(PGRES_TUPLES_OK == PQresultStatus(pgRes.get()));
+    int nb = PQntuples(pgRes.get());
+    bool hasTuples = (nb > 0);
+
+    return hasTuples;
+}
+
+PgTablesReader::columns_t PgTablesReader::GetGeometryColumns() const
+{
+    FDOLOG_MARKER("PgTablesReader::+GetGeometryColumns");
+
+    columns_t columns;
+
+    if (!mTableSpatialCached) {
+      FDOLOG_WRITE("PgTablesReader::-SelectColumnExtent '%s' is not a geometrie table!", mTableCached);
+      return columns;
+    }
+/* 2008/02
+    std::string sql("SELECT g.f_geometry_column, g.type, g.coord_dimension, g.srid "
+                    "FROM geometry_columns g "
+                    "WHERE  g.f_table_schema = '"
+                    + mCurrentSchema +
+                    "' AND g.f_table_name = '"
+                    + mTableCached + "'");
+-*/
+    // because geometry_columns table is out of date after a 'DROP TABLE...' !
+    std::string sql("SELECT g.f_geometry_column, g.type, g.coord_dimension, g.srid"
+	                  " FROM geometry_columns g, pg_attribute a, pg_class c, pg_type t, pg_namespace n"
+                    " WHERE  g.f_table_schema = '" + mCurrentSchema + "'"
+                    " AND g.f_table_name = '" + mTableCached + "'"
+                  	" AND g.f_geometry_column = a.attname "
+	                  " AND a.attnum > 0 "
+	                  " AND a.attrelid = c.oid "
+	                  " AND a.atttypid = t.oid "
+	                  " AND c.relnamespace = n.oid "
+	                  " AND c.relname = g.f_table_name "
+	                  " AND n.nspname = g.f_table_schema "
+	                  " ORDER BY a.attnum");
+
+    // Here, we intentionally DO NOT use FdoISQLCommand to eliminate
+    // unnecessary overhead. It's faster to work as close to libpq API as possible.
+
+    // TODO: Add additional level of try-catch here
+
+    boost::shared_ptr<PGresult> pgRes(mConn->PgExecuteQuery(sql.c_str()), PQclear);
+    assert(PGRES_TUPLES_OK == PQresultStatus(pgRes.get()));
+    assert(4 == PQnfields(pgRes.get()));
+
+    int const ntuples = PQntuples(pgRes.get());
+
+    // Prepare collection for geometry columns
+    columns.reserve(ntuples);
+    
+    //
+    // Read properties of geometry columns in given table
+    //
+    FdoStringP name;
+    FdoGeometryType type = FdoGeometryType_None;
+    FdoInt32 dim = 0;
+    FdoInt32 srid = 0;
+
+    try
+    {
+        for (int ntuple = 0; ntuple < ntuples; ++ntuple)
+        {
+            // 0 - geometry_columns.f_geometry_name
+            name = PQgetvalue(pgRes.get(), ntuple, 0);
+
+            // 1 - geometry_columns.type
+            std::string stype(PQgetvalue(pgRes.get(), ntuple, 1));
+            type = ewkb::FdoGeometryTypeFromPgType(stype);
+
+            // 2 - geometry_columns.coord_dimension
+            char const* cdim = PQgetvalue(pgRes.get(), ntuple, 2);
+            FdoInt32 tmp = boost::lexical_cast<FdoInt32>(cdim);
+            dim = ewkb::FdoDimensionTypeFromPgType(tmp, stype);
+
+            // 3 - geometry_columns.srid
+            char const* csrid = PQgetvalue(pgRes.get(), ntuple, 3);
+            srid = boost::lexical_cast<FdoInt32>(csrid);
+
+            // Estimate bounding box of geometries in given column
+            FdoPtr<FdoEnvelopeImpl> bbox;
+            bbox = EstimateColumnExtent(static_cast<char const*>(name));
+            if (bbox->GetIsEmpty()) 
+            {
+              bbox = SelectColumnExtent(static_cast<char const*>(name));
+              if (bbox->GetIsEmpty()) 
+              {
+                bbox = FdoEnvelopeImpl::Create(0.0, 0.0, 0.0, 0.0);
+              }
+            }
+
+            // Describe geometry column and add to the collection
+            PgGeometryColumn::Ptr col(new PgGeometryColumn(name, type, dim, srid, bbox));
+            columns.push_back(col);
+        }
+
+        FDOLOG_WRITE(" - Number of described columns: %d", columns.size());
+    }
+    catch (boost::bad_lexical_cast& e)
+    {
+        FDOLOG_WRITE("Field value conversion failed: %s", e.what());
+        throw FdoException::Create(L"Error occured while reading schema of geometry column");
+    }
+
+    assert(ntuples == columns.size());
+    return columns;
+}
+
+void PgTablesReader::Open()
+{
+    FDOLOG_MARKER("PgTablesReader::+Open");
+
+    assert(!mCurrentSchema.empty());
+
+    std::string sql("SELECT schemaname, tablename FROM pg_tables"
+				            " WHERE  schemaname='" + mCurrentSchema + "'"
+                    " AND (tablename NOT LIKE 'pg_%')"
+				            " AND (tablename NOT LIKE 'spatial_ref_sys%')"
+				            " AND (tablename NOT LIKE 'sql_%')"
+				            " AND (tablename NOT LIKE 'geom%')"
+				            " ORDER BY tablename");
+    
+    // Query spatial tables and attach results to the SQL data reader
+    mCmd = static_cast<FdoISQLCommand*>(mConn->CreateCommand(FdoCommandType_SQLCommand));
+    assert(NULL != mCmd);
+    
+    FdoStringP tmp(sql.c_str());
+    mCmd->SetSQLStatement(tmp);
+    
+    mReader = mCmd->ExecuteReader();
+    assert(NULL != mReader);
+}
+
+bool PgTablesReader::ReadNext()
+{
+    bool hasTuples = mReader->ReadNext();
+    
+    // Cache table name
+    if (hasTuples)
+    {
+        mTableCached = static_cast<char const*>(GetTableName());
+        mTableSpatialCached = CheckSpatialTable();
+    }
+    
+    return hasTuples;
+}
+
+void PgTablesReader::Close()
+{
+    if (NULL != mReader)
+        mReader->Close();        
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Private operations
+///////////////////////////////////////////////////////////////////////////////
+
+void PgTablesReader::ValidateConnectionState() const
+{
+    if (FdoConnectionState_Closed == mConn->GetConnectionState())
+    {
+        FDOLOG_WRITE("Connection is closed or invalid.");
+
+        throw FdoException::Create(NlsMsgGet(MSG_POSTGIS_CONNECTION_INVALID,
+            "Connection is closed or invalid."));
+    }
+}
+
+FdoPtr<FdoEnvelopeImpl> PgTablesReader::EstimateColumnExtent(
+    std::string const& column) const
+{
+    FDOLOG_MARKER("PgTablesReader::-EstimateColumnExtent");
+    assert(!mCurrentSchema.empty() && !mTableCached.empty());
+
+    if (!mTableSpatialCached) {
+      FDOLOG_WRITE("PgTablesReader::-SelectColumnExtent '%s' is not a geometrie table!", mTableCached );
+      FdoPtr<FdoEnvelopeImpl> extent;
+      FDO_SAFE_ADDREF(extent.p);
+      return extent.p;
+    }
+
+    FDOLOG_WRITE("Geometry column: %s.%s.%s", mCurrentSchema.c_str(), 
+        mTableCached.c_str(), column.c_str());
+
+    // Query estimating spatial extent for given geometry column using table statistics.
+    // For PostgreSQL>=8.0.0 statistics are gathered by VACUUM ANALYZE and resulting
+    // extent will be about 95% of the real one.
+
+    std::string sql("SELECT xmin(env), ymin(env), xmax(env), ymax(env) FROM ("
+                     " SELECT estimated_extent('"
+                     + mCurrentSchema + "', '"
+                     + mTableCached + "', '"
+                     + column + "') AS env) AS extentsub");
+
+    // NOTE: The PgExecuteQuery throws on error, but if no exception occurs,
+    //       valid query result is assumed.
+
+    boost::shared_ptr<PGresult> pgRes(mConn->PgExecuteQuery(sql.c_str()), PQclear);
+    assert(PGRES_TUPLES_OK == PQresultStatus(pgRes.get()));
+    assert(1 == PQntuples(pgRes.get()));
+    try
+    {
+        bool    nullVal = false;
+        char const* cval = NULL;
+        
+        // X MIN
+        cval = PQgetvalue(pgRes.get(), 0, 0);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double xmin = StringConv<double>(cval);
+        // Y MIN
+        cval = PQgetvalue(pgRes.get(), 0, 1);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double ymin = StringConv<double>(cval);
+        // X MAX
+        cval = PQgetvalue(pgRes.get(), 0, 2);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double xmax = StringConv<double>(cval);
+        // Y MAX
+        cval = PQgetvalue(pgRes.get(), 0, 3);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double ymax = StringConv<double>(cval);
+
+        // Build spatial envelope object
+        FdoPtr<FdoEnvelopeImpl> extent;
+        if (!nullVal) 
+        {
+          extent = FdoEnvelopeImpl::Create(xmin, ymin, xmax, ymax);
+          FDOLOG_WRITE("Extent:\n\txmin = %.8f\n\tymin = %.8f\n\txmax = %.8f\n\tymax = %.8f",
+              xmin, ymin, xmax, ymax);
+        } 
+        else 
+        {
+          extent = FdoEnvelopeImpl::Create(); // create empty envelope!
+          FDOLOG_WRITE("Warning! estimated_extent is empty! use VACUUM or ANALYZE");
+        }
+
+        FDO_SAFE_ADDREF(extent.p);
+        return extent.p;
+    }
+    catch (boost::bad_lexical_cast& e)
+    {
+        FDOLOG_WRITE("Extent coordinate value conversion failed: %s", e.what());
+        throw FdoException::Create(L"Error occured while reading coordinate of estimated extent");
+    }
+}
+
+FdoPtr<FdoEnvelopeImpl> PgTablesReader::SelectColumnExtent(
+    std::string const& column) const
+{
+    FDOLOG_MARKER("PgTablesReader::-SelectColumnExtent");
+    assert(!mCurrentSchema.empty() && !mTableCached.empty());
+
+    if (!mTableSpatialCached) {
+      FDOLOG_WRITE("PgTablesReader::-SelectColumnExtent '%s' is not a geometrie table!", mTableCached );
+      FdoPtr<FdoEnvelopeImpl> extent;
+      FDO_SAFE_ADDREF(extent.p);
+      return extent.p;
+    }
+
+    FDOLOG_WRITE("Geometry column: %s.%s.%s", mCurrentSchema.c_str(), 
+        mTableCached.c_str(), column.c_str());
+
+    // Query estimating spatial extent for given geometry column using table statistics.
+    // For PostgreSQL>=8.0.0 statistics are gathered by VACUUM ANALYZE and resulting
+    // extent will be about 95% of the real one.
+
+    std::string sql("SELECT xmin(box.extent), xmin(box.extent), xmax(box.extent), ymax(box.extent) "
+                     "FROM ( SELECT extent(" + column + ") FROM "
+                     + mCurrentSchema + "."+ mTableCached // TODO add mBaseName
+                     + ") AS box");
+
+    // NOTE: The PgExecuteQuery throws on error, but if no exception occurs,
+    //       valid query result is assumed.
+
+    boost::shared_ptr<PGresult> pgRes(mConn->PgExecuteQuery(sql.c_str()), PQclear);
+    assert(PGRES_TUPLES_OK == PQresultStatus(pgRes.get()));
+    assert(1 == PQntuples(pgRes.get()));
+    try
+    {
+        bool    nullVal = false;
+        char const* cval = NULL;
+        
+        // X MIN
+        cval = PQgetvalue(pgRes.get(), 0, 0);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double xmin = StringConv<double>(cval);
+        // Y MIN
+        cval = PQgetvalue(pgRes.get(), 0, 1);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double ymin = StringConv<double>(cval);
+        // X MAX
+        cval = PQgetvalue(pgRes.get(), 0, 2);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double xmax = StringConv<double>(cval);
+        // Y MAX
+        cval = PQgetvalue(pgRes.get(), 0, 3);
+        if (!cval || !strlen(cval)) nullVal = true;
+        double ymax = StringConv<double>(cval);
+
+        // Build spatial envelope object
+        FdoPtr<FdoEnvelopeImpl> extent;
+        if (!nullVal)
+        {
+          FDOLOG_WRITE("Extent:\n\txmin = %.8f\n\tymin = %.8f\n\txmax = %.8f\n\tymax = %.8f",
+            xmin, ymin, xmax, ymax);
+          extent = FdoEnvelopeImpl::Create(xmin, ymin, xmax, ymax);
+        } else  {
+          extent = FdoEnvelopeImpl::Create(); // create empty envelope!
+          FDOLOG_WRITE("Warning! No Extent selectd!");
+        }
+
+        FDO_SAFE_ADDREF(extent.p);
+        return extent.p;
+    }
+    catch (boost::bad_lexical_cast& e)
+    {
+        FDOLOG_WRITE("Extent coordinate value conversion failed: %s", e.what());
+        throw FdoException::Create(L"Error occured while select coordinate of extent");
+    }
+}
+
+}} // namespace fdo::postgis

Property changes on: fdo\trunk\Providers\PostGIS\Src\Provider\PgTablesReader.cpp
___________________________________________________________________
Name: svn:eol-style
   + native

Index: fdo/trunk/Providers/PostGIS/Src/Provider/PgTablesReader.h
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PgTablesReader.h	(revision 0)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PgTablesReader.h	(revision 0)
@@ -0,0 +1,149 @@
+//
+// Copyright (C) 2007 Refractions Research, Inc. 
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of version 2.1 of the GNU Lesser
+// General Public License as published by the Free Software Foundation.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#ifndef FDOPOSTGIS_PGTABLESREADER_H_INCLUDED
+#define FDOPOSTGIS_PGTABLESREADER_H_INCLUDED
+
+#include "Connection.h"
+#include "SQLDataReader.h"
+#include "PgGeometryColumn.h"
+// FDO
+#include <Fdo/Commands/Sql/ISQLCommand.h>
+// std
+#include <string>
+#include <vector>
+// boost
+#include <boost/noncopyable.hpp>
+
+namespace fdo { namespace postgis {
+
+/// Implementation of reader for PostGIS spatial tables and alpha table.
+/// Tables are read using current connection established to a FDO datastore.
+/// This class is dedicated for <strong>internal use only</strong> and
+/// it's <strong>not</strong> exposed to FDO clients.
+///
+class PgTablesReader :
+    public FdoIDisposable,
+    private boost::noncopyable
+{
+public:
+
+    /// Type of FDO smart pointer for the class.
+    typedef FdoPtr<PgTablesReader> Ptr;
+    
+    /// Type of geometry columns collection
+    typedef std::vector<PgGeometryColumn::Ptr> columns_t;
+    
+    /// Constructor creates new reader instance associated with given connection.
+    PgTablesReader(Connection* conn);
+
+    /// Get name of schema to which table belongs.
+    FdoStringP GetSchemaName() const;
+    
+    /// Get name of table.
+    FdoStringP GetTableName() const;
+
+    // check if the table has a spatial column
+    bool CheckSpatialTable() const;
+    bool IsSpatialTable() const { return mTableSpatialCached; }
+
+    /// Get collection of geometry columns.
+    /// Every column is described by following elements:
+    ///  - name
+    ///  - coordinates dimension
+    ///  - geometry type
+    ///  - SRID
+    columns_t GetGeometryColumns() const;
+    
+    /// Open tables reader.
+    /// This operation mimics FDO command usually creating instance of a reader.
+    /// There is no command dedicated for PgSpatialTableReader instantiation,
+    /// so this function behaves like a command preparing reader instance.
+    void Open();
+
+    /// Advance the reader to next spatial table.
+    /// \return
+    /// true if there is another table to read or false if iterator reached
+    /// end of the result set.
+    bool ReadNext();
+    
+    /// Close reader instance releasing all associated resources.
+    void Close();
+    
+protected:
+
+	/// Default constructor (DO NOT USE -- Only defined to make Linux Build Happy).
+    PgTablesReader();
+
+	/// Destructor closes reader on destroy.
+    virtual ~PgTablesReader();
+
+    //
+    // FdoIDisposable interface
+    //
+
+    /// Dispose this object.
+    void Dispose();
+
+private:
+
+    //
+    // Private data members
+    //
+    
+    // Handle to connection for current session.
+    Connection::Ptr mConn;
+    
+    // Handle to result reader used internally.
+    // The PgTablesReader forwards calls to the SQLDataReader.
+    //SQLDataReader::Ptr mReader;
+    FdoPtr<FdoISQLDataReader> mReader;
+    
+    // Command used internally to feed reader with query results.
+    FdoPtr<FdoISQLCommand> mCmd;
+    
+    // Name of current PostgreSQL schema (FDO datastore).
+    std::string mCurrentSchema;
+    
+    // Name of a table currently read and cached.
+    std::string mTableCached;
+
+    // table currently read is type spatial
+    bool mTableSpatialCached;
+
+    //
+    // Private operations
+    //
+    
+    // Validates basic state of the reader instance.
+    void ValidateConnectionState() const;
+
+    // Executes query to estimate spatial extent of features
+    // in given geometry column in a table.
+    // Table is used with full path: schema.table.
+    FdoPtr<FdoEnvelopeImpl> EstimateColumnExtent(
+        std::string const& column) const;
+
+    // Executes query to select spatial extent of features
+    // in given geometry column in a table.
+    // Table is used with full path: schema.table.
+    FdoPtr<FdoEnvelopeImpl> SelectColumnExtent(
+        std::string const& column) const;
+};
+
+}} // namespace fdo::postgis
+
+#endif // FDOPOSTGIS_PGTABLESREADER_H_INCLUDED

Property changes on: fdo\trunk\Providers\PostGIS\Src\Provider\PgTablesReader.h
___________________________________________________________________
Name: svn:eol-style
   + native

Index: fdo/trunk/Providers/PostGIS/Src/Provider/PostGisProvider.vcproj
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/PostGisProvider.vcproj	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/PostGisProvider.vcproj	(working copy)
@@ -580,19 +580,19 @@
 				>
 			</File>
 			<File
-				RelativePath=".\PgSpatialTablesReader.cpp"
+				RelativePath=".\PgTableColumnsReader.cpp"
 				>
 			</File>
 			<File
-				RelativePath=".\PgSpatialTablesReader.h"
+				RelativePath=".\PgTableColumnsReader.h"
 				>
 			</File>
 			<File
-				RelativePath=".\PgTableColumnsReader.cpp"
+				RelativePath=".\PgTablesReader.cpp"
 				>
 			</File>
 			<File
-				RelativePath=".\PgTableColumnsReader.h"
+				RelativePath=".\PgTablesReader.h"
 				>
 			</File>
 			<File
Index: fdo/trunk/Providers/PostGIS/Src/Provider/SchemaDescription.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/SchemaDescription.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/SchemaDescription.cpp	(working copy)
@@ -20,7 +20,10 @@
 #include "SchemaDescription.h"
 #include "SpatialContextCollection.h"
 #include "PgGeometryColumn.h"
-#include "PgSpatialTablesReader.h"
+//ticket #236 - does not support non spatial classes - eric barby
+//PgSpatialTablesReader has been replaced by PgTablesReader
+#include "PgTablesReader.h"
+//#include "PgSpatialTablesReader.h"
 #include "PgTableColumnsReader.h"
 #include "PgUtility.h"
 // std
@@ -187,100 +190,119 @@
     //
     // Process every table to FDO class
     //
-    PgSpatialTablesReader::Ptr stReader(new PgSpatialTablesReader(mConn.p));
+    //ticket #236 - does not support non spatial classes - eric barby
+    PgTablesReader::Ptr stReader(new PgTablesReader(mConn.p));
+    //PgSpatialTablesReader::Ptr stReader(new PgSpatialTablesReader(mConn.p));
     stReader->Open();
 
     while (stReader->ReadNext())
     {
-        // TODO: Fetch all geometries, but not only the first one - default
-
-        PgSpatialTablesReader::columns_t::size_type const geometryIdx = 0;
-        PgSpatialTablesReader::columns_t geometryColumns(stReader->GetGeometryColumns());
-        PgGeometryColumn::Ptr geomColumn = geometryColumns[geometryIdx];
-
-        ////////////////// GENERATE SPATIAL CONTEXT //////////////////
-
-        FdoStringP spContextName(SpatialContextDefaultName);
-        FdoInt32 srid = geomColumn->GetSRID();
-        if (srid >= 0)
-        {
-            spContextName = FdoStringP::Format(L"PostGIS_%d", srid);
-        }
-        
-        SpatialContext::Ptr spContext;
-        spContext = spContexts->FindItem(spContextName);
-        if (NULL == spContext)
-        {
-            spContext = CreateSpatialContext(mConn, spContextName, geomColumn);
-            spContexts->Add(spContext);
-
-            FDOLOG_WRITE(L"Created spatial context: %s",
-                static_cast<FdoString*>(spContextName));
-        }
-
         ////////////////// CALCULATE SPATIAL EXTENT //////////////////
 
         // TODO: Do we want to calculate bbox at all?
+        // already in stReader->GetGeometryColumns() {
+        //     PgSpatialTablesReader::EstimateColumnExtent()
+        //  or PgSpatialTablesReader::SelectColumnExtent()
+        // }
 
         ////////////////// GENERATE CLASS DEFINITION //////////////////
 
+        FdoStringP fdoClassName=stReader->GetTableName();
+        //ticket #310 - class naming convention wihout ~ - eric barby
         // TODO: Do we need to have geometry column name in FDO class name?
-        FdoStringP fdoClassName = FdoStringP::Format(L"%s~%s",
-            static_cast<FdoString*>(stReader->GetSchemaName()),
-            static_cast<FdoString*>(stReader->GetTableName()));
+        //fdoClassName = FdoStringP::Format(L"%s~%s",
+        //    static_cast<FdoString*>(stReader->GetSchemaName()),
+        //    static_cast<FdoString*>(stReader->GetTableName() ));
         assert(!featClasses->FindItem(fdoClassName));
 
         // TODO: Use table COMMENT as a class description
-        FdoPtr<FdoFeatureClass> featClass = FdoFeatureClass::Create(fdoClassName, L"");      
-
+        //ticket #236 - does not support non spatial classes - eric barby
+        FdoPtr<FdoClassDefinition> xClass;
+        if (stReader->IsSpatialTable()) {
+          xClass = FdoFeatureClass::Create(fdoClassName, L"");      
+          FDOLOG_WRITE(L"Created feature class: %s", static_cast<FdoString*>(fdoClassName));
+        } else {
+          xClass = FdoClass::Create(fdoClassName, L"");      
+          FDOLOG_WRITE(L"Created class: %s", static_cast<FdoString*>(fdoClassName));
+        }
         // Physical mapping for the feature class
         ov::ClassDefinition::Ptr classDef = ov::ClassDefinition::Create();
         classDef->SetName(fdoClassName);
+        classDef->SetSchemaName(stReader->GetSchemaName());
 
-        FdoPtr<FdoPropertyDefinitionCollection> pdc = featClass->GetProperties();
+        FdoPtr<FdoPropertyDefinitionCollection> pdc = xClass->GetProperties();
 
-        FDOLOG_WRITE(L"Created feature class: %s", static_cast<FdoString*>(fdoClassName));
+        if (stReader->IsSpatialTable()) 
+        {
+          // TODO: Fetch all geometries, but not only the first one - default
 
-        ////////////////// CREATE GEOMETRY PROPERTY //////////////////
+          PgTablesReader::columns_t::size_type const geometryIdx = 0;
+          PgTablesReader::columns_t geometryColumns(stReader->GetGeometryColumns());
+          PgGeometryColumn::Ptr geomColumn = geometryColumns[geometryIdx];
 
-        FdoGeometryType geomType = geomColumn->GetGeometryType();
+          ////////////////// GENERATE SPATIAL CONTEXT //////////////////
 
-        FdoPtr<FdoGeometricPropertyDefinition> geomPropDef;
-        geomPropDef = FdoGeometricPropertyDefinition::Create(
-            geomColumn->GetName(), geomColumn->GetDescription());                        
+          FdoStringP spContextName(SpatialContextDefaultName);
+          FdoInt32 srid = geomColumn->GetSRID();
+          if (srid >= 0)
+          {
+              spContextName = FdoStringP::Format(L"PostGIS_%d", srid);
+          }
+          
+          SpatialContext::Ptr spContext;
+          spContext = spContexts->FindItem(spContextName);
+          if (NULL == spContext)
+          {
+              spContext = CreateSpatialContext(mConn, spContextName, geomColumn);
+              //ticket #94 - Generate extent for features assigned to default spatial context - eric barby
+              spContext->SetExtent(static_cast<FdoEnvelopeImpl*>(geomColumn->GetEnvelope()));
+              spContexts->Add(spContext);
 
-        // General geometry type mask
-        FdoInt32 geometricType = 
-            FdoGeometricType_Point|FdoGeometricType_Curve|FdoGeometricType_Surface;
+              FDOLOG_WRITE(L"Created spatial context: %s",
+                  static_cast<FdoString*>(spContextName));
+          }
 
-        // Try to match specific geometry type
-        if (FdoGeometryType_Point == geomType
-            || FdoGeometryType_MultiPoint == geomType)
-        {
-            geometricType = FdoGeometricType_Point;
-        }
-        else if (FdoGeometryType_LineString == geomType
-                 || FdoGeometryType_MultiLineString == geomType)
-        {
-            geometricType = FdoGeometricType_Curve;
-        }
-        else if (FdoGeometryType_Polygon == geomType
-                 || FdoGeometryType_MultiPolygon == geomType)
-        {
-            geometricType = FdoGeometricType_Surface;
-        }
+          ////////////////// CREATE GEOMETRY PROPERTY //////////////////
 
-        geomPropDef->SetGeometryTypes(geometricType);  
-        if (NULL != spContext)
-        {
-            geomPropDef->SetSpatialContextAssociation(spContext->GetName());
-        }
-        pdc->Add(geomPropDef);
-        featClass->SetGeometryProperty(geomPropDef);
+          FdoGeometryType geomType = geomColumn->GetGeometryType();
 
-        FDOLOG_WRITE(L"+ geometric property: %s",
-            static_cast<FdoString*>(geomColumn->GetName()));
+          FdoPtr<FdoGeometricPropertyDefinition> geomPropDef;
+          geomPropDef = FdoGeometricPropertyDefinition::Create(
+              geomColumn->GetName(), geomColumn->GetDescription());                        
 
+          // General geometry type mask
+          FdoInt32 geometricType = 
+              FdoGeometricType_Point|FdoGeometricType_Curve|FdoGeometricType_Surface;
+
+          // Try to match specific geometry type
+          if (FdoGeometryType_Point == geomType
+              || FdoGeometryType_MultiPoint == geomType)
+          {
+              geometricType = FdoGeometricType_Point;
+          }
+          else if (FdoGeometryType_LineString == geomType
+                   || FdoGeometryType_MultiLineString == geomType)
+          {
+              geometricType = FdoGeometricType_Curve;
+          }
+          else if (FdoGeometryType_Polygon == geomType
+                   || FdoGeometryType_MultiPolygon == geomType)
+          {
+              geometricType = FdoGeometricType_Surface;
+          }
+
+          geomPropDef->SetGeometryTypes(geometricType);  
+          if (NULL != spContext)
+          {
+              geomPropDef->SetSpatialContextAssociation(spContext->GetName());
+          }
+          pdc->Add(geomPropDef);
+          (dynamic_cast<FdoFeatureClass*>(xClass.p))->SetGeometryProperty(geomPropDef);
+
+          FDOLOG_WRITE(L"+ geometric property: %s",
+              static_cast<FdoString*>(geomColumn->GetName()));
+        }//if stReader->IsSpatialTable()
+
         ////////////////// CREATE DATA PROPERTIES //////////////////
 
         PgTableColumnsReader::Ptr tcReader =
@@ -290,9 +312,16 @@
         
         while(tcReader->ReadNext())
         {
+          FdoStringP colName(tcReader->GetColumnName());
+          if (pdc->FindItem(colName)) 
+          { // eric barby - because  is out of date after a remove thisTable 'DROP TABLE...' !
+            FDOLOG_WRITE("ERROR: Table '%s' PropertyDefinition '%s' is already in the PropertyDefinitionCollection", stReader->GetTableName(), colName);
+          } 
+          else 
+          {
             FdoPtr<FdoDataPropertyDefinition> datPropDef;
             datPropDef = FdoDataPropertyDefinition::Create(
-                tcReader->GetColumnName(), tcReader->GetColumnDescription());
+              colName, tcReader->GetColumnDescription());
 
             FDOLOG_WRITE(L"+ data property: %s",
                 static_cast<FdoString*>(tcReader->GetColumnName()));
@@ -308,6 +337,13 @@
             bool const isNullable = tcReader->GetColumnNullability();
             datPropDef->SetNullable(isNullable);
 
+            // eric barby - add default value.
+            if (tcReader->IsDefault()) {
+              FdoStringP defaultVal(tcReader->GetDefault());
+              if (defaultVal.GetLength())
+                datPropDef->SetDefaultValue(defaultVal);
+            }
+
             // First, it's required to add property to the base collection.
             // So, it can be add to the identity properties in next step,
             // if required.
@@ -319,15 +355,21 @@
                 FDOLOG_WRITE(" - PRIMARY KEY");
 
                 FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity;
-                propsIdentity = featClass->GetIdentityProperties();
+                propsIdentity = xClass->GetIdentityProperties();
                 assert(NULL != propsIdentity);
 
                 datPropDef->SetNullable(false);
                 propsIdentity->Add(datPropDef);
+
+                // 2008-02 add correct sequence information. 
+                bool const isSequence = tcReader->IsSequence();
+                datPropDef->SetIsAutoGenerated(isSequence);
             }
+          }
         }
         tcReader->Close();
 
+        //ticket #171 - Autogenated identity property is mandatory - eric barby
         ////////////////// SET AUTO-GENERATED TO SINGLE COLUMN PK OF INTEGRAL TYPE //////////////////
 
         // TODO: It is possible, that user connects to a datastore that was not created
@@ -338,9 +380,10 @@
 
         // TODO: In future, it would be a good idea to automatically
         // replace PK of integral type with serial data type, in ApplySchema command.
-
+        
+        /*-- 2008-02 eb: Deleted by barby
         FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity;
-        propsIdentity = featClass->GetIdentityProperties();
+        propsIdentity = xClass->GetIdentityProperties();
         if (1 == propsIdentity->GetCount())
         {
             FdoPtr<FdoDataPropertyDefinition> propId = propsIdentity->GetItem(0);
@@ -352,24 +395,23 @@
             {
                 propId->SetIsAutoGenerated(true);
             }
-        }
+        } -*/
 
         //
         // Add Feature Class and Class Definition to collections
         //
-        featClasses->Add(featClass);
+        featClasses->Add(xClass);
         phClasses->Add(classDef);
-
     } // while
 
     stReader->Close();
 
-
     //
     // Compose the Schema Description aggregation
     //
     assert(NULL != logicalSchemas);
     assert(NULL != phClasses);
+    featSchema->AcceptChanges();
 
     SetLogicalSchemas(logicalSchemas);
     SetSchemaMapping(schemaMapping);
@@ -410,7 +452,7 @@
     //
     // Query for SRS details
     //
-    FdoInt32 srid = -1;
+    FdoInt32 srid =  -1;
     std::string sridText;
     try
     {
Index: fdo/trunk/Providers/PostGIS/Src/Provider/SelectAggregatesCommand.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/SelectAggregatesCommand.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/SelectAggregatesCommand.cpp	(working copy)
@@ -129,8 +129,11 @@
 
 FdoIDataReader* SelectAggregatesCommand::Execute()
 {
-    FDOLOG_MARKER("SelectAggregatesCommand::+Execute");
+  FDOLOG_MARKER("SelectAggregatesCommand::+Execute");
 
+  //ticket #241 - Implement Support for SelectAggregates, SpatialExtents and Count - eric barby
+  try
+  {
     //////////////////////////////////////////////////////////////
     // TODO: Refactor this big function into smaller procedures
     //////////////////////////////////////////////////////////////
@@ -138,8 +141,15 @@
     //
     // Collect schema details
     //
-    FdoPtr<FdoFeatureSchemaCollection> logicalSchemas;
-    logicalSchemas = mConn->GetLogicalSchema();
+    // eric barby - why not use mConn->DescribeSchema() / mConn->GetLogicalSchema()
+    //     and use mConn->GetPhysicalSchemaMapping() ?
+    FdoFeatureSchemaCollection *logicalSchemas = mConn->GetLogicalSchema();
+    if (!logicalSchemas) 
+    {
+        throw FdoCommandException::Create(L"[PostGIS] SelectCommand can not find schema definition");
+    }
+    //FdoPtr<FdoFeatureSchemaCollection> logicalSchemas;
+    //logicalSchemas = mConn->GetLogicalSchema();
 
     FDOLOG_WRITE(L"Number of logical schemas: %d", logicalSchemas->GetCount());
 
@@ -163,7 +173,7 @@
     {
         FdoStringP msg =
             FdoStringP::Format(L"Logical schema for '%s' not found", 
-            static_cast<FdoString*>(classId));
+                               static_cast<FdoString*>(classId));
         FDOLOG_WRITE("ERROR: %s", static_cast<char const*>(msg));
         throw FdoCommandException::Create(msg);
     }
@@ -174,7 +184,7 @@
     {
         FdoStringP msg =
             FdoStringP::Format(L"No class definition found for schema '%s'", 
-            static_cast<FdoString*>(classId));
+                               static_cast<FdoString*>(classId));
         FDOLOG_WRITE("ERROR: %s", static_cast<char const*>(msg));
         throw FdoCommandException::Create(msg);
     }
@@ -200,7 +210,7 @@
     {
         FdoStringP msg =
             FdoStringP::Format(L"Physical schema for '%s' not found", 
-            static_cast<FdoString*>(className));
+                               static_cast<FdoString*>(className));
         FDOLOG_WRITE("ERROR: %s", static_cast<char const*>(msg));
         throw FdoCommandException::Create(msg);
     }
@@ -212,22 +222,26 @@
     // Build SELECT clause
     //
     std::string sep;
-    std::string sqlSelect;
+    std::string sqlSelect("");
+    FdoPtr<FdoPropertyDefinitionCollection> props = classDef->GetProperties();
+    FdoInt32 currentSrid = GetSRID(props);
 
     FilterProcessor::Ptr filterProc(new FilterProcessor());
     ExpressionProcessor::Ptr exprProc(new ExpressionProcessor());
 
+    FDOLOG_WRITE("Number of properties: %d", mProperties->GetCount());
+
     // TODO: What should we do if mProperties is NULL?
     FdoInt32 const propsSize = mProperties->GetCount();
-
-    for (FdoInt32 i = 0; i < propsSize; i++)
+  
+    for (FdoInt32 propIdx = 0; propIdx < propsSize; propIdx++)
     {
-        FdoPtr<FdoIdentifier> id(mProperties->GetItem(i));
+        FdoPtr<FdoIdentifier> id(mProperties->GetItem(propIdx));
 
         if (NULL != dynamic_cast<FdoComputedIdentifier*>(id.p))
         {
             // Parse complex computed expression and identifier
-
+          
             FdoComputedIdentifier* compId = NULL;
             compId = dynamic_cast<FdoComputedIdentifier*>(id.p);
             
@@ -258,6 +272,7 @@
 
             FdoStringP name(id->GetName());
             sqlSelect.append(sep + static_cast<char const*>(name));
+
         }
 
         sep = ",";
@@ -287,10 +302,23 @@
     //
     // Build WHERE or HAVING clause
     //
+    //ticket #241 - Implement Support for SelectAggregates, SpatialExtents and Count - eric barby
     std::string sqlWhere;
     std::string sqlHaving;
 
+    //
+    // Process filter conditions
+    //
+    //ticket #241 - Implement Support for SelectAggregates, SpatialExtents and Count - eric barby
+    if (NULL != mFilter)
+    {
+        FDOLOG_WRITE("Configuring filter");
 
+        FilterProcessor::Ptr proc(new FilterProcessor(currentSrid));
+        mFilter->Process(proc);
+        sqlWhere = proc->GetFilterStatement();
+    }
+
     //
     // Compile final SQL query
     //
@@ -314,7 +342,31 @@
         sql.append(" HAVING " + sqlHaving);
     }    
 
+    // 3 - ORDER BY clause
+    //ticket #241 - Implement Support for SelectAggregates, SpatialExtents and Count - eric barby
+    FdoPtr<FdoIdentifierCollection> orderingColumns = GetOrdering();
+    FdoInt32 const orderingCount = orderingColumns->GetCount();
+    if (orderingCount > 0)
+    {
+        std::string sep("");
+        sql.append(" ORDER BY ");
 
+        for (FdoInt32 i = 0; i < orderingCount; ++i)
+        {
+            FdoPtr<FdoIdentifier> id(orderingColumns->GetItem(i));
+            FdoStringP name(id->GetName());
+
+            sql.append(sep + static_cast<char const*>(name));
+
+            if (FdoOrderingOption_Ascending == GetOrderingOption())
+                sql.append(" ASC ");
+            else
+                sql.append(" DESC ");
+
+            sep = ",";
+        }
+    }
+
     //
     // Declare cursor and create feature reader
     //
@@ -335,6 +387,17 @@
 
     FDO_SAFE_ADDREF(reader.p);
     return reader.p;
+  }
+  catch (FdoException* e)
+  {
+      FDOLOG_WRITE("ERROR: The execution of Select Aggregates command failed.");
+
+      FdoCommandException* ne = NULL;
+      ne = FdoCommandException::Create(NlsMsgGet(MSG_POSTGIS_COMMAND_SELECT_FAILED,
+              "The execution of Select Aggregates command failed."), e);
+      e->Release();
+      throw ne;
+  }
 }
 
 }} // namespace fdo::postgis
Index: fdo/trunk/Providers/PostGIS/Src/Provider/SelectCommand.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/SelectCommand.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/SelectCommand.cpp	(working copy)
@@ -152,8 +152,15 @@
         //
         // Get Logical Schema
         //
-        FdoPtr<FdoFeatureSchemaCollection> logicalSchemas;
-        logicalSchemas = mConn->GetLogicalSchema();
+        // eric barby - why not use mConn->DescribeSchema() / mConn->GetLogicalSchema()
+        //     and use mConn->GetPhysicalSchemaMapping() ?
+        FdoFeatureSchemaCollection *logicalSchemas = mConn->GetLogicalSchema();
+        if (!logicalSchemas) 
+        {
+            throw FdoCommandException::Create(L"[PostGIS] SelectCommand can not find schema definition");
+        }
+        //FdoPtr<FdoFeatureSchemaCollection> logicalSchemas;
+        //logicalSchemas = mConn->GetLogicalSchema();
 
         FDOLOG_WRITE(L"Number of logical schemas: %d", logicalSchemas->GetCount());
 
@@ -226,6 +233,7 @@
         // Read properties definition to SQL columns
         //
         FdoInt32 currentSrid = 0;
+        std::string sep;
         std::string sqlColumns("");
         FdoPtr<FdoPropertyDefinitionCollection> props = classDef->GetProperties();
         
@@ -260,15 +268,11 @@
             // Add property to columns list
             FdoStringP propName(propDef->GetName());
 
-            if (propIdx > 0)
-            {
-                sqlColumns += ',';
-            }
-            sqlColumns += tablePath;
-            sqlColumns += '.';
-            sqlColumns += static_cast<char const*>(propName);
+            sqlColumns.append(sep + tablePath + '.' + static_cast<char const*>(propName));
 
             FDOLOG_WRITE("\t- %s", static_cast<char const*>(propName));
+    
+            sep = ",";
         }
 
         //
Index: fdo/trunk/Providers/PostGIS/Src/Provider/SQLDataReader.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/SQLDataReader.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/SQLDataReader.cpp	(working copy)
@@ -25,9 +25,10 @@
 #include <cstdio> // scanf()
 #include <sstream>
 #include <string>
+//ticket #312 - remove BoostDateTime dependency - eric barby
 // boost
-#include <boost/date_time/gregorian/gregorian.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
+//  #include <boost/date_time/gregorian/gregorian.hpp>
+//  #include <boost/date_time/posix_time/posix_time.hpp>
 
 namespace fdo { namespace postgis {
 
@@ -241,12 +242,12 @@
         {
             return FdoDateTime();
         }
-
         try
         {
-            using namespace boost::gregorian;
-            using namespace boost::posix_time;
-            
+            //ticket #312 - remove BoostDateTime dependency - eric barby
+            //using namespace boost::gregorian;
+            //using namespace boost::posix_time;
+
             // NOTE: We expect the default SQL date and time output defined in ISO 8601.
             //       http://en.wikipedia.org/wiki/ISO_8601
 
@@ -258,8 +259,10 @@
             if (std::string::npos != sval.find_first_of('-')
                 && std::string::npos != sval.find_first_of(':'))
             {
-                // Accepted forma is:
+                // Accepted format is:
+                // [YYYY]-[MM]-[DD] [hh]:[mm]:[ss]
                 // [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss]±[hh]:[mm]
+                // for tolerate T use *[Tt ]
 
                 int y, m, d, hh, mm, ss;
                 y = m = d = hh = mm = ss = 0;
@@ -278,23 +281,46 @@
             }
             else if (std::string::npos != sval.find_first_of('-') && sval.size() <= 12)
             {
-                date d(from_simple_string(sval));
+                //ticket #312 - remove BoostDateTime dependency - eric barby
+                //date d(from_simple_string(sval));
+                //fdt.year = static_cast<FdoInt16>(d.year());
+                //fdt.month = static_cast<FdoInt8>(d.month());
+                //fdt.day = static_cast<FdoInt8>(d.day());
+                // Accepted format is:
+                // [YYYY]-[MM]-[DD]
+                int y, m, d;
+                y = m = d;
+                int const count = std::sscanf(sval.c_str(),
+                    "%4d-%02d-%02d", &y, &m, &d);
+                assert(3 == count);
 
-                fdt.year = static_cast<FdoInt16>(d.year());
-                fdt.month = static_cast<FdoInt8>(d.month());
-                fdt.day = static_cast<FdoInt8>(d.day());
-
+                fdt.year = static_cast<FdoInt16>(y);
+                fdt.month = static_cast<FdoInt8>(m);
+                fdt.day = static_cast<FdoInt8>(d);                
                 assert(fdt.IsDate());
             }
             else if (std::string::npos != sval.find_first_of(':'))
             {
-                ptime t(time_from_string(sval));
-                time_duration td(t.time_of_day());
+                //ticket #312 - remove BoostDateTime dependency - eric barby
+                //ptime t(time_from_string(sval));
+                //time_duration td(t.time_of_day());
+                //
+                //fdt.hour = static_cast<FdoInt8>(td.hours());
+                //fdt.minute = static_cast<FdoInt8>(td.minutes());
+                //fdt.seconds = static_cast<FdoFloat>(td.seconds());
 
-                fdt.hour = static_cast<FdoInt8>(td.hours());
-                fdt.minute = static_cast<FdoInt8>(td.minutes());
-                fdt.seconds = static_cast<FdoFloat>(td.seconds());
+                // Accepted format is:
+                // [hh]:[mm]:[ss]
 
+                int y, m, d, hh, mm, ss;
+                y = m = d = hh = mm = ss = 0;
+                int const count = std::sscanf(sval.c_str(),
+                    "%02d:%02d:%02d", &hh, &mm, &ss);
+                assert(3 == count);
+
+                fdt.hour = static_cast<FdoInt8>(hh);
+                fdt.minute = static_cast<FdoInt8>(mm);
+                fdt.seconds = static_cast<FdoFloat>(ss);
                 assert(fdt.IsTime());
             }
             else
Index: fdo/trunk/Providers/PostGIS/Src/Provider/UpdateCommand.cpp
===================================================================
--- fdo/trunk/Providers/PostGIS/Src/Provider/UpdateCommand.cpp	(revision 1)
+++ fdo/trunk/Providers/PostGIS/Src/Provider/UpdateCommand.cpp	(working copy)
@@ -64,17 +64,24 @@
     //
     // Collect schema details required to build SQL command
     //
-    SchemaDescription::Ptr schemaDesc(SchemaDescription::Create());
-    schemaDesc->DescribeSchema(mConn, NULL);
+    // eric barby - faster with mConn->DescribeSchema() , uses cache version 
+    SchemaDescription*  schemaDesc = mConn->DescribeSchema();
+    if (!schemaDesc || !schemaDesc->IsDescribed()) 
+    {
+        throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find schema definition");
+    }
+    //SchemaDescription::Ptr schemaDesc(SchemaDescription::Create());
+    //schemaDesc->DescribeSchema(mConn, NULL);
 
+    //ticket #236 - does not support non spatial classes - eric barby
     FdoPtr<FdoIdentifier> classIdentifier(GetFeatureClassName());
     FdoPtr<FdoClassDefinition> classDef(schemaDesc->FindClassDefinition(mClassIdentifier));    
-    if (!classDef) 
+    ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier));
+    if (!classDef || !phClass) 
     {
         throw FdoCommandException::Create(L"[PostGIS] UpdateCommand can not find class definition");
     }
 
-    ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier));
     FdoStringP tablePath(phClass->GetTablePath());
 
     //
@@ -84,19 +91,55 @@
     std::string sqlValues;
 
     ExpressionProcessor::Ptr expProc(new ExpressionProcessor());
+    FdoPtr<FdoPropertyDefinitionCollection>     propsDefinition(classDef->GetProperties());
+    FdoPtr<FdoDataPropertyDefinitionCollection> propsIdentity(classDef->GetIdentityProperties());
+    FdoInt32 currentSrid = GetSRID(propsDefinition);
 
     FdoInt32 const propsSize = mPropertyValues->GetCount();
     for (FdoInt32 i = 0; i < propsSize; i++)
     {
-        FdoPtr<FdoPropertyValue> propValue(mPropertyValues->GetItem(i));
-        FdoPtr<FdoIdentifier> propId(propValue->GetName());
+        FdoPtr<FdoPropertyValue> propVal(mPropertyValues->GetItem(i));
+        FdoStringP   pName(propVal->GetName()->GetName());
+        FdoPtr<FdoPropertyDefinition> propDef(GetPropDefinition(propsDefinition, pName));
+        if (propDef) {
+          pName = propDef->GetName();
+        } else {
+          FDOLOG_WRITE(L"can not find porpertyDefinition '%s'", static_cast<FdoString*>(propVal->GetName()->GetName()));
+          //throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find porpertyDefinition!");
+        }
+        // eric barby - this propId is not needed!
+        // FdoPtr<FdoIdentifier> propId(propVal->GetName());
 
-        FdoPtr<FdoValueExpression> expr(propValue->GetValue());
+        FdoPtr<FdoValueExpression> expr(propVal->GetValue());
         expr->Process(expProc);
+        std::string value = expProc->ReleaseBuffer();
+        if (propDef) {
+          if (FdoPropertyType_DataProperty == propDef->GetPropertyType())
+          {
+            FdoDataPropertyDefinition* dataDef = static_cast<FdoDataPropertyDefinition*>(propDef.p);
+            //ticket #313 - can't filter,insert or update date/datetime - eric barby
+            //eric barby - date conversion needed
+            if (FdoDataType_DateTime == dataDef->GetDataType()) {
+              FdoDateTimeValue *dateValuePtr=dynamic_cast<FdoDateTimeValue*>(propVal->GetValue());
+              if (!dateValuePtr->IsNull()) {
+                FDOLOG_WRITE(L"convert Date:", dateValuePtr->ToString());
+                value = static_cast<char const*>(FdoStringP(dateValuePtr->ToString()));
+              }
+            }
+          } 
+          //bruno scott - this geom is not needed,maybe we should delete these lines 
+          else 
+          if (FdoPropertyType_GeometricProperty == propDef->GetPropertyType())
+          {
+              // TODO: eric barby - It won't work with multiple-geometric properties
+              FdoGeometricPropertyDefinition* geom = NULL;
+              geom = static_cast<FdoGeometricPropertyDefinition*>(propDef.p);
+          }
+        }
 
-        sqlValues += sep + static_cast<char const*>(FdoStringP(propId->GetName()));
+        sqlValues += sep + static_cast<char const*>(pName); // FdoStringP(propId->GetName())
         sqlValues += " = ";
-        sqlValues += expProc->ReleaseBuffer();
+        sqlValues += value;
 
         sep = ",";
     }
@@ -104,7 +147,8 @@
     //
     // Build WHERE clause
     //
-    FilterProcessor::Ptr filterProc(new FilterProcessor());
+    //eric barby - srid for spatial filter
+    FilterProcessor::Ptr filterProc(new FilterProcessor(currentSrid));
     std::string sqlWhere;
 
     if (NULL != mFilter)

