Skip to content

Commit

Permalink
Expose new db_type for dynamic type mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
zann1x committed Aug 13, 2023
1 parent ff7e29c commit 826fa77
Show file tree
Hide file tree
Showing 31 changed files with 910 additions and 458 deletions.
35 changes: 22 additions & 13 deletions include/soci/column-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ namespace soci
struct SOCI_DECL column_info
{
std::string name;
// DEPRECATED. USE dataType INSTEAD.
data_type type;
db_type dataType;
std::size_t length; // meaningful for text columns only
std::size_t precision;
std::size_t scale;
Expand All @@ -35,37 +37,36 @@ struct type_conversion<column_info>
static std::size_t get_numeric_value(const values & v,
const std::string & field_name)
{
data_type dt = v.get_properties(field_name).get_data_type();
db_type dt = v.get_properties(field_name).get_db_type();
switch (dt)
{
case dt_double:
case db_double:
return static_cast<std::size_t>(
v.get<double>(field_name, 0.0));
case dt_int8:
case db_int8:
return static_cast<std::size_t>(
v.get<int8_t>(field_name, 0));
case dt_uint8:
case db_uint8:
return static_cast<std::size_t>(
v.get<uint8_t>(field_name, 0));
case dt_int16:
case db_int16:
return static_cast<std::size_t>(
v.get<int16_t>(field_name, 0));
case dt_uint16:
case db_uint16:
return static_cast<std::size_t>(
v.get<uint16_t>(field_name, 0));
case dt_int32:
case db_int32:
return static_cast<std::size_t>(
v.get<int32_t>(field_name, 0));
case dt_uint32:
case db_uint32:
return static_cast<std::size_t>(
v.get<uint32_t>(field_name, 0));
case dt_int64:
case db_int64:
return static_cast<std::size_t>(
v.get<int64_t>(field_name, 0ll));
case dt_uint64:
case db_uint64:
return static_cast<std::size_t>(
v.get<uint64_t>(field_name, 0ull));
break;
default:
return 0u;
}
Expand All @@ -86,10 +87,12 @@ struct type_conversion<column_info>
type_name.find("CHAR") != std::string::npos)
{
ci.type = dt_string;
ci.dataType = db_string;
}
else if (type_name == "integer" || type_name == "INTEGER")
{
ci.type = dt_int32;
ci.type = dt_integer;
ci.dataType = db_int32;
}
else if (type_name.find("number") != std::string::npos ||
type_name.find("NUMBER") != std::string::npos ||
Expand All @@ -99,10 +102,12 @@ struct type_conversion<column_info>
if (ci.scale != 0)
{
ci.type = dt_double;
ci.dataType = db_double;
}
else
{
ci.type = dt_int32;
ci.type = dt_integer;
ci.dataType = db_int32;
}
}
else if (type_name.find("time") != std::string::npos ||
Expand All @@ -111,23 +116,27 @@ struct type_conversion<column_info>
type_name.find("DATE") != std::string::npos)
{
ci.type = dt_date;
ci.dataType = db_date;
}
else if (type_name.find("blob") != std::string::npos ||
type_name.find("BLOB") != std::string::npos ||
type_name.find("oid") != std::string::npos ||
type_name.find("OID") != std::string::npos)
{
ci.type = dt_blob;
ci.dataType = db_blob;
}
else if (type_name.find("xml") != std::string::npos ||
type_name.find("XML") != std::string::npos)
{
ci.type = dt_xml;
ci.dataType = db_xml;
}
else
{
// this seems to be a safe default
ci.type = dt_string;
ci.dataType = db_string;
}

const std::string & nullable_s = v.get<std::string>("IS_NULLABLE");
Expand Down
2 changes: 1 addition & 1 deletion include/soci/db2/soci-db2.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ struct SOCI_DB2_DECL db2_statement_backend : details::statement_backend
std::string rewrite_for_procedure_call(std::string const& query) override;

int prepare_for_describe() override;
void describe_column(int colNum, data_type& dtype, std::string& columnName) override;
void describe_column(int colNum, data_type& dtype, db_type& dbtype, std::string& columnName) override;
size_t column_size(int col);

db2_standard_into_type_backend* make_into_type_backend() override;
Expand Down
2 changes: 1 addition & 1 deletion include/soci/empty/soci-empty.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ struct SOCI_EMPTY_DECL empty_statement_backend : details::statement_backend
std::string rewrite_for_procedure_call(std::string const& query) override;

int prepare_for_describe() override;
void describe_column(int colNum, data_type& dtype, std::string& columnName) override;
void describe_column(int colNum, data_type& dtype, db_type& dbtype, std::string& columnName) override;

empty_standard_into_type_backend* make_into_type_backend() override;
empty_standard_use_type_backend* make_use_type_backend() override;
Expand Down
1 change: 1 addition & 0 deletions include/soci/firebird/soci-firebird.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ struct firebird_statement_backend : details::statement_backend

int prepare_for_describe() override;
void describe_column(int colNum, data_type &dtype,
db_type &dbtype,
std::string &columnName) override;

firebird_standard_into_type_backend * make_into_type_backend() override;
Expand Down
1 change: 1 addition & 0 deletions include/soci/mysql/soci-mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ struct mysql_statement_backend : details::statement_backend

int prepare_for_describe() override;
void describe_column(int colNum, data_type &dtype,
db_type &dbtype,
std::string &columnName) override;

mysql_standard_into_type_backend * make_into_type_backend() override;
Expand Down
1 change: 1 addition & 0 deletions include/soci/odbc/soci-odbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ struct odbc_statement_backend : details::statement_backend

int prepare_for_describe() override;
void describe_column(int colNum, data_type &dtype,
db_type &dbtype,
std::string &columnName) override;

// helper for defining into vector<string>
Expand Down
3 changes: 3 additions & 0 deletions include/soci/once-temp-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,11 @@ class SOCI_DECL ddl_type
int precision, int scale);
void drop_column(const std::string & tableName,
const std::string & columnName);
// DEPRECATED. USE column(std::string, db_type, int, int) INSTEAD.
ddl_type & column(const std::string & columnName, data_type dt,
int precision = 0, int scale = 0);
ddl_type & column(const std::string & columnName, db_type dt,
int precision = 0, int scale = 0);
ddl_type & unique(const std::string & name,
const std::string & columnNames);
ddl_type & primary_key(const std::string & name,
Expand Down
105 changes: 96 additions & 9 deletions include/soci/oracle/soci-oracle.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ struct oracle_statement_backend : details::statement_backend

int prepare_for_describe() override;
void describe_column(int colNum, data_type &dtype,
db_type &dbtype,
std::string &columnName) override;

// helper for defining into vector<string>
Expand Down Expand Up @@ -330,14 +331,86 @@ struct oracle_session_backend : details::session_backend
}

std::string create_column_type(data_type dt,
int precision, int scale) override
{
// Oracle-specific SQL syntax:

std::string res;
switch (dt)
{
case dt_string:
{
std::ostringstream oss;

if (precision == 0)
{
oss << "clob";
}
else
{
oss << "varchar(" << precision << ")";
}

res += oss.str();
}
break;

case dt_date:
res += "timestamp";
break;

case dt_double:
{
std::ostringstream oss;
if (precision == 0)
{
oss << "number";
}
else
{
oss << "number(" << precision << ", " << scale << ")";
}

res += oss.str();
}
break;

case dt_integer:
res += "integer";
break;

case dt_long_long:
res += "number";
break;

case dt_unsigned_long_long:
res += "number";
break;

case dt_blob:
res += "blob";
break;

case dt_xml:
res += "xmltype";
break;

default:
throw soci_error("this data_type is not supported in create_column");
}

return res;
}

std::string create_column_type(db_type dt,
int precision, int scale) override
{
// Oracle-specific SQL syntax:

std::string res;
switch (dt)
{
case dt_string:
case db_string:
{
std::ostringstream oss;

Expand All @@ -354,11 +427,11 @@ struct oracle_session_backend : details::session_backend
}
break;

case dt_date:
case db_date:
res += "timestamp";
break;

case dt_double:
case db_double:
{
std::ostringstream oss;
if (precision == 0)
Expand All @@ -374,27 +447,27 @@ struct oracle_session_backend : details::session_backend
}
break;

case dt_int16:
case db_int16:
res += "smallint";
break;

case dt_int32:
case db_int32:
res += "integer";
break;

case dt_int64:
case db_int64:
res += "number";
break;

case dt_uint64:
case db_uint64:
res += "number";
break;

case dt_blob:
case db_blob:
res += "blob";
break;

case dt_xml:
case db_xml:
res += "xmltype";
break;

Expand All @@ -407,13 +480,27 @@ struct oracle_session_backend : details::session_backend
std::string add_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " add " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string add_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " add " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string alter_column(const std::string & tableName,
const std::string & columnName, data_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " modify " +
columnName + " " + create_column_type(dt, precision, scale);
}
std::string alter_column(const std::string & tableName,
const std::string & columnName, db_type dt,
int precision, int scale) override
{
return "alter table " + tableName + " modify " +
columnName + " " + create_column_type(dt, precision, scale);
Expand Down
1 change: 1 addition & 0 deletions include/soci/postgresql/soci-postgresql.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ struct postgresql_statement_backend : details::statement_backend

int prepare_for_describe() override;
void describe_column(int colNum, data_type & dtype,
db_type & dbtype,
std::string & columnName) override;

postgresql_standard_into_type_backend * make_into_type_backend() override;
Expand Down
6 changes: 6 additions & 0 deletions include/soci/row.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@ class SOCI_DECL column_properties
public:

std::string get_name() const { return name_; }
// DEPRECATED. USE get_db_type() INSTEAD.
data_type get_data_type() const { return dataType_; }
db_type get_db_type() const { return dbType_; }

void set_name(std::string const& name) { name_ = name; }
// DEPRECATED. USE set_db_type(db_type) INSTEAD.
void set_data_type(data_type dataType) { dataType_ = dataType; }
void set_db_type(db_type dataType) { dbType_ = dataType; }

private:
std::string name_;
// DEPRECATED. USE exchangeDataType_ INSTEAD.
data_type dataType_;
db_type dbType_;
};

class SOCI_DECL row
Expand Down
Loading

0 comments on commit 826fa77

Please sign in to comment.