[Liblas-commits] libpc: a big wad of Oracle writer
liblas-commits at liblas.org
liblas-commits at liblas.org
Wed Mar 9 09:21:38 EST 2011
details: http://hg.liblas.orglibpc/rev/1b0b916218c7
changeset: 189:1b0b916218c7
user: Howard Butler <hobu.inc at gmail.com>
date: Wed Mar 09 08:21:32 2011 -0600
description:
a big wad of Oracle writer
diffstat:
src/drivers/oci/block.hpp | 6 +-
src/drivers/oci/writer.cpp | 421 ++++++++++++++++++++++++++++++++++++++++++--
src/drivers/oci/writer.hpp | 80 +++++++-
3 files changed, 475 insertions(+), 32 deletions(-)
diffs (truncated from 593 to 300 lines):
diff -r 9bf3a3b2a277 -r 1b0b916218c7 src/drivers/oci/block.hpp
--- a/src/drivers/oci/block.hpp Tue Mar 08 16:05:29 2011 -0800
+++ b/src/drivers/oci/block.hpp Wed Mar 09 08:21:32 2011 -0600
@@ -46,10 +46,12 @@
{
public:
Block( chipper::Block const& block);
-
+
+ Block(Block const& other) : m_block(other.m_block) {};
+
private:
Block& operator=(const Block&); // nope
- Block(const Block&); // nope
+
chipper::Block const& m_block;
diff -r 9bf3a3b2a277 -r 1b0b916218c7 src/drivers/oci/writer.cpp
--- a/src/drivers/oci/writer.cpp Tue Mar 08 16:05:29 2011 -0800
+++ b/src/drivers/oci/writer.cpp Wed Mar 09 08:21:32 2011 -0600
@@ -34,6 +34,8 @@
#include <cassert>
+#include <sstream>
+#include <cctype> // toupper
#include "writer.hpp"
#include "header.hpp"
@@ -42,29 +44,98 @@
#include <libpc/exceptions.hpp>
#include <libpc/libpc_config.hpp>
+#include <cstdlib>
+#include <iostream>
-namespace libpc
+#include <boost/make_shared.hpp>
+
+namespace libpc { namespace driver { namespace oci {
+
+Options::Options()
+{
+ m_tree.put("3d", false);
+ m_tree.put("solid", false);
+ m_tree.put("overwrite", false);
+ m_tree.put("debug", false);
+ m_tree.put("verbose", false);
+ m_tree.put("srid", 4269);
+ m_tree.put("capacity", 8000);
+ m_tree.put("precision", 8);
+ m_tree.put("pcid", -1);
+ m_tree.put("connection", std::string(""));
+ m_tree.put("block_table_name", std::string("output"));
+ m_tree.put("block_table_partition_column", std::string(""));
+ m_tree.put("block_table_partition_value", std::string(""));
+ m_tree.put("base_table_name", std::string("hobu"));
+ m_tree.put("cloud_column_name", std::string("cloud"));
+ m_tree.put("header_blob_column_name", std::string("header"));
+ m_tree.put("header_blob_column_name", std::string("header"));
+ m_tree.put("base_table_aux_columns", std::string(""));
+ m_tree.put("base_table_aux_values", std::string(""));
+ m_tree.put("pre_block_sql", std::string(""));
+ m_tree.put("pre_sql", std::string(""));
+ m_tree.put("post_block_sql", libpc::Bounds<double>());
+}
+
+bool Options::IsDebug() const
+{
+ bool debug = false;
+ try
+ {
+ debug = m_tree.get<bool>("debug");
+ }
+ catch (liblas::property_tree::ptree_bad_path const& e) {
+ ::boost::ignore_unused_variable_warning(e);
+
+ }
+ return debug;
+}
+
+Writer::Writer(Stage& prevStage, Options& options)
+ : Consumer(prevStage)
+ , m_stage(prevStage)
+ , m_chipper(m_stage, options.GetPTree().get<boost::uint32_t>("capacity") )
+ , m_options(options)
+ , m_verbose(false)
{
-
-OCIWriter::OCIWriter(Stage& prevStage, boost::uint32_t block_size)
- : Consumer(prevStage), m_stage(prevStage), m_block_size(block_size)
-{
-
- chipper::Chipper c(m_stage, m_block_size );
- c.Chip();
return;
}
+Connection Writer::Connect()
+{
+ std::string connection = m_options.GetPTree().get<std::string>("connection");
+ if (connection.empty())
+ throw libpc_error("Oracle connection string empty! Unable to connect");
-OCIWriter::~OCIWriter()
+
+ std::string::size_type slash_pos = connection.find("/",0);
+ std::string username = connection.substr(0,slash_pos);
+ std::string::size_type at_pos = connection.find("@",slash_pos);
+
+ std::string password = connection.substr(slash_pos+1, at_pos-slash_pos-1);
+ std::string instance = connection.substr(at_pos+1);
+
+ Connection con = boost::make_shared<OWConnection>(username.c_str(),password.c_str(),instance.c_str());
+
+ if (con->Succeeded())
+ if (m_verbose)
+ std::cout << "Oracle connection succeeded" << std::endl;
+ else
+ throw libpc_error("Oracle connection failed");
+
+ return con;
+
+}
+
+Writer::~Writer()
{
return;
}
-const std::string& OCIWriter::getName() const
+const std::string& Writer::getName() const
{
static std::string name("OCI Writer");
return name;
@@ -75,21 +146,270 @@
-void OCIWriter::writeBegin()
+void Writer::run(std::ostringstream const& command)
+{
+ Statement statement = Statement(m_connection->CreateStatement(command.str().c_str()));
+
+ // Because of OCIGDALErrorHandler, this is going to throw if there is a
+ // problem. When it does, the statement should go out of scope and
+ // be destroyed without leaking.
+ statement->Execute();
+}
+
+void Writer::WipeBlockTable()
+{
+ std::ostringstream oss;
+
+ std::string block_table_name = m_options.GetPTree().get<std::string>("block_table_name");
+ std::string base_table_name = m_options.GetPTree().get<std::string>("base_table_name");
+ std::string cloud_column_name = m_options.GetPTree().get<std::string>("cloud_column_name");
+
+ oss << "DELETE FROM " << block_table_name;
+ try {
+ run(oss);
+ } catch (libpc_error const&)
+ {
+ // if we failed, let's try dropping the spatial index for the block_table_name
+ oss.str("");
+ if (m_options.IsDebug())
+ std::cout << "Dropping index " << block_table_name
+ << "_cloud_idx for block_table_name"
+ << std::endl;
+ oss << "DROP INDEX " << block_table_name << "_cloud_idx" ;
+ run(oss);
+ oss.str("");
+
+ oss << "DELETE FROM " << block_table_name;
+ run(oss);
+ oss.str("");
+ }
+
+ oss.str("");
+
+ // These need to be uppercase to satisfy the PLSQL function
+ cloud_column_name = to_upper(cloud_column_name);
+ base_table_name = to_upper(base_table_name);
+
+ oss << "declare\n"
+ "begin \n"
+ " mdsys.sdo_pc_pkg.drop_dependencies('"
+ << base_table_name <<
+ "', '"
+ << cloud_column_name <<
+ "'); end;";
+ run(oss);
+ oss.str("");
+
+ oss << "DROP TABLE" << block_table_name;
+ run(oss);
+ oss.str("");
+
+ // Oracle upper cases the table name when inserting it in the
+ // USER_SDO_GEOM_METADATA. We'll use std::transform to do it.
+ // See http://forums.devx.com/showthread.php?t=83058 for the
+ // technique
+
+ block_table_name = to_upper(block_table_name);
+ oss << "DELETE FROM USER_SDO_GEOM_METADATA WHERE TABLE_NAME='" << block_table_name << "'" ;
+ run(oss);
+}
+
+void Writer::CreateBlockIndex()
+{
+ std::ostringstream oss;
+ std::string block_table_name = m_options.GetPTree().get<std::string>("block_table_name");
+
+ bool is3d = m_options.GetPTree().get<bool>("3d");
+ oss << "CREATE INDEX "<< block_table_name << "_cloud_idx on "
+ << block_table_name << "(blk_extent) INDEXTYPE IS MDSYS.SPATIAL_INDEX";
+
+ if (is3d)
+ {
+ oss <<" PARAMETERS('sdo_indx_dims=3')";
+ }
+
+ run(oss);
+ oss.str("");
+
+ oss << "CREATE INDEX " << block_table_name <<"_objectid_idx on "
+ << block_table_name << "(OBJ_ID,BLK_ID) COMPRESS 2" ;
+ run(oss);
+ oss.str("");
+
+
+}
+
+bool Writer::BlockTableExists()
+{
+
+ std::ostringstream oss;
+ std::string block_table_name = m_options.GetPTree().get<std::string>("block_table_name");
+
+ char szTable[OWNAME]= "";
+ oss << "select table_name from user_tables where table_name like upper('%%"<< block_table_name <<"%%') ";
+
+
+ Statement statement = Statement(m_connection->CreateStatement(oss.str().c_str()));
+
+ // Because of OCIGDALErrorHandler, this is going to throw if there is a
+ // problem. When it does, the statement should go out of scope and
+ // be destroyed without leaking.
+ statement->Execute();
+
+ statement->Define(szTable);
+
+ try {
+ statement->Execute();
+ } catch (libpc_error const& ) {
+ // Assume for now that an error returned here is OCI_NODATA, which means
+ // the table doesn't exist. If this really isn't the case, we're going
+ // to get more legit message further down the line.
+ return false;
+ }
+
+ return true;
+
+}
+
+void Writer::CreateBlockTable()
+{
+ std::ostringstream oss;
+ std::string block_table_name = m_options.GetPTree().get<std::string>("block_table_name");
+
+ oss << "CREATE TABLE " << block_table_name << " AS SELECT * FROM MDSYS.SDO_PC_BLK_TABLE";
+
+ run(oss);
+ m_connection->Commit();
+
+}
+
+bool Writer::IsGeographic(boost::int32_t srid)
+
+{
+ typedef boost::shared_ptr<long> shared_long;
+ typedef boost::shared_ptr<char> shared_char;
+ std::ostringstream oss;
+ // char* kind = (char* ) malloc (OWNAME * sizeof(char));
+ shared_char kind = boost::shared_ptr<char>(new char[OWNAME]);
+ oss << "SELECT COORD_REF_SYS_KIND from MDSYS.SDO_COORD_REF_SYSTEM WHERE SRID = :1";
+
+ Statement statement = Statement(m_connection->CreateStatement(oss.str().c_str()));
+
+ shared_long p_srid = boost::shared_ptr<long>(new long);
+ *p_srid = srid;
+ // p_srid[0] = srid;
+
+ statement->Bind(p_srid.get());
+ statement->Define(kind.get());
+
More information about the Liblas-commits
mailing list