From 650986b279bcb028942997103de81f362a3a0dbd Mon Sep 17 00:00:00 2001 From: Lucio Asnaghi Date: Tue, 16 Nov 2010 17:31:13 +0000 Subject: [PATCH] + improved occi plugin + ability to import collections and multi-geometries correctly + added a parameter to control the usage of the connection pool + added more verbosity in debug mode, to report wrong enums --- plugins/input/occi/README | 6 +- plugins/input/occi/occi_datasource.cpp | 692 ++++++++++++++----------- plugins/input/occi/occi_datasource.hpp | 2 + plugins/input/occi/occi_featureset.cpp | 420 ++++++++------- plugins/input/occi/occi_featureset.hpp | 41 +- plugins/input/occi/occi_types.cpp | 68 +++ plugins/input/occi/occi_types.hpp | 56 +- 7 files changed, 783 insertions(+), 502 deletions(-) diff --git a/plugins/input/occi/README b/plugins/input/occi/README index 726ef279a..a36411c88 100644 --- a/plugins/input/occi/README +++ b/plugins/input/occi/README @@ -1,7 +1,11 @@ # # To regenerate C++ class declarations & implementations for the Spatial -# object types of your database you should execute OTT +# object types of your database you should execute OTT in your server ! # + +echo "TYPE MDSYS.SDO_POINT_TYPE AS SDOPointType" > spatial_types.typ +echo "TYPE MDSYS.SDO_GEOMETRY AS SDOGeometry" >> spatial_types.typ + ott userid=scott/tiger attraccess=private intype=spatial_types.typ code=cpp \ cppfile=spatial_classeso.cpp hfile=spatial_classesh.h mapfile=spatial_classesm.cpp \ mapfunc=RegisterClasses diff --git a/plugins/input/occi/occi_datasource.cpp b/plugins/input/occi/occi_datasource.cpp index 03d2641df..58b64cd8a 100644 --- a/plugins/input/occi/occi_datasource.cpp +++ b/plugins/input/occi/occi_datasource.cpp @@ -70,164 +70,32 @@ DATASOURCE_PLUGIN(occi_datasource) occi_datasource::occi_datasource(parameters const& params, bool bind) - : datasource (params), - table_(*params_.get("table","")), - geometry_field_(*params_.get("geometry_field","GEOLOC")), - type_(datasource::Vector), - extent_initialized_(false), - row_limit_(*params_.get("row_limit",0)), - row_prefetch_(*params_.get("row_prefetch",100)), - desc_(*params_.get("type"), *params_.get("encoding","utf-8")), - pool_(0) + : datasource (params), + table_(*params_.get("table","")), + geometry_field_(*params_.get("geometry_field","GEOLOC")), + type_(datasource::Vector), + extent_initialized_(false), + row_limit_(*params_.get("row_limit",0)), + row_prefetch_(*params_.get("row_prefetch",100)), + desc_(*params_.get("type"), *params_.get("encoding","utf-8")), + pool_(NULL), + conn_(NULL) { - multiple_geometries_ = *params_.get("multiple_geometries",false); - use_spatial_index_ = *params_.get("use_spatial_index",true); + if (! params_.get("user")) throw datasource_exception("No specified"); + if (! params_.get("password")) throw datasource_exception("No specified"); + if (! params_.get("host")) throw datasource_exception("No string specified"); - boost::optional ext = params_.get("extent"); - if (ext) extent_initialized_ = extent_.from_string(*ext); + multiple_geometries_ = *params_.get("multiple_geometries",false); + use_spatial_index_ = *params_.get("use_spatial_index",true); + use_connection_pool_ = *params_.get("use_connection_pool",true); - if (bind) - { - this->bind(); - } -} + boost::optional ext = params_.get("extent"); + if (ext) extent_initialized_ = extent_.from_string(*ext); -void occi_datasource::bind() const -{ - if (is_bound_) return; - - boost::optional initial_size = params_.get("initial_size",1); - boost::optional max_size = params_.get("max_size",10); - - // connect to environment - try - { - Environment* env = occi_environment::get_environment(); - - pool_ = env->createStatelessConnectionPool( - *params_.get("user"), - *params_.get("password"), - *params_.get("host"), - *max_size, - *initial_size, - 1, - StatelessConnectionPool::HOMOGENEOUS); - } - catch (SQLException &ex) - { - throw datasource_exception(ex.getMessage()); - } - - std::string table_name = mapnik::table_from_sql(table_); - - // get SRID from geometry metadata - { - occi_connection_ptr conn (pool_); - - std::ostringstream s; - s << "select srid from " << SDO_GEOMETRY_METADATA_TABLE << " where"; - s << " lower(table_name) = lower('" << table_name << "') and"; - s << " lower(column_name) = lower('" << geometry_field_ << "')"; - - try - { - ResultSet* rs = conn.execute_query (s.str()); - if (rs && rs->next ()) - { - srid_ = rs->getInt(1); - } - } - catch (SQLException &ex) - { - throw datasource_exception(ex.getMessage()); - } - } - - // get columns description - { - std::ostringstream s; - s << "select * from (" << table_name << ") where rownum < 1"; - - occi_connection_ptr conn (pool_); - - try - { - ResultSet* rs = conn.execute_query (s.str()); - if (rs) - { - std::vector listOfColumns = rs->getColumnListMetaData(); - - for (unsigned int i=0;i("password"), + *params_.get("host"), + *params_.get("max_size",10), + *params_.get("initial_size",1), + 1, + StatelessConnectionPool::HOMOGENEOUS); + } + catch (SQLException &ex) + { + throw datasource_exception(ex.getMessage()); + } + } + else + { + try + { + Environment* env = occi_environment::get_environment(); + + conn_ = env->createConnection( + *params_.get("user"), + *params_.get("password"), + *params_.get("host")); + } + catch (SQLException &ex) + { + throw datasource_exception(ex.getMessage()); + } + } + + std::string table_name = mapnik::table_from_sql(table_); + + // get SRID from geometry metadata + { + std::ostringstream s; + s << "select srid from " << SDO_GEOMETRY_METADATA_TABLE << " where"; + s << " lower(table_name) = lower('" << table_name << "') and"; + s << " lower(column_name) = lower('" << geometry_field_ << "')"; + + try + { + occi_connection_ptr conn; + if (use_connection_pool_) conn.set_pool(pool_); + else conn.set_connection(conn_, false); + + ResultSet* rs = conn.execute_query (s.str()); + if (rs && rs->next ()) + { + srid_ = rs->getInt(1); + } + } + catch (SQLException &ex) + { + throw datasource_exception(ex.getMessage()); + } + } + + // get columns description + { + std::ostringstream s; + s << "select * from (" << table_name << ") where rownum < 1"; + + try + { + occi_connection_ptr conn; + if (use_connection_pool_) conn.set_pool(pool_); + else conn.set_connection(conn_, false); + + ResultSet* rs = conn.execute_query (s.str()); + if (rs) + { + std::vector listOfColumns = rs->getColumnListMetaData(); + + for (unsigned int i = 0; i < listOfColumns.size(); ++i) + { + MetaData columnObj = listOfColumns[i]; + + std::string fld_name = columnObj.getString(MetaData::ATTR_NAME); + int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE); + +#if 0 + int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE); + if (type_code == OCCI_TYPECODE_OBJECT) + { + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object)); + continue; + } +#endif + + switch (type_oid) + { + case oracle::occi::OCCIBOOL: + case oracle::occi::OCCIINT: + case oracle::occi::OCCIUNSIGNED_INT: + case oracle::occi::OCCIROWID: + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer)); + break; + case oracle::occi::OCCIFLOAT: + case oracle::occi::OCCIBFLOAT: + case oracle::occi::OCCIDOUBLE: + case oracle::occi::OCCIBDOUBLE: + case oracle::occi::OCCINUMBER: + case oracle::occi::OCCI_SQLT_NUM: + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double)); + break; + case oracle::occi::OCCICHAR: + case oracle::occi::OCCISTRING: + case oracle::occi::OCCI_SQLT_AFC: + case oracle::occi::OCCI_SQLT_AVC: + case oracle::occi::OCCI_SQLT_CHR: + case oracle::occi::OCCI_SQLT_LVC: + case oracle::occi::OCCI_SQLT_RDD: + case oracle::occi::OCCI_SQLT_STR: + case oracle::occi::OCCI_SQLT_VCS: + case oracle::occi::OCCI_SQLT_VNU: + case oracle::occi::OCCI_SQLT_VBI: + case oracle::occi::OCCI_SQLT_VST: + desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String)); + break; + case oracle::occi::OCCIDATE: + case oracle::occi::OCCITIMESTAMP: + case oracle::occi::OCCIINTERVALDS: + case oracle::occi::OCCIINTERVALYM: + case oracle::occi::OCCI_SQLT_DAT: + case oracle::occi::OCCI_SQLT_DATE: + case oracle::occi::OCCI_SQLT_TIME: + case oracle::occi::OCCI_SQLT_TIME_TZ: + case oracle::occi::OCCI_SQLT_TIMESTAMP: + case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: + case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: + case oracle::occi::OCCI_SQLT_INTERVAL_YM: + case oracle::occi::OCCI_SQLT_INTERVAL_DS: + case oracle::occi::OCCIANYDATA: + case oracle::occi::OCCIBLOB: + case oracle::occi::OCCIBFILE: + case oracle::occi::OCCIBYTES: + case oracle::occi::OCCICLOB: + case oracle::occi::OCCIVECTOR: + case oracle::occi::OCCIMETADATA: + case oracle::occi::OCCIPOBJECT: + case oracle::occi::OCCIREF: + case oracle::occi::OCCIREFANY: + case oracle::occi::OCCISTREAM: + case oracle::occi::OCCICURSOR: + case oracle::occi::OCCI_SQLT_FILE: + case oracle::occi::OCCI_SQLT_CFILE: + case oracle::occi::OCCI_SQLT_REF: + case oracle::occi::OCCI_SQLT_CLOB: + case oracle::occi::OCCI_SQLT_BLOB: + case oracle::occi::OCCI_SQLT_RSET: +#ifdef MAPNIK_DEBUG + clog << "unsupported datatype " << occi_enums::resolve_datatype(type_oid) + << " (type_oid=" << type_oid << ")" << endl; +#endif + break; + default: +#ifdef MAPNIK_DEBUG + clog << "unknown datatype " << occi_enums::resolve_datatype(type_oid) + << " (type_oid=" << type_oid << ")" << endl; +#endif + break; + } + } + } + } + catch (SQLException &ex) + { + throw datasource_exception(ex.getMessage()); + } + } + + is_bound_ = true; +} + std::string occi_datasource::name() { return "occi"; @@ -254,8 +318,7 @@ box2d occi_datasource::envelope() const if (extent_initialized_) return extent_; if (!is_bound_) bind(); - double lox, loy, hix, hiy; - occi_connection_ptr conn (pool_); + double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0; boost::optional estimate_extent = params_.get("estimate_extent",false); @@ -266,8 +329,16 @@ box2d occi_datasource::envelope() const s << " (select sdo_aggr_mbr(" << geometry_field_ << ") shape from " << table_ << ") a, "; s << " table (sdo_util.getvertices(a.shape)) c"; +#ifdef MAPNIK_DEBUG + clog << s.str() << endl; +#endif + try { + occi_connection_ptr conn; + if (use_connection_pool_) conn.set_pool(pool_); + else conn.set_connection(conn_, false); + ResultSet* rs = conn.execute_query (s.str()); if (rs && rs->next ()) { @@ -295,16 +366,29 @@ box2d occi_datasource::envelope() const { std::string table_name = mapnik::table_from_sql(table_); - { - std::ostringstream s; - s << "select dim.sdo_lb as lx, dim.sdo_ub as ux from "; - s << SDO_GEOMETRY_METADATA_TABLE << " m, table(m.diminfo) dim "; - s << " where lower(m.table_name) = '" << table_name << "' and dim.sdo_dimname = 'X'"; + std::ostringstream s; + s << "select dim.sdo_lb, dim.sdo_ub from "; + s << SDO_GEOMETRY_METADATA_TABLE << " m, table(m.diminfo) dim "; + s << " where lower(m.table_name) = '" << table_name << "' and dim.sdo_dimname = 'X'"; + s << " UNION "; + s << "select dim.sdo_lb, dim.sdo_ub from "; + s << SDO_GEOMETRY_METADATA_TABLE << " m, table(m.diminfo) dim "; + s << " where lower(m.table_name) = '" << table_name << "' and dim.sdo_dimname = 'Y'"; - try +#ifdef MAPNIK_DEBUG + clog << s.str() << endl; +#endif + + try + { + occi_connection_ptr conn; + if (use_connection_pool_) conn.set_pool(pool_); + else conn.set_connection(conn_, false); + + ResultSet* rs = conn.execute_query (s.str()); + if (rs) { - ResultSet* rs = conn.execute_query (s.str()); - if (rs && rs->next ()) + if (rs->next ()) { try { @@ -316,23 +400,8 @@ box2d occi_datasource::envelope() const clog << ex.what() << endl; } } - } - catch (SQLException &ex) - { - throw datasource_exception(ex.getMessage()); - } - } - - { - std::ostringstream s; - s << "select dim.sdo_lb as ly, dim.sdo_ub as uy from "; - s << SDO_GEOMETRY_METADATA_TABLE << " m, table(m.diminfo) dim "; - s << " where lower(m.table_name) = '" << table_name << "' and dim.sdo_dimname = 'Y'"; - - try - { - ResultSet* rs = conn.execute_query (s.str()); - if (rs && rs->next ()) + + if (rs->next ()) { try { @@ -344,23 +413,27 @@ box2d occi_datasource::envelope() const clog << ex.what() << endl; } } - } - catch (SQLException &ex) - { - throw datasource_exception(ex.getMessage()); + + extent_.init (lox,loy,hix,hiy); + extent_initialized_ = true; } } - - extent_.init (lox,loy,hix,hiy); - extent_initialized_ = true; + catch (SQLException &ex) + { + throw datasource_exception(ex.getMessage()); + } } + if (! extent_initialized_) + throw datasource_exception("Unable to determine the extent of a table"); + return extent_; } layer_descriptor occi_datasource::get_descriptor() const { if (!is_bound_) bind(); + return desc_; } @@ -368,101 +441,110 @@ featureset_ptr occi_datasource::features(query const& q) const { if (!is_bound_) bind(); - if (pool_) + box2d const& box=q.get_bbox(); + + std::ostringstream s; + s << "select " << geometry_field_ << " as geom"; + std::set const& props = q.property_names(); + std::set::const_iterator pos = props.begin(); + std::set::const_iterator end = props.end(); + while (pos != end) { - box2d const& box=q.get_bbox(); - - std::ostringstream s; - s << "select " << geometry_field_ << " as geom"; - std::set const& props=q.property_names(); - std::set::const_iterator pos=props.begin(); - std::set::const_iterator end=props.end(); - while (pos != end) - { - s <<",\""<<*pos<<"\""; - ++pos; - } - - s << " from "; - - std::string query (table_); - std::string table_name = mapnik::table_from_sql(query); - - if (use_spatial_index_) - { - std::ostringstream spatial_sql; - spatial_sql << std::setprecision(16); - spatial_sql << " where sdo_filter(" << geometry_field_ << ","; - spatial_sql << " mdsys.sdo_geometry(" << SDO_GTYPE_2DPOLYGON << "," << srid_ << ",NULL,"; - spatial_sql << " mdsys.sdo_elem_info_array(1," << SDO_ETYPE_POLYGON << "," << SDO_INTERPRETATION_RECTANGLE << "),"; - spatial_sql << " mdsys.sdo_ordinate_array("; - spatial_sql << box.minx() << "," << box.miny() << ", "; - spatial_sql << box.maxx() << "," << box.maxy() << ")), 'querytype=WINDOW') = 'TRUE'"; - - if (boost::algorithm::ifind_first(query,"where")) - { - boost::algorithm::ireplace_first(query, "where", spatial_sql.str() + " and"); - } - else if (boost::algorithm::find_first(query,table_name)) - { - boost::algorithm::ireplace_first(query, table_name , table_name + " " + spatial_sql.str()); - } - } - - if (row_limit_ > 0) - { - std::string row_limit_string = "rownum < " + row_limit_; - - if (boost::algorithm::ifind_first(query,"where")) - { - boost::algorithm::ireplace_first(query, "where", row_limit_string + " and"); - } - else if (boost::algorithm::find_first(query,table_name)) - { - boost::algorithm::ireplace_first(query, table_name , table_name + " " + row_limit_string); - } - } - - s << query; - -#ifdef MAPNIK_DEBUG - clog << s.str() << endl; -#endif - - return featureset_ptr (new occi_featureset (pool_, - s.str(), - desc_.get_encoding(), - multiple_geometries_, - row_prefetch_, - props.size())); + s << ",\"" << *pos << "\""; + ++pos; } - return featureset_ptr(); + s << " from "; + + std::string query (table_); + std::string table_name = mapnik::table_from_sql(query); + + if (use_spatial_index_) + { + std::ostringstream spatial_sql; + spatial_sql << std::setprecision(16); + spatial_sql << " where sdo_filter(" << geometry_field_ << ","; + spatial_sql << " mdsys.sdo_geometry(" << SDO_GTYPE_2DPOLYGON << "," << srid_ << ",NULL,"; + spatial_sql << " mdsys.sdo_elem_info_array(1," << SDO_ETYPE_POLYGON << "," << SDO_INTERPRETATION_RECTANGLE << "),"; + spatial_sql << " mdsys.sdo_ordinate_array("; + spatial_sql << box.minx() << "," << box.miny() << ", "; + spatial_sql << box.maxx() << "," << box.maxy() << ")), 'querytype=WINDOW') = 'TRUE'"; + + if (boost::algorithm::ifind_first(query, "where")) + { + boost::algorithm::ireplace_first(query, "where", spatial_sql.str() + " and"); + } + else if (boost::algorithm::ifind_first(query, table_name)) + { + boost::algorithm::ireplace_first(query, table_name, table_name + " " + spatial_sql.str()); + } + else + { +#ifdef MAPNIK_DEBUG + clog << "Cannot determine where to add the spatial filter declaration" << endl; +#endif + } + } + + if (row_limit_ > 0) + { + std::string row_limit_string = "rownum < " + row_limit_; + + if (boost::algorithm::ifind_first(query,"where")) + { + boost::algorithm::ireplace_first(query, "where", row_limit_string + " and"); + } + else if (boost::algorithm::ifind_first(query, table_name)) + { + boost::algorithm::ireplace_first(query, table_name, table_name + " " + row_limit_string); + } + else + { +#ifdef MAPNIK_DEBUG + clog << "Cannot determine where to add the row limit declaration" << endl; +#endif + } + } + + s << query; + +#ifdef MAPNIK_DEBUG + clog << s.str() << endl; +#endif + + return featureset_ptr (new occi_featureset (pool_, + conn_, + s.str(), + desc_.get_encoding(), + multiple_geometries_, + use_connection_pool_, + row_prefetch_, + props.size())); } featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const { if (!is_bound_) bind(); - if (pool_) + std::ostringstream s; + s << "select " << geometry_field_ << " as geom"; + std::vector::const_iterator itr = desc_.get_descriptors().begin(); + std::vector::const_iterator end = desc_.get_descriptors().end(); + unsigned size=0; + while (itr != end) { - std::ostringstream s; - s << "select " << geometry_field_ << " as geom"; - std::vector::const_iterator itr = desc_.get_descriptors().begin(); - std::vector::const_iterator end = desc_.get_descriptors().end(); - unsigned size=0; - while (itr != end) - { - s <<",\""<< itr->get_name() << "\""; - ++itr; - ++size; - } + s << ",\"" << itr->get_name() << "\""; + ++itr; + ++size; + } - s << " from "; + s << " from "; - std::string query (table_); - std::string table_name = mapnik::table_from_sql(query); + std::string query (table_); + std::string table_name = mapnik::table_from_sql(query); + if (use_spatial_index_) + { std::ostringstream spatial_sql; spatial_sql << std::setprecision(16); spatial_sql << " where sdo_filter(" << geometry_field_ << ","; @@ -473,40 +555,52 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt) const if (boost::algorithm::ifind_first(query,"where")) { - boost::algorithm::ireplace_first(query, "where", spatial_sql.str() + " and"); + boost::algorithm::ireplace_first(query, "where", spatial_sql.str() + " and"); } - else if (boost::algorithm::find_first(query,table_name)) + else if (boost::algorithm::ifind_first(query,table_name)) { - boost::algorithm::ireplace_first(query, table_name , table_name + " " + spatial_sql.str()); + boost::algorithm::ireplace_first(query, table_name, table_name + " " + spatial_sql.str()); } - - if (row_limit_ > 0) + else { - std::string row_limit_string = "rownum < " + row_limit_; - - if (boost::algorithm::ifind_first(query,"where")) - { - boost::algorithm::ireplace_first(query, "where", row_limit_string + " and"); - } - else if (boost::algorithm::find_first(query,table_name)) - { - boost::algorithm::ireplace_first(query, table_name , table_name + " " + row_limit_string); - } - } - - s << query; - #ifdef MAPNIK_DEBUG - clog << s.str() << endl; + clog << "Cannot determine where to add the spatial filter declaration" << endl; #endif - - return featureset_ptr (new occi_featureset (pool_, - s.str(), - desc_.get_encoding(), - multiple_geometries_, - row_prefetch_, - size)); + } } - return featureset_ptr(); + if (row_limit_ > 0) + { + std::string row_limit_string = "rownum < " + row_limit_; + + if (boost::algorithm::ifind_first(query,"where")) + { + boost::algorithm::ireplace_first(query, "where", row_limit_string + " and"); + } + else if (boost::algorithm::ifind_first(query, table_name)) + { + boost::algorithm::ireplace_first(query, table_name, table_name + " " + row_limit_string); + } + else + { +#ifdef MAPNIK_DEBUG + clog << "Cannot determine where to add the row limit declaration" << endl; +#endif + } + } + + s << query; + +#ifdef MAPNIK_DEBUG + clog << s.str() << endl; +#endif + + return featureset_ptr (new occi_featureset (pool_, + conn_, + s.str(), + desc_.get_encoding(), + multiple_geometries_, + use_connection_pool_, + row_prefetch_, + size)); } diff --git a/plugins/input/occi/occi_datasource.hpp b/plugins/input/occi/occi_datasource.hpp index 13f30bcdd..f862760be 100644 --- a/plugins/input/occi/occi_datasource.hpp +++ b/plugins/input/occi/occi_datasource.hpp @@ -63,6 +63,8 @@ class occi_datasource : public mapnik::datasource const int row_prefetch_; mutable mapnik::layer_descriptor desc_; mutable oracle::occi::StatelessConnectionPool* pool_; + mutable oracle::occi::Connection* conn_; + bool use_connection_pool_; bool multiple_geometries_; bool use_spatial_index_; }; diff --git a/plugins/input/occi/occi_featureset.cpp b/plugins/input/occi/occi_featureset.cpp index 3d2f120a0..5e4d6f8a2 100644 --- a/plugins/input/occi/occi_featureset.cpp +++ b/plugins/input/occi/occi_featureset.cpp @@ -55,18 +55,24 @@ using oracle::occi::SQLException; using oracle::occi::Type; using oracle::occi::Number; -occi_featureset::occi_featureset(StatelessConnectionPool * pool, +occi_featureset::occi_featureset(StatelessConnectionPool* pool, + Connection* conn, std::string const& sqlstring, std::string const& encoding, bool multiple_geometries, + bool use_connection_pool, unsigned prefetch_rows, unsigned num_attrs) - : conn_(pool), - tr_(new transcoder(encoding)), + : tr_(new transcoder(encoding)), multiple_geometries_(multiple_geometries), num_attrs_(num_attrs), count_(0) { + if (use_connection_pool) + conn_.set_pool(pool); + else + conn_.set_connection(conn, false); + try { rs_ = conn_.execute_query (sqlstring, prefetch_rows); @@ -90,12 +96,12 @@ feature_ptr occi_featureset::next() boost::scoped_ptr geom (dynamic_cast (rs_->getObject(1))); if (geom.get()) { - convert_geometry (geom.get(), feature); + convert_geometry (geom.get(), feature, multiple_geometries_); } std::vector listOfColumns = rs_->getColumnListMetaData(); - for (unsigned int i=1;igetInt (i + 1)); - break; - } - - case oracle::occi::OCCIFLOAT: - case oracle::occi::OCCIBFLOAT: - case oracle::occi::OCCIDOUBLE: - case oracle::occi::OCCIBDOUBLE: - case oracle::occi::OCCINUMBER: - case oracle::occi::OCCI_SQLT_NUM: - { - boost::put(*feature,fld_name,rs_->getDouble (i + 1)); - break; - } + case oracle::occi::OCCIBOOL: + case oracle::occi::OCCIINT: + case oracle::occi::OCCIUNSIGNED_INT: + case oracle::occi::OCCIROWID: + { + boost::put(*feature,fld_name,rs_->getInt (i + 1)); + break; + } + + case oracle::occi::OCCIFLOAT: + case oracle::occi::OCCIBFLOAT: + case oracle::occi::OCCIDOUBLE: + case oracle::occi::OCCIBDOUBLE: + case oracle::occi::OCCINUMBER: + case oracle::occi::OCCI_SQLT_NUM: + { + boost::put(*feature,fld_name,rs_->getDouble (i + 1)); + break; + } - case oracle::occi::OCCICHAR: - case oracle::occi::OCCISTRING: - case oracle::occi::OCCI_SQLT_AFC: - case oracle::occi::OCCI_SQLT_AVC: - case oracle::occi::OCCI_SQLT_CHR: - case oracle::occi::OCCI_SQLT_LVC: - case oracle::occi::OCCI_SQLT_STR: - case oracle::occi::OCCI_SQLT_VCS: - case oracle::occi::OCCI_SQLT_VNU: - case oracle::occi::OCCI_SQLT_VBI: - case oracle::occi::OCCI_SQLT_VST: - case oracle::occi::OCCI_SQLT_RDD: - { - UnicodeString ustr = tr_->transcode (rs_->getString (i + 1).c_str()); - boost::put(*feature,fld_name,ustr); - break; - } - - case oracle::occi::OCCIDATE: - case oracle::occi::OCCITIMESTAMP: - case oracle::occi::OCCI_SQLT_DAT: - case oracle::occi::OCCI_SQLT_TIMESTAMP: - case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: - case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: - case oracle::occi::OCCIPOBJECT: - { + case oracle::occi::OCCICHAR: + case oracle::occi::OCCISTRING: + case oracle::occi::OCCI_SQLT_AFC: + case oracle::occi::OCCI_SQLT_AVC: + case oracle::occi::OCCI_SQLT_CHR: + case oracle::occi::OCCI_SQLT_LVC: + case oracle::occi::OCCI_SQLT_RDD: + case oracle::occi::OCCI_SQLT_STR: + case oracle::occi::OCCI_SQLT_VCS: + case oracle::occi::OCCI_SQLT_VNU: + case oracle::occi::OCCI_SQLT_VBI: + case oracle::occi::OCCI_SQLT_VST: + { + UnicodeString ustr = tr_->transcode (rs_->getString (i + 1).c_str()); + boost::put(*feature,fld_name,ustr); + break; + } + + case oracle::occi::OCCIDATE: + case oracle::occi::OCCITIMESTAMP: + case oracle::occi::OCCIINTERVALDS: + case oracle::occi::OCCIINTERVALYM: + case oracle::occi::OCCI_SQLT_DAT: + case oracle::occi::OCCI_SQLT_DATE: + case oracle::occi::OCCI_SQLT_TIME: + case oracle::occi::OCCI_SQLT_TIME_TZ: + case oracle::occi::OCCI_SQLT_TIMESTAMP: + case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: + case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: + case oracle::occi::OCCI_SQLT_INTERVAL_YM: + case oracle::occi::OCCI_SQLT_INTERVAL_DS: + case oracle::occi::OCCIANYDATA: + case oracle::occi::OCCIBLOB: + case oracle::occi::OCCIBFILE: + case oracle::occi::OCCIBYTES: + case oracle::occi::OCCICLOB: + case oracle::occi::OCCIVECTOR: + case oracle::occi::OCCIMETADATA: + case oracle::occi::OCCIPOBJECT: + case oracle::occi::OCCIREF: + case oracle::occi::OCCIREFANY: + case oracle::occi::OCCISTREAM: + case oracle::occi::OCCICURSOR: + case oracle::occi::OCCI_SQLT_FILE: + case oracle::occi::OCCI_SQLT_CFILE: + case oracle::occi::OCCI_SQLT_REF: + case oracle::occi::OCCI_SQLT_CLOB: + case oracle::occi::OCCI_SQLT_BLOB: + case oracle::occi::OCCI_SQLT_RSET: + { #ifdef MAPNIK_DEBUG - clog << "unsupported type_oid="<getSdo_gtype(); int dimensions = gtype / 1000; @@ -213,23 +247,25 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature) convert_polygon (geom, feature, dimensions); break; case SDO_GTYPE_MULTIPOINT: - convert_multipoint (geom, feature, dimensions); + // Todo - using convert_multipoint_2 until we have proper multipoint handling in convert_multipoint + // http://trac.mapnik.org/ticket/458 + //convert_multipoint (geom, feature, dimensions, multiple_geometries); + convert_multipoint (geom, feature, dimensions, true); break; case SDO_GTYPE_MULTILINE: - convert_multilinestring (geom, feature, dimensions); + convert_multilinestring (geom, feature, dimensions, multiple_geometries); break; case SDO_GTYPE_MULTIPOLYGON: - convert_multipolygon (geom, feature, dimensions); + convert_multipolygon (geom, feature, dimensions, multiple_geometries); break; case SDO_GTYPE_COLLECTION: -#ifdef MAPNIK_DEBUG - clog << "unsupported collection" << endl; -#endif + convert_collection (geom, feature, dimensions, multiple_geometries); break; case SDO_GTYPE_UNKNOWN: default: #ifdef MAPNIK_DEBUG - clog << "unknown geometry_type=" << gtype << endl; + clog << "unknown " << occi_enums::resolve_gtype(geomtype) + << "(gtype=" << gtype << ")" << endl; #endif break; } @@ -238,6 +274,7 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature) void occi_featureset::convert_point (SDOGeometry* geom, feature_ptr feature, int dimensions) { SDOPointType* sdopoint = geom->getSdo_point(); + if (sdopoint && ! sdopoint->isNull()) { geometry_type* point = new geometry_type(mapnik::Point); @@ -252,16 +289,21 @@ void occi_featureset::convert_linestring (SDOGeometry* geom, feature_ptr feature { const std::vector& elem_info = geom->getSdo_elem_info(); const std::vector& ordinates = geom->getSdo_ordinates(); - int ord_size = ordinates.size(); - if (ord_size >= dimensions) + if ((int) ordinates.size() >= dimensions) { - geometry_type * line = new geometry_type(mapnik::LineString); - line->set_capacity (ord_size); - - fill_geometry_type (line, elem_info, ordinates, dimensions, false); - - feature->add_geometry (line); + const bool is_single_geom = true; + const bool is_point_type = false; + const bool multiple_geometries = false; + + convert_ordinates (feature, + mapnik::LineString, + elem_info, + ordinates, + dimensions, + is_single_geom, + is_point_type, + multiple_geometries); } } @@ -269,135 +311,131 @@ void occi_featureset::convert_polygon (SDOGeometry* geom, feature_ptr feature, i { const std::vector& elem_info = geom->getSdo_elem_info(); const std::vector& ordinates = geom->getSdo_ordinates(); - int ord_size = ordinates.size(); - if (ord_size >= dimensions) + if ((int) ordinates.size() >= dimensions) { - geometry_type * poly = new geometry_type(mapnik::Polygon); - poly->set_capacity (ord_size); + const bool is_single_geom = true; + const bool is_point_type = false; + const bool multiple_geometries = false; - fill_geometry_type (poly, elem_info, ordinates, dimensions, false); - - feature->add_geometry (poly); + convert_ordinates (feature, + mapnik::Polygon, + elem_info, + ordinates, + dimensions, + is_single_geom, + is_point_type, + multiple_geometries); } } -void occi_featureset::convert_multipoint (SDOGeometry* geom, feature_ptr feature, int dimensions) +void occi_featureset::convert_multipoint (SDOGeometry* geom, feature_ptr feature, int dimensions, bool multiple_geometries) { const std::vector& elem_info = geom->getSdo_elem_info(); const std::vector& ordinates = geom->getSdo_ordinates(); - int ord_size = ordinates.size(); - if (ord_size >= dimensions) + if ((int) ordinates.size() >= dimensions) { - geometry_type * point = new geometry_type(mapnik::Point); - - fill_geometry_type (point, elem_info, ordinates, dimensions, true); - - feature->add_geometry (point); + const bool is_single_geom = false; + const bool is_point_type = true; + + convert_ordinates (feature, + mapnik::Point, + elem_info, + ordinates, + dimensions, + is_single_geom, + is_point_type, + multiple_geometries); } } -/* -void occi_featureset::convert_multipoint_2 (SDOGeometry* geom, feature_ptr feature, int dimensions) -{ - int num_geometries = geom->getNumGeometries (); - for (int i=0;i(geom->getGeometryRef (i)), feature); - } -} -*/ - -void occi_featureset::convert_multilinestring (SDOGeometry* geom, feature_ptr feature, int dimensions) +void occi_featureset::convert_multilinestring (SDOGeometry* geom, feature_ptr feature, int dimensions, bool multiple_geometries) { const std::vector& elem_info = geom->getSdo_elem_info(); const std::vector& ordinates = geom->getSdo_ordinates(); - int ord_size = ordinates.size(); - if (ord_size >= dimensions) + if ((int) ordinates.size() >= dimensions) { - geometry_type * line = new geometry_type(mapnik::LineString); - line->set_capacity (ord_size); - - fill_geometry_type (line, elem_info, ordinates, dimensions, false); - - feature->add_geometry (line); + const bool is_single_geom = false; + const bool is_point_type = false; + + convert_ordinates (feature, + mapnik::LineString, + elem_info, + ordinates, + dimensions, + is_single_geom, + is_point_type, + multiple_geometries); } } -/* -void occi_featureset::convert_multilinestring_2 (SDOGeometry* geom, feature_ptr feature, int dimensions) -{ - int num_geometries = geom->getNumGeometries (); - for (int i=0;i(geom->getGeometryRef (i)), feature); - } -} -*/ - -void occi_featureset::convert_multipolygon (SDOGeometry* geom, feature_ptr feature, int dimensions) +void occi_featureset::convert_multipolygon (SDOGeometry* geom, feature_ptr feature, int dimensions, bool multiple_geometries) { const std::vector& elem_info = geom->getSdo_elem_info(); const std::vector& ordinates = geom->getSdo_ordinates(); - int ord_size = ordinates.size(); - if (ord_size >= dimensions) + if ((int) ordinates.size() >= dimensions) { - geometry_type * poly = new geometry_type(mapnik::Polygon); - poly->set_capacity (ord_size); - - fill_geometry_type (poly, elem_info, ordinates, dimensions, false); - - feature->add_geometry (poly); + const bool is_single_geom = false; + const bool is_point_type = false; + + convert_ordinates (feature, + mapnik::Polygon, + elem_info, + ordinates, + dimensions, + is_single_geom, + is_point_type, + multiple_geometries); } } -/* -void occi_featureset::convert_multipolygon_2 (SDOGeometry* geom, feature_ptr feature, int dimensions) +void occi_featureset::convert_collection (SDOGeometry* geom, feature_ptr feature, int dimensions, bool multiple_geometries) { - int num_geometries = geom->getNumGeometries (); - for (int i=0;i& elem_info = geom->getSdo_elem_info(); + const std::vector& ordinates = geom->getSdo_ordinates(); + + if ((int) ordinates.size() >= dimensions) { - convert_polygon (static_cast(geom->getGeometryRef (i)), feature); + const bool is_single_geom = false; + const bool is_point_type = false; + + convert_ordinates (feature, + mapnik::Polygon, + elem_info, + ordinates, + dimensions, + is_single_geom, + is_point_type, + multiple_geometries); } } -*/ -/* -void occi_featureset::convert_collection (SDOGeometry* geom, feature_ptr feature, int dimensions) +void occi_featureset::convert_ordinates (mapnik::feature_ptr feature, + const mapnik::eGeomType& geom_type, + const std::vector& elem_info, + const std::vector& ordinates, + const int dimensions, + const bool is_single_geom, + const bool is_point_geom, + const bool multiple_geometries) { - int num_geometries = geom->getNumGeometries (); - for (int i=0;igetGeometryRef (i); - if (g != NULL) - { - convert_geometry (g, feature); - } - } -} -*/ - -void occi_featureset::fill_geometry_type (geometry_type * geom, - const std::vector& elem_info, - const std::vector& ordinates, - const int dimensions, - const bool is_point_geom) -{ - int elem_size = elem_info.size(); - int ord_size = ordinates.size(); - - int offset, etype, interp; + const int elem_size = elem_info.size(); + const int ord_size = ordinates.size(); + if (elem_size >= 0) { - offset = elem_info [0]; - etype = elem_info [1]; - interp = elem_info [2]; + int offset = elem_info [0]; + int etype = elem_info [1]; + int interp = elem_info [2]; - if (elem_size > SDO_ELEM_INFO_SIZE) + if (! is_single_geom && elem_size > SDO_ELEM_INFO_SIZE) { + geometry_type* geom = multiple_geometries ? 0 : new geometry_type(geom_type); + if (geom) geom->set_capacity (ord_size); + for (int i = SDO_ELEM_INFO_SIZE; i < elem_size; i+=3) { int next_offset = elem_info [i]; @@ -405,17 +443,20 @@ void occi_featureset::fill_geometry_type (geometry_type * geom, int next_interp = elem_info [i + 2]; bool is_linear_element = true; bool is_unknown_etype = false; + mapnik::eGeomType gtype = mapnik::Point; switch (etype) { case SDO_ETYPE_POINT: if (interp == SDO_INTERPRETATION_POINT) {} if (interp > SDO_INTERPRETATION_POINT) {} + gtype = mapnik::Point; break; case SDO_ETYPE_LINESTRING: if (interp == SDO_INTERPRETATION_STRAIGHT) {} if (interp == SDO_INTERPRETATION_CIRCULAR) {} + gtype = mapnik::LineString; break; case SDO_ETYPE_POLYGON: @@ -424,6 +465,7 @@ void occi_featureset::fill_geometry_type (geometry_type * geom, if (interp == SDO_INTERPRETATION_CIRCULAR) {} if (interp == SDO_INTERPRETATION_RECTANGLE) {} if (interp == SDO_INTERPRETATION_CIRCLE) {} + gtype = mapnik::Polygon; break; case SDO_ETYPE_COMPOUND_LINESTRING: @@ -431,6 +473,7 @@ void occi_featureset::fill_geometry_type (geometry_type * geom, case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR: // interp = next ETYPE to consider is_linear_element = false; + gtype = mapnik::Polygon; break; case SDO_ETYPE_UNKNOWN: // unknown @@ -444,45 +487,68 @@ void occi_featureset::fill_geometry_type (geometry_type * geom, if (is_linear_element) { + if (multiple_geometries) + { + if (geom) + feature->add_geometry (geom); + + geom = new geometry_type(gtype); + geom->set_capacity ((next_offset - 1) - (offset - 1 - dimensions)); + } + fill_geometry_type (geom, - offset - 1, - next_offset - 1, - ordinates, - dimensions, - is_point_geom); + offset - 1, + next_offset - 1, + ordinates, + dimensions, + is_point_geom); } offset = next_offset; etype = next_etype; interp = next_interp; } + + if (geom) + { + feature->add_geometry (geom); + geom = 0; + } } else { + geometry_type * geom = new geometry_type(geom_type); + geom->set_capacity (ord_size); + fill_geometry_type (geom, - offset - 1, - ord_size, - ordinates, - dimensions, - is_point_geom); + offset - 1, + ord_size, + ordinates, + dimensions, + is_point_geom); + + feature->add_geometry (geom); } } } void occi_featureset::fill_geometry_type (geometry_type * geom, - const int real_offset, - const int next_offset, - const std::vector& ordinates, - const int dimensions, - const bool is_point_geom) + const int real_offset, + const int next_offset, + const std::vector& ordinates, + const int dimensions, + const bool is_point_geom) { geom->move_to ((double) ordinates[real_offset], (double) ordinates[real_offset + 1]); if (is_point_geom) + { for (int p = real_offset + dimensions; p < next_offset; p += dimensions) geom->move_to ((double) ordinates[p], (double) ordinates[p + 1]); + } else + { for (int p = real_offset + dimensions; p < next_offset; p += dimensions) geom->line_to ((double) ordinates[p], (double) ordinates[p + 1]); - + } } diff --git a/plugins/input/occi/occi_featureset.hpp b/plugins/input/occi/occi_featureset.hpp index 4a13abb82..304d40f1c 100644 --- a/plugins/input/occi/occi_featureset.hpp +++ b/plugins/input/occi/occi_featureset.hpp @@ -26,6 +26,7 @@ // mapnik #include +#include #include // boost @@ -38,37 +39,39 @@ class occi_featureset : public mapnik::Featureset { public: - occi_featureset(oracle::occi::StatelessConnectionPool * pool, + occi_featureset(oracle::occi::StatelessConnectionPool* pool, + oracle::occi::Connection* conn, std::string const& sqlstring, std::string const& encoding, bool multiple_geometries, + bool use_connection_pool, unsigned prefetch_rows, unsigned num_attrs); virtual ~occi_featureset(); mapnik::feature_ptr next(); private: - void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature); void convert_point (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); void convert_linestring (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); void convert_polygon (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - void convert_multipoint (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - //void convert_multipoint_2 (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - void convert_multilinestring (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - //void convert_multilinestring_2 (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - void convert_multipolygon (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - //void convert_multipolygon_2 (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); - //void convert_collection (SDOGeometry* geom, mapnik::feature_ptr feature, int dims); + void convert_multipoint (SDOGeometry* geom, mapnik::feature_ptr feature, int dims, bool multiple_geometries); + void convert_multilinestring (SDOGeometry* geom, mapnik::feature_ptr feature, int dims, bool multiple_geometries); + void convert_multipolygon (SDOGeometry* geom, mapnik::feature_ptr feature, int dims, bool multiple_geometries); + void convert_collection (SDOGeometry* geom, mapnik::feature_ptr feature, int dims, bool multiple_geometries); + void convert_geometry (SDOGeometry* geom, mapnik::feature_ptr feature, bool multiple_geometries); + void convert_ordinates (mapnik::feature_ptr feature, + const mapnik::eGeomType& geom_type, + const std::vector& elem_info, + const std::vector& ordinates, + const int dimensions, + const bool is_single_geom, + const bool is_point_geom, + const bool multiple_geometries); void fill_geometry_type (mapnik::geometry_type * geom, - const std::vector& elem_info, - const std::vector& ordinates, - const int dimensions, - const bool is_point_geom); - void fill_geometry_type (mapnik::geometry_type * geom, - const int real_offset, - const int next_offset, - const std::vector& ordinates, - const int dimensions, - const bool is_point_geom); + const int real_offset, + const int next_offset, + const std::vector& ordinates, + const int dimensions, + const bool is_point_geom); occi_connection_ptr conn_; oracle::occi::ResultSet* rs_; boost::scoped_ptr tr_; diff --git a/plugins/input/occi/occi_types.cpp b/plugins/input/occi/occi_types.cpp index c73b78acb..03e205eb5 100644 --- a/plugins/input/occi/occi_types.cpp +++ b/plugins/input/occi/occi_types.cpp @@ -25,3 +25,71 @@ oracle::occi::Environment* occi_environment::env_ = 0; + +std::string occi_enums::resolve_gtype(int gtype) +{ + switch(gtype) + { + case SDO_GTYPE_UNKNOWN: return "SDO_GTYPE_UNKNOWN"; + case SDO_GTYPE_POINT: return "SDO_GTYPE_POINT"; + case SDO_GTYPE_LINE: return "SDO_GTYPE_LINE"; + case SDO_GTYPE_POLYGON: return "SDO_GTYPE_POLYGON"; + case SDO_GTYPE_MULTIPOINT: return "SDO_GTYPE_MULTIPOINT"; + case SDO_GTYPE_MULTILINE: return "SDO_GTYPE_MULTILINE"; + case SDO_GTYPE_MULTIPOLYGON: return "SDO_GTYPE_MULTIPOLYGON"; + case SDO_GTYPE_COLLECTION: return "SDO_GTYPE_COLLECTION"; + default: return ""; + } +} + +std::string occi_enums::resolve_etype(int etype) +{ + switch(etype) + { + case SDO_ETYPE_UNKNOWN: return "SDO_ETYPE_UNKNOWN"; + case SDO_ETYPE_POINT: return "SDO_ETYPE_POINT"; + case SDO_ETYPE_LINESTRING: return "SDO_ETYPE_LINESTRING"; + case SDO_ETYPE_POLYGON: return "SDO_ETYPE_POLYGON"; + case SDO_ETYPE_POLYGON_INTERIOR: return "SDO_ETYPE_POLYGON_INTERIOR"; + case SDO_ETYPE_COMPOUND_LINESTRING: return "SDO_ETYPE_COMPOUND_LINESTRING"; + case SDO_ETYPE_COMPOUND_POLYGON: return "SDO_ETYPE_COMPOUND_POLYGON"; + case SDO_ETYPE_COMPOUND_POLYGON_INTERIOR: return "SDO_ETYPE_COMPOUND_POLYGON_INTERIOR"; + default: return ""; + } +} + +std::string occi_enums::resolve_datatype(int type_id) +{ + switch(type_id) + { + case oracle::occi::OCCIINT: return "OCCIINT"; + case oracle::occi::OCCIUNSIGNED_INT: return "OCCIUNSIGNED_INT"; + case oracle::occi::OCCIFLOAT: return "OCCIFLOAT"; + case oracle::occi::OCCIBFLOAT: return "OCCIBFLOAT"; + case oracle::occi::OCCIDOUBLE: return "OCCIDOUBLE"; + case oracle::occi::OCCIBDOUBLE: return "OCCIBDOUBLE"; + case oracle::occi::OCCINUMBER: return "OCCINUMBER"; + case oracle::occi::OCCI_SQLT_NUM: return "OCCI_SQLT_NUM"; + case oracle::occi::OCCICHAR: return "OCCICHAR"; + case oracle::occi::OCCISTRING: return "OCCISTRING"; + case oracle::occi::OCCI_SQLT_AFC: return "OCCI_SQLT_AFC"; + case oracle::occi::OCCI_SQLT_AVC: return "OCCI_SQLT_AVC"; + case oracle::occi::OCCI_SQLT_CHR: return "OCCI_SQLT_CHR"; + case oracle::occi::OCCI_SQLT_LVC: return "OCCI_SQLT_LVC"; + case oracle::occi::OCCI_SQLT_STR: return "OCCI_SQLT_STR"; + case oracle::occi::OCCI_SQLT_VCS: return "OCCI_SQLT_VCS"; + case oracle::occi::OCCI_SQLT_VNU: return "OCCI_SQLT_VNU"; + case oracle::occi::OCCI_SQLT_VBI: return "OCCI_SQLT_VBI"; + case oracle::occi::OCCI_SQLT_VST: return "OCCI_SQLT_VST"; + case oracle::occi::OCCI_SQLT_RDD: return "OCCI_SQLT_RDD"; + case oracle::occi::OCCIDATE: return "OCCIDATE"; + case oracle::occi::OCCITIMESTAMP: return "OCCITIMESTAMP"; + case oracle::occi::OCCI_SQLT_DAT: return "OCCI_SQLT_DAT"; + case oracle::occi::OCCI_SQLT_TIMESTAMP: return "OCCI_SQLT_TIMESTAMP"; + case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ: return "OCCI_SQLT_TIMESTAMP_LTZ"; + case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ: return "OCCI_SQLT_TIMESTAMP_TZ"; + case oracle::occi::OCCIPOBJECT: return "OCCIPOBJECT"; + default: return ""; + } +} + diff --git a/plugins/input/occi/occi_types.hpp b/plugins/input/occi/occi_types.hpp index 96b4c7822..561c40571 100644 --- a/plugins/input/occi/occi_types.hpp +++ b/plugins/input/occi/occi_types.hpp @@ -132,19 +132,39 @@ private: class occi_connection_ptr { public: - occi_connection_ptr (oracle::occi::StatelessConnectionPool* pool) - : pool_ (pool), - conn_ (pool->getConnection ()), + explicit occi_connection_ptr () + : env_ (occi_environment::get_environment()), + pool_ (0), + conn_ (0), stmt_ (0), - rs_ (0) + rs_ (0), + owns_connection_ (false) { } - + ~occi_connection_ptr () { close_query (true); } + void set_pool(oracle::occi::StatelessConnectionPool* pool) + { + close_query (true); + + pool_ = pool; + conn_ = pool_->getConnection(); + owns_connection_ = true; + } + + void set_connection(oracle::occi::Connection* conn, bool owns_connection) + { + close_query (true); + + pool_ = 0; + conn_ = conn; + owns_connection_ = owns_connection; + } + oracle::occi::ResultSet* execute_query (const std::string& s, const unsigned prefetch = 0) { close_query (false); @@ -187,16 +207,40 @@ private: if (release_connection) { - pool_->releaseConnection (conn_); + if (pool_) + { + pool_->releaseConnection (conn_); + } + else + { + if (owns_connection_) + { + env_->terminateConnection(conn_); + } + } + conn_ = 0; } } } + oracle::occi::Environment* env_; oracle::occi::StatelessConnectionPool* pool_; oracle::occi::Connection* conn_; oracle::occi::Statement* stmt_; oracle::occi::ResultSet* rs_; + bool owns_connection_; }; + +class occi_enums +{ +public: + + static std::string resolve_gtype(int gtype); + static std::string resolve_etype(int etype); + static std::string resolve_datatype(int type_id); +}; + + #endif // OCCI_TYPES_HPP