[prev in list] [next in list] [prev in thread] [next in thread]
List: fdo-commits
Subject: [fdo-commits] r5815 - trunk/Providers/SQLite/Src/Provider
From: svn_fdo () osgeo ! org
Date: 2010-11-18 18:31:30
Message-ID: 20101118183130.74D81390613 () trac ! osgeo ! org
[Download RAW message or body]
Author: romicadascalescu
Date: 2010-11-18 10:31:30 -0800 (Thu, 18 Nov 2010)
New Revision: 5815
Modified:
trunk/Providers/SQLite/Src/Provider/SltCommands.h
trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp
trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h
trunk/Providers/SQLite/Src/Provider/SltProvider.cpp
trunk/Providers/SQLite/Src/Provider/SltProvider.h
Log:
#504 SQLite provider. Improvements:
- Improve performance checking on insert if values changed & avoid releasing the \
schema when temp table are created
Modified: trunk/Providers/SQLite/Src/Provider/SltCommands.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltCommands.h 2010-11-18 14:56:20 UTC (rev \
5814)
+++ trunk/Providers/SQLite/Src/Provider/SltCommands.h 2010-11-18 18:31:30 UTC (rev \
5815) @@ -448,7 +448,70 @@
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
+// Class used only to detect if the property values collection has changed between
+// two or more consecutive inserts. No other special handling is done here
+class SltPropertyValueCollection : public FdoPropertyValueCollection
+{
+private:
+ bool m_collChanged;
+protected:
+ SltPropertyValueCollection()
+ {
+ m_collChanged = false;
+ }
+ virtual ~SltPropertyValueCollection()
+ {
+ }
+ virtual void Dispose()
+ {
+ delete this;
+ }
+public:
+ static SltPropertyValueCollection* Create()
+ {
+ return new SltPropertyValueCollection();
+ }
+ virtual void SetItem(FdoInt32 index, FdoPropertyValue* value)
+ {
+ m_collChanged = true;
+ FdoCollection<FdoPropertyValue, FdoCommandException>::SetItem(index, value);
+ }
+ virtual FdoInt32 Add(FdoPropertyValue* value)
+ {
+ m_collChanged = true;
+ return FdoCollection<FdoPropertyValue, FdoCommandException>::Add(value);
+ }
+ virtual void Insert(FdoInt32 index, FdoPropertyValue* value)
+ {
+ m_collChanged = true;
+ FdoCollection<FdoPropertyValue, FdoCommandException>::Insert(index, value);
+ }
+ virtual void Clear()
+ {
+ m_collChanged = true;
+ FdoCollection<FdoPropertyValue, FdoCommandException>::Clear();
+ }
+ virtual void Remove(const FdoPropertyValue* value)
+ {
+ m_collChanged = true;
+ FdoCollection<FdoPropertyValue, FdoCommandException>::Remove(value);
+ }
+ virtual void RemoveAt(FdoInt32 index)
+ {
+ m_collChanged = true;
+ FdoCollection<FdoPropertyValue, FdoCommandException>::RemoveAt(index);
+ }
+ bool GetCollectionChanged()
+ {
+ return m_collChanged;
+ }
+ void SetCollectionChanged(bool value)
+ {
+ m_collChanged = value;
+ }
+};
+
//Insert is special. We attempt to speed up inserts if the caller is cooperating.
//The contract is as follows -- as long as the caller reuses the SltInsert object,
//he is working with a compiled query and within a single transaction. Whenever
@@ -459,7 +522,7 @@
SltInsert(SltConnection* connection)
: SltCommand<FdoIInsert>(connection)
{
- m_properties = FdoPropertyValueCollection::Create();
+ m_properties = SltPropertyValueCollection::Create();
m_pCompiledSQL = NULL;
m_idProp = NULL;
m_db = m_connection->GetDbConnection();
@@ -544,16 +607,21 @@
}
else
{
- size_t count = (size_t)m_properties->GetCount();
-
- //detect changes to the property value collection that may have been
- //done between calls to Execute(). Not recommended to do that, but \
it happens...
- if (count != m_propNames.size())
+ // Provider will detect any add/move/insert/delete of properties \
only + // It's not detecting if a property value changed the name \
while in collection + // see below the comments.
+ if (m_properties->GetCollectionChanged())
{
FlushSQL();
return Execute();
}
-
+ // Do we really need this check? e.g. 50 properties for each insert \
we do 50 string compare + // I would say no because usually you \
add/move/delete property values + // and not take a property value and \
set the name after is already in the collection + // Sure someone can \
do that but it will be a rare case, and to cover rare cases + // and \
pay for all other cases... in the end is a API style usage :) +#ifdef \
EXTRA_CHECK_PROPVALUENAME_CHG + size_t count = \
(size_t)m_properties->GetCount(); for (size_t i=0; i<count; i++)
{
FdoPtr<FdoPropertyValue> pv = m_properties->GetItem(i);
@@ -564,6 +632,7 @@
return Execute();
}
}
+#endif
}
// in case active transaction was closed by the user reopen it
@@ -649,6 +718,7 @@
m_pCompiledSQL = NULL;
m_propNames.clear();
+ m_properties->SetCollectionChanged(false);
}
@@ -662,6 +732,7 @@
sbval.Append(") VALUES(");
+ m_properties->SetCollectionChanged(false);
for (int i=0; i<m_properties->GetCount(); i++)
{
FdoPtr<FdoPropertyValue> pv = m_properties->GetItem(i);
@@ -707,7 +778,7 @@
// used only to get the inserted ID if needed
FdoDataPropertyDefinition* m_idProp;
- FdoPropertyValueCollection* m_properties;
+ SltPropertyValueCollection* m_properties;
std::string m_fcname;
std::string m_fcmainname;
@@ -827,10 +898,36 @@
if (rc == SQLITE_DONE)
{
const char* sql = m_sb.Data();
- if (StringStartsWith(sql, "create"))
- m_connection->FreeCachedSchema(true);
- else if (StringStartsWith(sql, "drop") || StringStartsWith(sql, \
"alter"))
- m_connection->FreeCachedSchema(false);
+ const char* lastPos = NULL;
+ if (StringStartsWith(sql, "create", &lastPos)) // handle CREATE \
[TEMP]/[TEMPORARY] TABLE + {
+ // if we clear the schema and the table is not in the schema we \
do it for nothing + // in case we create a non temp table free the \
cached schema + if (!StringStartsWith(lastPos, "TEMP"))
+ m_connection->FreeCachedSchema();
+ }
+ else if (StringStartsWith(sql, "drop", &lastPos)) // DROP VIEW/TABLE \
[IF EXIST] database.tablename + {
+ std::string name;
+ if (StringStartsWith(lastPos, "table", &lastPos) || \
StringStartsWith(lastPos, "view", &lastPos)) + {
+ if (StringStartsWith(lastPos, "if ", &lastPos)) // skip IF
+ lastPos = SkipTokenString(lastPos); // skip EXISTS
+ name = GetTableNameToken(lastPos);
+ }
+ // if we clear the schema and the table is not in the schema we \
do it for nothing + if (name.size())
+ m_connection->ClearClassFromCachedSchema(name.c_str(), \
true); + }
+ else if (StringStartsWith(sql, "alter", &lastPos))
+ {
+ std::string name;
+ lastPos = SkipTokenString(lastPos); // skip TABLE
+ name = GetTableNameToken(lastPos);
+ // if we clear the schema and the table is not in the schema we \
do it for nothing + if (name.size())
+ m_connection->ClearClassFromCachedSchema(name.c_str(), \
false); + }
// "CREATE/ALTER/DROP* will set sqlite3_changes = 0 so result will \
be 0 // INSERT/UPDATE/DELETE* will return affected rows
// in case of error an exception will be thrown
Modified: trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp 2010-11-18 14:56:20 \
UTC (rev 5814)
+++ trunk/Providers/SQLite/Src/Provider/SltConversionUtils.cpp 2010-11-18 18:31:30 \
UTC (rev 5815) @@ -77,8 +77,45 @@
return -1;
}
-bool StringStartsWith(const char* str, const char* val)
+// returns a table name been able to process formats like:
+// name, "name", main."name", main.name, "main"."name"
+std::string GetTableNameToken(const char* str)
{
+ const char* strTmp = str;
+ while (*strTmp == ' ' && *strTmp != '\0') strTmp++;
+ str = strTmp;
+ bool startDq = false;
+ while(*strTmp != '\0')
+ {
+ if (*strTmp == '\"')
+ startDq = !startDq;
+ if (*strTmp == ' ' && !startDq)
+ break;
+ strTmp++;
+ }
+ if (str == strTmp)
+ return std::string("");
+ if (StringStartsWith(str, "main."))
+ str = str + 5;
+ else if (StringStartsWith(str, "\"main\"."))
+ str = str + 7;
+ if (*str == '\"')
+ return std::string(str+1, (int)(strTmp-str-2));
+ else
+ return std::string(str, (int)(strTmp-str));
+}
+
+// skips a predefined token whihc cannot contain space character
+const char* SkipTokenString(const char* str)
+{
+ const char* strTmp = str;
+ while (*strTmp == ' ' && *strTmp != '\0') strTmp++;
+ while(*strTmp != '\0' && *strTmp != ' ') strTmp++;
+ return strTmp;
+}
+
+bool StringStartsWith(const char* str, const char* val, const char** lastPos)
+{
assert( str!=NULL );
const char* strTmp = str;
while (*strTmp == ' ' && *strTmp != '\0') strTmp++;
@@ -86,7 +123,11 @@
while(sqlite3UpperToLower[*strTmp++] == sqlite3UpperToLower[*valTmp++])
{
if (*valTmp == '\0')
+ {
+ if (lastPos != NULL)
+ *lastPos = strTmp;
return true;
+ }
}
return false;
}
Modified: trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h 2010-11-18 14:56:20 UTC \
(rev 5814)
+++ trunk/Providers/SQLite/Src/Provider/SltConversionUtils.h 2010-11-18 18:31:30 UTC \
(rev 5815) @@ -67,7 +67,9 @@
SLT_API void BindPropVals(FdoParameterValueCollection* props, sqlite3_stmt* stmt, \
bool useParmName, int geomFormat); SLT_API void BindPropValue(sqlite3_stmt* stmt, \
int i, FdoLiteralValue* lv, int geomFormat); SLT_API int StringContains(const char* \
str, const char* val);
-SLT_API bool StringStartsWith(const char* str, const char* val);
+SLT_API bool StringStartsWith(const char* str, const char* val, const char** lastPos \
= NULL); +SLT_API const char* SkipTokenString(const char* str);
+SLT_API std::string GetTableNameToken(const char* str);
SLT_API TokenDateFormatType StringToDateFormat(const char* specifier);
Modified: trunk/Providers/SQLite/Src/Provider/SltProvider.cpp
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltProvider.cpp 2010-11-18 14:56:20 UTC (rev \
5814)
+++ trunk/Providers/SQLite/Src/Provider/SltProvider.cpp 2010-11-18 18:31:30 UTC (rev \
5815) @@ -4103,36 +4103,54 @@
return (xyTolerance > 0.0);
}
-void SltConnection::FreeCachedSchema (bool isAddition)
+void SltConnection::ClearClassFromCachedSchema(const char* table, bool fullDrop)
{
- if (isAddition)
+ // do we have this class in the current schema?
+ if (!fullDrop)
{
- // The cached FDO schema will need to be refreshed
- FDO_SAFE_RELEASE(m_pSchema);
- m_pSchema = NULL;
+ MetadataCache::iterator iter = m_mNameToMetadata.find((char*)table);
+ if (iter != m_mNameToMetadata.end())
+ {
+ // in case we do just clean it up.
+ FDO_SAFE_RELEASE(m_pSchema);
+ m_pSchema = NULL;
+
+ delete iter->second;
+ free(iter->first); //it was created via strdup, must use free()
+ m_mNameToMetadata.erase(iter);
+ }
}
- else // should we improve this? for now let's not do it.
+ else
{
- FDO_SAFE_RELEASE(m_pSchema);
- m_pSchema = NULL;
- //free the spatial indexes
- for (SpatialIndexCache::iterator iter = m_mNameToSpatialIndex.begin();
- iter != m_mNameToSpatialIndex.end(); iter++)
- {
- iter->second->Release();
- free((char*)iter->first); //it was created via strdup, must use free()
- }
-
- m_mNameToSpatialIndex.clear();
-
//clear the cached schema metadata
- for (MetadataCache::iterator iter = m_mNameToMetadata.begin();
- iter != m_mNameToMetadata.end(); iter++)
+ for (MetadataCache::iterator iter = iter = m_mNameToMetadata.begin();
+ iter != m_mNameToMetadata.end(); iter++)
{
delete iter->second;
free(iter->first); //it was created via strdup, must use free()
}
-
m_mNameToMetadata.clear();
+ // in case we do just clean it up.
+ FDO_SAFE_RELEASE(m_pSchema);
+ m_pSchema = NULL;
}
+ SpatialIndexCache::iterator iterSp = m_mNameToSpatialIndex.find((char*)table);
+ if (iterSp != m_mNameToSpatialIndex.end())
+ {
+ SpatialIndex* si = iterSp->second->GetSpatialIndex();
+ if (si)
+ {
+ // we cannot release it since there might be cached statements keeping \
the SI locked + si->ResetToEmpty();
+ if (!fullDrop) // we had alter
+ RebuildSpatialOperator(iterSp->second);
+ }
+ }
}
+
+void SltConnection::FreeCachedSchema ()
+{
+ // The cached FDO schema will need to be refreshed
+ FDO_SAFE_RELEASE(m_pSchema);
+ m_pSchema = NULL;
+}
Modified: trunk/Providers/SQLite/Src/Provider/SltProvider.h
===================================================================
--- trunk/Providers/SQLite/Src/Provider/SltProvider.h 2010-11-18 14:56:20 UTC (rev \
5814)
+++ trunk/Providers/SQLite/Src/Provider/SltProvider.h 2010-11-18 18:31:30 UTC (rev \
5815) @@ -262,7 +262,8 @@
int GetDefaultSpatialContext();
bool SupportsTolerance();
bool AddSupportForTolerance();
- void FreeCachedSchema (bool isAddition);
+ void FreeCachedSchema ();
+ void ClearClassFromCachedSchema(const char* table, bool fullDrop);
private :
_______________________________________________
fdo-commits mailing list
fdo-commits@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/fdo-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic