Compare commits
2 commits
master
...
oracle-nex
Author | SHA1 | Date | |
---|---|---|---|
|
364341152c | ||
|
04a7c7b36f |
6 changed files with 721 additions and 636 deletions
|
@ -52,14 +52,7 @@ using mapnik::datasource_exception;
|
||||||
using mapnik::box2d;
|
using mapnik::box2d;
|
||||||
using mapnik::coord2d;
|
using mapnik::coord2d;
|
||||||
|
|
||||||
using oracle::occi::Environment;
|
|
||||||
using oracle::occi::Connection;
|
|
||||||
using oracle::occi::Statement;
|
|
||||||
using oracle::occi::ResultSet;
|
|
||||||
using oracle::occi::MetaData;
|
|
||||||
using oracle::occi::SQLException;
|
using oracle::occi::SQLException;
|
||||||
using oracle::occi::Type;
|
|
||||||
using oracle::occi::StatelessConnectionPool;
|
|
||||||
|
|
||||||
const double occi_datasource::FMAX = std::numeric_limits<double>::max();
|
const double occi_datasource::FMAX = std::numeric_limits<double>::max();
|
||||||
const std::string occi_datasource::METADATA_TABLE = "USER_SDO_GEOM_METADATA";
|
const std::string occi_datasource::METADATA_TABLE = "USER_SDO_GEOM_METADATA";
|
||||||
|
@ -78,11 +71,12 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
pixel_width_token_("!pixel_width!"),
|
pixel_width_token_("!pixel_width!"),
|
||||||
pixel_height_token_("!pixel_height!"),
|
pixel_height_token_("!pixel_height!"),
|
||||||
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding", "utf-8")),
|
desc_(*params.get<std::string>("type"), *params.get<std::string>("encoding", "utf-8")),
|
||||||
|
creator_(params.get<std::string>("user"),
|
||||||
|
params.get<std::string>("password"),
|
||||||
|
params.get<std::string>("host")),
|
||||||
use_wkb_(*params.get<mapnik::boolean>("use_wkb", false)),
|
use_wkb_(*params.get<mapnik::boolean>("use_wkb", false)),
|
||||||
row_limit_(*params.get<mapnik::value_integer>("row_limit", 0)),
|
row_limit_(*params.get<mapnik::value_integer>("row_limit", 0)),
|
||||||
row_prefetch_(*params.get<int>("row_prefetch", 100)),
|
row_prefetch_(*params.get<int>("row_prefetch", 100))
|
||||||
pool_(0),
|
|
||||||
conn_(0)
|
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_STATS
|
#ifdef MAPNIK_STATS
|
||||||
mapnik::progress_timer __stats__(std::clog, "occi_datasource::init");
|
mapnik::progress_timer __stats__(std::clog, "occi_datasource::init");
|
||||||
|
@ -103,7 +97,7 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
}
|
}
|
||||||
estimate_extent_ = *params.get<mapnik::boolean>("estimate_extent",false);
|
estimate_extent_ = *params.get<mapnik::boolean>("estimate_extent",false);
|
||||||
use_spatial_index_ = *params.get<mapnik::boolean>("use_spatial_index",true);
|
use_spatial_index_ = *params.get<mapnik::boolean>("use_spatial_index",true);
|
||||||
use_connection_pool_ = *params.get<mapnik::boolean>("use_connection_pool",true);
|
persist_connection_ = *params.get<mapnik::boolean>("persist_connection",false);
|
||||||
|
|
||||||
boost::optional<std::string> ext = params.get<std::string>("extent");
|
boost::optional<std::string> ext = params.get<std::string>("extent");
|
||||||
if (ext) extent_initialized_ = extent_.from_string(*ext);
|
if (ext) extent_initialized_ = extent_.from_string(*ext);
|
||||||
|
@ -116,38 +110,20 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect to environment
|
// connect to environment
|
||||||
if (use_connection_pool_)
|
boost::optional<int> initial_size = params.get<int>("initial_size", 1);
|
||||||
{
|
boost::optional<int> max_size = params.get<int>("max_size", 10);
|
||||||
try
|
|
||||||
{
|
|
||||||
pool_ = occi_environment::instance().create_pool(
|
|
||||||
*params.get<std::string>("user"),
|
|
||||||
*params.get<std::string>("password"),
|
|
||||||
*params.get<std::string>("host"),
|
|
||||||
*params.get<int>("max_size", 5),
|
|
||||||
*params.get<int>("initial_size", 1),
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
catch (SQLException& ex)
|
|
||||||
{
|
|
||||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn_ = occi_environment::instance().create_connection(
|
|
||||||
*params.get<std::string>("user"),
|
|
||||||
*params.get<std::string>("password"),
|
|
||||||
*params.get<std::string>("host"));
|
|
||||||
}
|
|
||||||
catch (SQLException& ex)
|
|
||||||
{
|
|
||||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ConnectionManager::instance().registerPool(creator_, *initial_size, *max_size);
|
||||||
|
shared_ptr< Pool<Connection,ConnectionCreator> > pool =
|
||||||
|
ConnectionManager::instance().getPool(creator_.id());
|
||||||
|
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
|
if (! conn) return;
|
||||||
|
|
||||||
|
if (conn->isOK())
|
||||||
|
{
|
||||||
// extract real table name
|
// extract real table name
|
||||||
table_name_ = mapnik::sql_utils::table_from_sql(table_);
|
table_name_ = mapnik::sql_utils::table_from_sql(table_);
|
||||||
|
|
||||||
|
@ -171,12 +147,8 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
occi_connection_ptr conn;
|
boost::shared_ptr<ResultSet> rs = conn->execute_query(s.str());
|
||||||
if (use_connection_pool_) conn.set_pool(pool_);
|
if (rs && rs->next())
|
||||||
else conn.set_connection(conn_, false);
|
|
||||||
|
|
||||||
ResultSet* rs = conn.execute_query(s.str());
|
|
||||||
if (rs && rs->next ())
|
|
||||||
{
|
{
|
||||||
if (! srid_initialized_)
|
if (! srid_initialized_)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +160,8 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
{
|
{
|
||||||
geometry_field_ = rs->getString(2);
|
geometry_field_ = rs->getString(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rs->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException& ex)
|
catch (SQLException& ex)
|
||||||
|
@ -209,30 +183,14 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
occi_connection_ptr conn;
|
boost::shared_ptr<ResultSet> rs = conn->execute_query(s.str());
|
||||||
if (use_connection_pool_) conn.set_pool(pool_);
|
|
||||||
else conn.set_connection(conn_, false);
|
|
||||||
|
|
||||||
ResultSet* rs = conn.execute_query(s.str());
|
|
||||||
if (rs)
|
if (rs)
|
||||||
{
|
{
|
||||||
std::vector<MetaData> listOfColumns = rs->getColumnListMetaData();
|
unsigned int numFields = rs->getNumFields();
|
||||||
|
for (unsigned int i = 0; i < numFields; ++i)
|
||||||
for (unsigned int i = 0; i < listOfColumns.size(); ++i)
|
|
||||||
{
|
{
|
||||||
MetaData columnObj = listOfColumns[i];
|
std::string fld_name = rs->getFieldName(i);
|
||||||
|
int type_oid = rs->getTypeOID(i);
|
||||||
std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
|
|
||||||
int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
|
|
||||||
if (type_code == OCCI_TYPECODE_OBJECT)
|
|
||||||
{
|
|
||||||
desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Object));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (type_oid)
|
switch (type_oid)
|
||||||
{
|
{
|
||||||
|
@ -300,7 +258,7 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
case oracle::occi::OCCI_SQLT_BLOB:
|
case oracle::occi::OCCI_SQLT_BLOB:
|
||||||
case oracle::occi::OCCI_SQLT_RSET:
|
case oracle::occi::OCCI_SQLT_RSET:
|
||||||
MAPNIK_LOG_WARN(occi) << "occi_datasource: Unsupported datatype "
|
MAPNIK_LOG_WARN(occi) << "occi_datasource: Unsupported datatype "
|
||||||
<< occi_enums::resolve_datatype(type_oid)
|
<< Environment::instance().resolve_datatype(type_oid)
|
||||||
<< " (type_oid=" << type_oid << ")";
|
<< " (type_oid=" << type_oid << ")";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -309,6 +267,8 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rs->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException& ex)
|
catch (SQLException& ex)
|
||||||
|
@ -316,23 +276,24 @@ occi_datasource::occi_datasource(parameters const& params)
|
||||||
throw datasource_exception(ex.getMessage());
|
throw datasource_exception(ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
occi_datasource::~occi_datasource()
|
occi_datasource::~occi_datasource()
|
||||||
{
|
{
|
||||||
if (use_connection_pool_)
|
if (! persist_connection_)
|
||||||
{
|
{
|
||||||
if (pool_ != 0)
|
boost::shared_ptr< Pool<Connection,ConnectionCreator> > pool =
|
||||||
|
ConnectionManager::instance().getPool(creator_.id());
|
||||||
|
if (pool)
|
||||||
{
|
{
|
||||||
occi_environment::instance().destroy_pool(pool_);
|
boost::shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
|
conn->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (conn_ != 0)
|
|
||||||
{
|
|
||||||
occi_environment::instance().destroy_connection(conn_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +313,13 @@ box2d<double> occi_datasource::envelope() const
|
||||||
|
|
||||||
double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0;
|
double lox = 0.0, loy = 0.0, hix = 0.0, hiy = 0.0;
|
||||||
|
|
||||||
|
boost::shared_ptr< Pool<Connection,ConnectionCreator> > pool =
|
||||||
|
ConnectionManager::instance().getPool(creator_.id());
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
if (estimate_extent_)
|
if (estimate_extent_)
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_STATS
|
#ifdef MAPNIK_STATS
|
||||||
|
@ -368,11 +335,7 @@ box2d<double> occi_datasource::envelope() const
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
occi_connection_ptr conn;
|
boost::shared_ptr<ResultSet> rs = conn->execute_query(s.str());
|
||||||
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())
|
if (rs && rs->next())
|
||||||
{
|
{
|
||||||
lox = rs->getDouble(1);
|
lox = rs->getDouble(1);
|
||||||
|
@ -381,6 +344,8 @@ box2d<double> occi_datasource::envelope() const
|
||||||
hiy = rs->getDouble(4);
|
hiy = rs->getDouble(4);
|
||||||
extent_.init(lox, loy, hix, hiy);
|
extent_.init(lox, loy, hix, hiy);
|
||||||
extent_initialized_ = true;
|
extent_initialized_ = true;
|
||||||
|
|
||||||
|
rs->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException& ex)
|
catch (SQLException& ex)
|
||||||
|
@ -407,11 +372,7 @@ box2d<double> occi_datasource::envelope() const
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
occi_connection_ptr conn;
|
boost::shared_ptr<ResultSet> rs = conn->execute_query(s.str());
|
||||||
if (use_connection_pool_) conn.set_pool(pool_);
|
|
||||||
else conn.set_connection(conn_, false);
|
|
||||||
|
|
||||||
ResultSet* rs = conn.execute_query(s.str());
|
|
||||||
if (rs)
|
if (rs)
|
||||||
{
|
{
|
||||||
if (rs->next())
|
if (rs->next())
|
||||||
|
@ -427,6 +388,8 @@ box2d<double> occi_datasource::envelope() const
|
||||||
}
|
}
|
||||||
extent_.init(lox, loy, hix, hiy);
|
extent_.init(lox, loy, hix, hiy);
|
||||||
extent_initialized_ = true;
|
extent_initialized_ = true;
|
||||||
|
|
||||||
|
rs->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (SQLException& ex)
|
catch (SQLException& ex)
|
||||||
|
@ -434,6 +397,8 @@ box2d<double> occi_datasource::envelope() const
|
||||||
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
throw datasource_exception("OCCI Plugin: " + ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (! extent_initialized_)
|
if (! extent_initialized_)
|
||||||
{
|
{
|
||||||
|
@ -505,6 +470,13 @@ featureset_ptr occi_datasource::features(query const& q) const
|
||||||
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features");
|
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
boost::shared_ptr< Pool<Connection,ConnectionCreator> > pool =
|
||||||
|
ConnectionManager::instance().getPool(creator_.id());
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
box2d<double> const& box = q.get_bbox();
|
box2d<double> const& box = q.get_bbox();
|
||||||
const double px_gw = 1.0 / boost::get<0>(q.resolution());
|
const double px_gw = 1.0 / boost::get<0>(q.resolution());
|
||||||
const double px_gh = 1.0 / boost::get<1>(q.resolution());
|
const double px_gh = 1.0 / boost::get<1>(q.resolution());
|
||||||
|
@ -562,14 +534,14 @@ featureset_ptr occi_datasource::features(query const& q) const
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
|
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
|
||||||
|
|
||||||
return boost::make_shared<occi_featureset>(pool_,
|
return boost::make_shared<occi_featureset>(conn->execute_query(s.str(), row_prefetch_),
|
||||||
conn_,
|
|
||||||
ctx,
|
ctx,
|
||||||
s.str(),
|
|
||||||
desc_.get_encoding(),
|
desc_.get_encoding(),
|
||||||
use_connection_pool_,
|
use_wkb_);
|
||||||
use_wkb_,
|
}
|
||||||
row_prefetch_);
|
}
|
||||||
|
|
||||||
|
return featureset_ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol) const
|
featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol) const
|
||||||
|
@ -578,6 +550,13 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol)
|
||||||
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features_at_point");
|
mapnik::progress_timer __stats__(std::clog, "occi_datasource::features_at_point");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
boost::shared_ptr< Pool<Connection,ConnectionCreator> > pool =
|
||||||
|
ConnectionManager::instance().getPool(creator_.id());
|
||||||
|
if (pool)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<Connection> conn = pool->borrowObject();
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
s << "SELECT ";
|
s << "SELECT ";
|
||||||
if (use_wkb_)
|
if (use_wkb_)
|
||||||
|
@ -631,12 +610,12 @@ featureset_ptr occi_datasource::features_at_point(coord2d const& pt, double tol)
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
|
MAPNIK_LOG_DEBUG(occi) << "occi_datasource: " << s.str();
|
||||||
|
|
||||||
return boost::make_shared<occi_featureset>(pool_,
|
return boost::make_shared<occi_featureset>(conn->execute_query(s.str(), row_prefetch_),
|
||||||
conn_,
|
|
||||||
ctx,
|
ctx,
|
||||||
s.str(),
|
|
||||||
desc_.get_encoding(),
|
desc_.get_encoding(),
|
||||||
use_connection_pool_,
|
use_wkb_);
|
||||||
use_wkb_,
|
}
|
||||||
row_prefetch_);
|
}
|
||||||
|
|
||||||
|
return featureset_ptr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,12 +82,11 @@ private:
|
||||||
const std::string pixel_width_token_;
|
const std::string pixel_width_token_;
|
||||||
const std::string pixel_height_token_;
|
const std::string pixel_height_token_;
|
||||||
mapnik::layer_descriptor desc_;
|
mapnik::layer_descriptor desc_;
|
||||||
|
ConnectionCreator<Connection> creator_;
|
||||||
bool use_wkb_;
|
bool use_wkb_;
|
||||||
mapnik::value_integer row_limit_;
|
mapnik::value_integer row_limit_;
|
||||||
int row_prefetch_;
|
int row_prefetch_;
|
||||||
oracle::occi::StatelessConnectionPool* pool_;
|
bool persist_connection_;
|
||||||
oracle::occi::Connection* conn_;
|
|
||||||
bool use_connection_pool_;
|
|
||||||
bool use_spatial_index_;
|
bool use_spatial_index_;
|
||||||
bool estimate_extent_;
|
bool estimate_extent_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,49 +43,22 @@ using mapnik::transcoder;
|
||||||
using mapnik::datasource_exception;
|
using mapnik::datasource_exception;
|
||||||
using mapnik::feature_factory;
|
using mapnik::feature_factory;
|
||||||
|
|
||||||
using oracle::occi::Connection;
|
|
||||||
using oracle::occi::Statement;
|
|
||||||
using oracle::occi::ResultSet;
|
|
||||||
using oracle::occi::StatelessConnectionPool;
|
|
||||||
using oracle::occi::MetaData;
|
using oracle::occi::MetaData;
|
||||||
using oracle::occi::SQLException;
|
using oracle::occi::SQLException;
|
||||||
using oracle::occi::Type;
|
using oracle::occi::Type;
|
||||||
using oracle::occi::Number;
|
using oracle::occi::Number;
|
||||||
using oracle::occi::Blob;
|
using oracle::occi::Blob;
|
||||||
|
|
||||||
occi_featureset::occi_featureset(StatelessConnectionPool* pool,
|
occi_featureset::occi_featureset(boost::shared_ptr<ResultSet> rs,
|
||||||
Connection* conn,
|
|
||||||
mapnik::context_ptr const& ctx,
|
mapnik::context_ptr const& ctx,
|
||||||
std::string const& sqlstring,
|
|
||||||
std::string const& encoding,
|
std::string const& encoding,
|
||||||
bool use_connection_pool,
|
bool use_wkb)
|
||||||
bool use_wkb,
|
: rs_(rs),
|
||||||
unsigned prefetch_rows)
|
|
||||||
: rs_(NULL),
|
|
||||||
tr_(new transcoder(encoding)),
|
tr_(new transcoder(encoding)),
|
||||||
feature_id_(1),
|
feature_id_(1),
|
||||||
ctx_(ctx),
|
ctx_(ctx),
|
||||||
use_wkb_(use_wkb)
|
use_wkb_(use_wkb)
|
||||||
{
|
{
|
||||||
if (use_connection_pool)
|
|
||||||
{
|
|
||||||
conn_.set_pool(pool);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
conn_.set_connection(conn, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
rs_ = conn_.execute_query(sqlstring, prefetch_rows);
|
|
||||||
}
|
|
||||||
catch (SQLException &ex)
|
|
||||||
{
|
|
||||||
MAPNIK_LOG_ERROR(occi) << "OCCI Plugin: error processing " << sqlstring << " : " << ex.getMessage();
|
|
||||||
|
|
||||||
rs_ = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
occi_featureset::~occi_featureset()
|
occi_featureset::~occi_featureset()
|
||||||
|
@ -94,25 +67,13 @@ occi_featureset::~occi_featureset()
|
||||||
|
|
||||||
feature_ptr occi_featureset::next()
|
feature_ptr occi_featureset::next()
|
||||||
{
|
{
|
||||||
while (rs_ != NULL && rs_->next() == oracle::occi::ResultSet::DATA_AVAILABLE)
|
while (rs_ != NULL && rs_->next())
|
||||||
{
|
{
|
||||||
feature_ptr feature(feature_factory::create(ctx_, feature_id_));
|
feature_ptr feature(feature_factory::create(ctx_, feature_id_));
|
||||||
|
|
||||||
if (use_wkb_)
|
if (use_wkb_)
|
||||||
{
|
{
|
||||||
Blob blob = rs_->getBlob(1);
|
unsigned int size = rs_->getBlob(1, buffer_);
|
||||||
blob.open(oracle::occi::OCCI_LOB_READONLY);
|
|
||||||
|
|
||||||
unsigned int size = blob.length();
|
|
||||||
if (buffer_.size() < size)
|
|
||||||
{
|
|
||||||
buffer_.resize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
oracle::occi::Stream* instream = blob.getStream(1, 0);
|
|
||||||
instream->readBuffer(buffer_.data(), size);
|
|
||||||
blob.closeStream(instream);
|
|
||||||
blob.close();
|
|
||||||
|
|
||||||
if (! geometry_utils::from_wkb(feature->paths(), buffer_.data(), size))
|
if (! geometry_utils::from_wkb(feature->paths(), buffer_.data(), size))
|
||||||
{
|
{
|
||||||
|
@ -132,22 +93,11 @@ feature_ptr occi_featureset::next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MetaData> listOfColumns = rs_->getColumnListMetaData();
|
unsigned int numFields = rs_->getNumFields();
|
||||||
|
for (unsigned int i = 0; i < numFields; ++i)
|
||||||
for (unsigned int i = 1; i < listOfColumns.size(); ++i)
|
|
||||||
{
|
{
|
||||||
MetaData columnObj = listOfColumns[i];
|
std::string fld_name = rs_->getFieldName(i);
|
||||||
|
int type_oid = rs_->getTypeOID(i);
|
||||||
std::string fld_name = columnObj.getString(MetaData::ATTR_NAME);
|
|
||||||
int type_oid = columnObj.getInt(MetaData::ATTR_DATA_TYPE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
int type_code = columnObj.getInt(MetaData::ATTR_TYPECODE);
|
|
||||||
if (type_code == OCCI_TYPECODE_OBJECT)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (type_oid)
|
switch (type_oid)
|
||||||
{
|
{
|
||||||
|
@ -192,7 +142,7 @@ feature_ptr occi_featureset::next()
|
||||||
case oracle::occi::OCCI_SQLT_TIMESTAMP:
|
case oracle::occi::OCCI_SQLT_TIMESTAMP:
|
||||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
|
case oracle::occi::OCCI_SQLT_TIMESTAMP_LTZ:
|
||||||
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
|
case oracle::occi::OCCI_SQLT_TIMESTAMP_TZ:
|
||||||
feature->put(fld_name, (UnicodeString)tr_->transcode(rs_->getString(i + 1).c_str()));
|
feature->put(fld_name, (UnicodeString)tr_->transcode(rs_->getString(i + 1)));
|
||||||
break;
|
break;
|
||||||
case oracle::occi::OCCIINTERVALDS:
|
case oracle::occi::OCCIINTERVALDS:
|
||||||
case oracle::occi::OCCIINTERVALYM:
|
case oracle::occi::OCCIINTERVALYM:
|
||||||
|
@ -218,7 +168,7 @@ feature_ptr occi_featureset::next()
|
||||||
case oracle::occi::OCCI_SQLT_RSET:
|
case oracle::occi::OCCI_SQLT_RSET:
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unsupported datatype "
|
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unsupported datatype "
|
||||||
<< occi_enums::resolve_datatype(type_oid)
|
<< Environment::instance().resolve_datatype(type_oid)
|
||||||
<< " (type_oid=" << type_oid << ")";
|
<< " (type_oid=" << type_oid << ")";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -368,7 +318,7 @@ void occi_featureset::convert_geometry(SDOGeometry* geom, feature_ptr feature)
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown oracle enum "
|
MAPNIK_LOG_WARN(occi) << "occi_featureset: Unknown oracle enum "
|
||||||
<< occi_enums::resolve_gtype(geomtype)
|
<< Environment::instance().resolve_gtype(geomtype)
|
||||||
<< "(gtype=" << gtype << ")";
|
<< "(gtype=" << gtype << ")";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -41,14 +41,10 @@
|
||||||
class occi_featureset : public mapnik::Featureset
|
class occi_featureset : public mapnik::Featureset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
occi_featureset(oracle::occi::StatelessConnectionPool* pool,
|
occi_featureset(boost::shared_ptr<ResultSet> rs,
|
||||||
oracle::occi::Connection* conn,
|
|
||||||
mapnik::context_ptr const& ctx,
|
mapnik::context_ptr const& ctx,
|
||||||
std::string const& sqlstring,
|
|
||||||
std::string const& encoding,
|
std::string const& encoding,
|
||||||
bool use_connection_pool,
|
bool use_wkb);
|
||||||
bool use_wkb,
|
|
||||||
unsigned prefetch_rows);
|
|
||||||
virtual ~occi_featureset();
|
virtual ~occi_featureset();
|
||||||
mapnik::feature_ptr next();
|
mapnik::feature_ptr next();
|
||||||
|
|
||||||
|
@ -68,8 +64,7 @@ private:
|
||||||
const int dimensions,
|
const int dimensions,
|
||||||
const bool is_point_geom);
|
const bool is_point_geom);
|
||||||
|
|
||||||
occi_connection_ptr conn_;
|
boost::shared_ptr<ResultSet> rs_;
|
||||||
oracle::occi::ResultSet* rs_;
|
|
||||||
boost::scoped_ptr<mapnik::transcoder> tr_;
|
boost::scoped_ptr<mapnik::transcoder> tr_;
|
||||||
mapnik::value_integer feature_id_;
|
mapnik::value_integer feature_id_;
|
||||||
mapnik::context_ptr ctx_;
|
mapnik::context_ptr ctx_;
|
||||||
|
|
|
@ -21,71 +21,3 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "occi_types.hpp"
|
#include "occi_types.hpp"
|
||||||
|
|
||||||
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 "<unknown SDO_GTYPE>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 "<unknown SDO_ETYPE>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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_LNG: return "OCCI_SQLT_LNG";
|
|
||||||
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 "<unknown ATTR_DATA_TYPE>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,13 +25,22 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/debug.hpp>
|
#include <mapnik/debug.hpp>
|
||||||
|
#include <mapnik/pool.hpp>
|
||||||
#include <mapnik/utils.hpp>
|
#include <mapnik/utils.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
#ifdef MAPNIK_THREADSAFE
|
#ifdef MAPNIK_THREADSAFE
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// stl
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
// occi
|
// occi
|
||||||
#include <occi.h>
|
#include <occi.h>
|
||||||
|
|
||||||
|
@ -46,6 +55,10 @@
|
||||||
#error Only ORACLE 10g >= 10.2.0.X is supported !
|
#error Only ORACLE 10g >= 10.2.0.X is supported !
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using mapnik::Pool;
|
||||||
|
using mapnik::singleton;
|
||||||
|
using mapnik::CreateStatic;
|
||||||
|
|
||||||
// geometry types definitions
|
// geometry types definitions
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -83,9 +96,9 @@ enum
|
||||||
SDO_INTERPRETATION_CIRCULAR = 2
|
SDO_INTERPRETATION_CIRCULAR = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class occi_environment : public mapnik::singleton<occi_environment, mapnik::CreateStatic>
|
class Environment : public mapnik::singleton<Environment, mapnik::CreateStatic>
|
||||||
{
|
{
|
||||||
friend class mapnik::CreateStatic<occi_environment>;
|
friend class mapnik::CreateStatic<Environment>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -94,51 +107,77 @@ public:
|
||||||
return env_;
|
return env_;
|
||||||
}
|
}
|
||||||
|
|
||||||
oracle::occi::Connection* create_connection(
|
std::string resolve_gtype(int gtype)
|
||||||
const std::string& user,
|
|
||||||
const std::string& password,
|
|
||||||
const std::string& host)
|
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_connection";
|
switch (gtype)
|
||||||
|
{
|
||||||
return env_->createConnection(user, password, host);
|
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 "<unknown SDO_GTYPE>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_connection(oracle::occi::Connection* conn)
|
std::string resolve_etype(int etype)
|
||||||
{
|
{
|
||||||
env_->terminateConnection(conn);
|
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 "<unknown SDO_ETYPE>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oracle::occi::StatelessConnectionPool* create_pool(
|
std::string resolve_datatype(int type_id)
|
||||||
const std::string& user,
|
|
||||||
const std::string& password,
|
|
||||||
const std::string& host,
|
|
||||||
int max_size,
|
|
||||||
int initial_size,
|
|
||||||
int incr_size)
|
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_pool";
|
switch (type_id)
|
||||||
|
{
|
||||||
return env_->createStatelessConnectionPool(
|
case oracle::occi::OCCIINT: return "OCCIINT";
|
||||||
user,
|
case oracle::occi::OCCIUNSIGNED_INT: return "OCCIUNSIGNED_INT";
|
||||||
password,
|
case oracle::occi::OCCIFLOAT: return "OCCIFLOAT";
|
||||||
host,
|
case oracle::occi::OCCIBFLOAT: return "OCCIBFLOAT";
|
||||||
max_size,
|
case oracle::occi::OCCIDOUBLE: return "OCCIDOUBLE";
|
||||||
initial_size,
|
case oracle::occi::OCCIBDOUBLE: return "OCCIBDOUBLE";
|
||||||
incr_size,
|
case oracle::occi::OCCINUMBER: return "OCCINUMBER";
|
||||||
oracle::occi::StatelessConnectionPool::HOMOGENEOUS);
|
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_LNG: return "OCCI_SQLT_LNG";
|
||||||
|
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 "<unknown ATTR_DATA_TYPE>";
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_pool(oracle::occi::StatelessConnectionPool* pool)
|
|
||||||
{
|
|
||||||
env_->terminateStatelessConnectionPool(
|
|
||||||
pool,
|
|
||||||
oracle::occi::StatelessConnectionPool::SPD_FORCE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
occi_environment()
|
Environment()
|
||||||
: env_(0)
|
: env_(0)
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_environment: constructor";
|
MAPNIK_LOG_DEBUG(occi) << "occi_environment: constructor";
|
||||||
|
@ -149,7 +188,7 @@ private:
|
||||||
RegisterClasses(env_);
|
RegisterClasses(env_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~occi_environment()
|
~Environment()
|
||||||
{
|
{
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_environment: destructor";
|
MAPNIK_LOG_DEBUG(occi) << "occi_environment: destructor";
|
||||||
|
|
||||||
|
@ -160,48 +199,17 @@ private:
|
||||||
oracle::occi::Environment* env_;
|
oracle::occi::Environment* env_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ResultSet
|
||||||
class occi_connection_ptr
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit occi_connection_ptr()
|
ResultSet(oracle::occi::Connection* conn,
|
||||||
: pool_(0),
|
std::string const& s,
|
||||||
conn_(0),
|
const unsigned prefetch = 0)
|
||||||
stmt_(0),
|
: conn_(conn),
|
||||||
rs_(0),
|
stmt_(NULL),
|
||||||
owns_connection_(false)
|
rs_(NULL),
|
||||||
|
metadata_queried_(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(std::string const& s, const unsigned prefetch = 0)
|
|
||||||
{
|
|
||||||
close_query(false);
|
|
||||||
|
|
||||||
MAPNIK_LOG_DEBUG(occi) << "occi_connection_ptr: " << s;
|
|
||||||
|
|
||||||
stmt_ = conn_->createStatement(s);
|
stmt_ = conn_->createStatement(s);
|
||||||
|
|
||||||
if (prefetch > 0)
|
if (prefetch > 0)
|
||||||
|
@ -211,60 +219,282 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
rs_ = stmt_->executeQuery();
|
rs_ = stmt_->executeQuery();
|
||||||
|
|
||||||
return rs_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
virtual ~ResultSet()
|
||||||
void close_query(const bool release_connection)
|
|
||||||
{
|
{
|
||||||
if (conn_)
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void close()
|
||||||
{
|
{
|
||||||
if (stmt_)
|
if (stmt_)
|
||||||
{
|
{
|
||||||
if (rs_)
|
if (rs_)
|
||||||
{
|
{
|
||||||
stmt_->closeResultSet(rs_);
|
stmt_->closeResultSet(rs_);
|
||||||
rs_ = 0;
|
rs_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn_->terminateStatement(stmt_);
|
conn_->terminateStatement(stmt_);
|
||||||
stmt_ = 0;
|
stmt_ = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
if (release_connection)
|
|
||||||
{
|
|
||||||
if (pool_)
|
|
||||||
{
|
|
||||||
pool_->releaseConnection(conn_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (owns_connection_)
|
|
||||||
{
|
|
||||||
occi_environment::instance().destroy_connection(conn_);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conn_ = 0;
|
inline bool next()
|
||||||
|
{
|
||||||
|
return rs_ && rs_->next() == oracle::occi::ResultSet::DATA_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int getNumFields()
|
||||||
|
{
|
||||||
|
query_metadata();
|
||||||
|
|
||||||
|
return metadata_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* getFieldName(int index)
|
||||||
|
{
|
||||||
|
query_metadata();
|
||||||
|
|
||||||
|
if (index >= 0 && (size_t)index < metadata_.size())
|
||||||
|
{
|
||||||
|
return metadata_[index].getString(oracle::occi::MetaData::ATTR_NAME).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getTypeOID(int index)
|
||||||
|
{
|
||||||
|
query_metadata();
|
||||||
|
|
||||||
|
if (index >= 0 && (size_t)index < metadata_.size())
|
||||||
|
{
|
||||||
|
return metadata_[index].getInt(oracle::occi::MetaData::ATTR_DATA_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isNull(int index) const
|
||||||
|
{
|
||||||
|
return rs_->isNull(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getInt(int index)
|
||||||
|
{
|
||||||
|
return rs_->getInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float getFloat(int index)
|
||||||
|
{
|
||||||
|
return rs_->getFloat(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double getDouble(int index)
|
||||||
|
{
|
||||||
|
return rs_->getDouble(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline oracle::occi::PObject* getObject(int index)
|
||||||
|
{
|
||||||
|
return rs_->getObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* getString(int index)
|
||||||
|
{
|
||||||
|
return rs_->getString(index).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned int getBlob(int index, std::vector<char>& buffer)
|
||||||
|
{
|
||||||
|
if (! rs_->isNull(index))
|
||||||
|
{
|
||||||
|
oracle::occi::Blob blob = rs_->getBlob(1);
|
||||||
|
blob.open(oracle::occi::OCCI_LOB_READONLY);
|
||||||
|
|
||||||
|
unsigned int size = blob.length();
|
||||||
|
if (buffer.size() < size)
|
||||||
|
{
|
||||||
|
buffer.resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
oracle::occi::Stream* instream = blob.getStream(1, 0);
|
||||||
|
instream->readBuffer(buffer.data(), size);
|
||||||
|
blob.closeStream(instream);
|
||||||
|
blob.close();
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
inline void query_metadata()
|
||||||
|
{
|
||||||
|
if (! metadata_queried_ && rs_)
|
||||||
|
{
|
||||||
|
metadata_ = rs_->getColumnListMetaData();
|
||||||
|
metadata_queried_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oracle::occi::StatelessConnectionPool* pool_;
|
|
||||||
oracle::occi::Connection* conn_;
|
oracle::occi::Connection* conn_;
|
||||||
oracle::occi::Statement* stmt_;
|
oracle::occi::Statement* stmt_;
|
||||||
oracle::occi::ResultSet* rs_;
|
oracle::occi::ResultSet* rs_;
|
||||||
bool owns_connection_;
|
|
||||||
|
std::vector<oracle::occi::MetaData> metadata_;
|
||||||
|
bool metadata_queried_;
|
||||||
|
|
||||||
|
ResultSet(const ResultSet&);
|
||||||
|
ResultSet& operator=(const ResultSet);
|
||||||
};
|
};
|
||||||
|
|
||||||
class occi_enums
|
class Connection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit Connection(std::string const& user,
|
||||||
|
std::string const& pass,
|
||||||
|
std::string const& host)
|
||||||
|
: conn_(NULL)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(occi) << "occi_environment: create_connection";
|
||||||
|
|
||||||
static std::string resolve_gtype(int gtype);
|
conn_ = Environment::instance().get_environment()->createConnection(user, pass, host);
|
||||||
static std::string resolve_etype(int etype);
|
}
|
||||||
static std::string resolve_datatype(int type_id);
|
|
||||||
|
~Connection()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<ResultSet> execute_query(std::string const& s, const unsigned prefetch = 0)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(occi) << "occi_connection_ptr: " << s;
|
||||||
|
|
||||||
|
return boost::make_shared<ResultSet>(conn_, s, prefetch);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isOK()
|
||||||
|
{
|
||||||
|
return (conn_ != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
if (conn_)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(occi) << "occi_environment: destroy_connection";
|
||||||
|
|
||||||
|
Environment::instance().get_environment()->terminateConnection(conn_);
|
||||||
|
|
||||||
|
conn_ = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
oracle::occi::Connection* conn_;
|
||||||
|
oracle::occi::Statement* stmt_;
|
||||||
|
oracle::occi::ResultSet* rs_;
|
||||||
|
|
||||||
|
Connection(const Connection&);
|
||||||
|
Connection& operator=(const Connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ConnectionCreator
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConnectionCreator(boost::optional<std::string> const& user,
|
||||||
|
boost::optional<std::string> const& pass,
|
||||||
|
boost::optional<std::string> const& host)
|
||||||
|
: user_(user),
|
||||||
|
pass_(pass),
|
||||||
|
host_(host)
|
||||||
|
{}
|
||||||
|
|
||||||
|
T* operator()() const
|
||||||
|
{
|
||||||
|
return new T(*user_, *pass_, *host_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string id() const
|
||||||
|
{
|
||||||
|
return connection_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string connection_string() const
|
||||||
|
{
|
||||||
|
std::string connect_str = connection_string_safe();
|
||||||
|
if (pass_ && !pass_->empty()) connect_str += " password=" + *pass_;
|
||||||
|
return connect_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string connection_string_safe() const
|
||||||
|
{
|
||||||
|
std::string connect_str;
|
||||||
|
if (host_ && !host_->empty()) connect_str += "host=" + *host_;
|
||||||
|
if (user_ && !user_->empty()) connect_str += " user=" + *user_;
|
||||||
|
return connect_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::optional<std::string> user_;
|
||||||
|
boost::optional<std::string> pass_;
|
||||||
|
boost::optional<std::string> host_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConnectionManager : public singleton <ConnectionManager,CreateStatic>
|
||||||
|
{
|
||||||
|
|
||||||
|
friend class CreateStatic<ConnectionManager>;
|
||||||
|
typedef Pool<Connection,ConnectionCreator> PoolType;
|
||||||
|
typedef std::map<std::string,boost::shared_ptr<PoolType> > ContType;
|
||||||
|
typedef boost::shared_ptr<Connection> HolderType;
|
||||||
|
ContType pools_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool registerPool(const ConnectionCreator<Connection>& creator,unsigned initialSize,unsigned maxSize)
|
||||||
|
{
|
||||||
|
ContType::const_iterator itr = pools_.find(creator.id());
|
||||||
|
|
||||||
|
if (itr != pools_.end())
|
||||||
|
{
|
||||||
|
itr->second->set_initial_size(initialSize);
|
||||||
|
itr->second->set_max_size(maxSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return pools_.insert(
|
||||||
|
std::make_pair(creator.id(),
|
||||||
|
boost::make_shared<PoolType>(creator,initialSize,maxSize))).second;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<PoolType> getPool(std::string const& key)
|
||||||
|
{
|
||||||
|
ContType::const_iterator itr=pools_.find(key);
|
||||||
|
if (itr!=pools_.end())
|
||||||
|
{
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
static const boost::shared_ptr<PoolType> emptyPool;
|
||||||
|
return emptyPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionManager() {}
|
||||||
|
private:
|
||||||
|
ConnectionManager(const ConnectionManager&);
|
||||||
|
ConnectionManager& operator=(const ConnectionManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // OCCI_TYPES_HPP
|
#endif // OCCI_TYPES_HPP
|
||||||
|
|
Loading…
Reference in a new issue