// // 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 "InsertCommand.h" #include "Connection.h" #include "ExpressionProcessor.h" #include "PgUtility.h" // std #include #include namespace fdo { namespace postgis { InsertCommand::InsertCommand(Connection* conn) : Base(conn), mClassIdentifier(NULL), mProperties(NULL), mBatchParameters(NULL) { // idle } InsertCommand::~InsertCommand() { // idle } /////////////////////////////////////////////////////////////////////////////// // FdoIInsert interface /////////////////////////////////////////////////////////////////////////////// FdoIdentifier* InsertCommand::GetFeatureClassName() { FDO_SAFE_ADDREF(mClassIdentifier.p); return mClassIdentifier.p; } void InsertCommand::SetFeatureClassName(FdoIdentifier* classIdentifier) { // TODO: Currently, when we use common schema for all feature classes - FdoPostGIS // it's safe to make FdoPostGIS lower-case because the PostGIS provider // does not use it in comparison, searching for classes, etc. operations. FdoPtr newIdentifier; if (NULL != classIdentifier) { FdoStringP schema(classIdentifier->GetSchemaName()); FdoStringP name(classIdentifier->GetName()); FdoStringP tmp(schema); tmp += L":"; tmp += name.Lower(); newIdentifier = FdoIdentifier::Create(tmp); } mClassIdentifier = newIdentifier; FDO_SAFE_ADDREF(mClassIdentifier.p); } void InsertCommand::SetFeatureClassName(FdoString* className) { FdoPtr cid; if (NULL != className) cid = FdoIdentifier::Create(className); else cid = NULL; SetFeatureClassName(cid); } FdoPropertyValueCollection* InsertCommand::GetPropertyValues() { if (NULL == mProperties) { mProperties = FdoPropertyValueCollection::Create(); assert(NULL != mProperties); } FDO_SAFE_ADDREF(mProperties.p); return mProperties.p; } FdoBatchParameterValueCollection* InsertCommand::GetBatchParameterValues() { return GetCollection(mBatchParameters); } FdoIFeatureReader* InsertCommand::Execute() { SchemaDescription::Ptr schemaDesc(SchemaDescription::Create()); schemaDesc->DescribeSchema(mConn, NULL); FdoPtr classDef(schemaDesc->FindClassDefinition(mClassIdentifier)); if (!classDef) { throw FdoCommandException::Create(L"[PostGIS] InsertCommand can not find class definition"); } ov::ClassDefinition::Ptr phClass(schemaDesc->FindClassMapping(mClassIdentifier)); if (NULL != mProperties) { std::string sep; std::string columns; std::string values; std::string sequence; ExpressionProcessor::Ptr expProc(new ExpressionProcessor()); // // Check auto-generated PRIMARY KEY and configure sequence // FdoStringP pkColumn; FdoPtr propsIdentity(classDef->GetIdentityProperties()); if (1 == propsIdentity->GetCount()) { FdoPtr prop(propsIdentity->GetItem(0)); if (prop->GetIsAutoGenerated() && (FdoDataType_Int16 == prop->GetDataType() || FdoDataType_Int32 == prop->GetDataType() || FdoDataType_Int64 == prop->GetDataType())) { pkColumn = prop->GetName(); std::string table(static_cast(phClass->GetTableName())); std::string column(static_cast(pkColumn)); sequence = details::MakeSequenceName(table, column); } } // // Collect columns and values for INSERT INTO statement // FdoInt32 const propsSize = mProperties->GetCount(); for (FdoInt32 i = 0; i < propsSize; i++) { FdoPtr propVal(mProperties->GetItem(i)); FdoPtr propId(propVal->GetName()); columns += sep + static_cast(FdoStringP(propId->GetName())); if (0 == pkColumn.ICompare(propId->GetName())) { values += sep + "nextval(\'" + sequence + "\')"; } else { FdoPtr expr(propVal->GetValue()); expr->Process(expProc); values += sep + expProc->ReleaseBuffer(); } sep = ","; } std::string tablePath(static_cast(phClass->GetTablePath())); std::string pkValue("nextval(\'" + sequence + "\'"); std::string sql("INSERT INTO " + tablePath + " (" + columns + ") VALUES (" + values + ")"); FdoSize affected = 0; mConn->PgExecuteCommand(sql.c_str(), affected); } return 0; } }} // namespace fdo::postgis