TableMapper.qm.dox.h
// -*- mode: c++; indent-tabs-mode: nil -*-
/* TableMapper.qm Copyright 2014 - 2017 Qore Technologies, s.r.o.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
// this module requires Qore 0.8.13 or better
// require type definitions everywhere
// enable all warnings
// don't use "$" signs for variables and class members, assume local variable scope
// requires the Mapper module
// requires the SqlUtil module
namespace TableMapper {
class InboundTableMapper : public Mapper::Mapper {
public:
public :
const OptionKeys = Mapper::OptionKeys + (
"unstable_input": sprintf("if this is set to True then a slower insert/upsert method will be used that verifies each input row; if False an optimized insert/upsert method is used (additionally bulk inserts/upserts are possible) but all input hashes must have the same keys in the same order; default: %y", OptionDefaults.unstable_input),
"insert_block": sprintf("the row block size used when bulk DML / batch inserts/upserts are used; default: %y", OptionDefaults.insert_block),
"rowcode": "a closure or call reference taking a single hash argument representing the row values inserted/upserted plus any output values generated in inserts (such as sequence values, for example)",
"upsert": "if True then data will be upserted instead of inserted",
"upsert_strategy": "the upsert strategy code to use; implies 'upsert'",
);
const OptionDefaults = (
"unstable_input": False,
"insert_block": 1000,
);
public:
private :
SqlUtil::AbstractTable table;
SqlUtil::AbstractDatabase db;
bool has_returning;
list ret_args = ();
list out_args = ();
bool unstable_input = False;
Qore::SQL::SQLStatement stmt;
int insert_block;
hash hbuf;
*int hbuf_size; // size of the batch in hbuf (like if returned from
// getRecListSize())
// FIXME would be nice to have hbuf with hbuf_size
// in a class, but there are performance considerations.
// --PQ 23-Mar-2017
*code rowcode;
bool upsert = False;
*int upsert_strategy;
*code upsert_code;
public:
constructor(SqlUtil::Table target, hash mapv, *hash opts);
constructor(SqlUtil::AbstractTable target, hash mapv, *hash opts);
destructor();
static hash getOutputRecord(*string mname, AbstractTable table, *hash output);
private:
init(hash mapv, *hash opts);
public:
private:
mapFieldType(string key, hash m, reference<auto> v, hash rec);
public:
private:
checkMapField(string k, reference<auto> fh);
public:
hash validTypes();
hash validKeys();
hash optionKeys();
hash insertRow(hash rec);
setRowCode(*code rowc);
*hash queueData(hash rec, *hash crec);
*hash queueData(Qore::AbstractIterator iter, *hash crec);
*hash queueData(list l, *hash crec);
private:
*hash queueDataIntern(hash rec);
public:
private:
*int getRecListSize(hash rec);
public:
private:
hash record2Batch(hash h);
public:
private:
bool isMapperConstant();
public:
static nothing addBatchToBatch(reference<hash> hb, hash batch);
deprecated static nothing addBatchToBatch(reference<hash> hb, reference x1, hash batch, *reference x2);
*hash flush();
discard();
// return nothing if nothing needs to be flushed
private:
*hash flushIntern(bool force_flush);
public:
*list getReturning();
logOutput(hash h);
TableMapper::InboundTableMapperIterator iterator(Qore::AbstractIterator i);
deprecated hash insertRowNoCommit(hash rec);
nothing commit();
nothing rollback();
string getTableName();
SqlUtil::AbstractTable getTable();
Qore::SQL::AbstractDatasource getDatasource();
private:
error(string fmt);
public:
private:
error2(string ex, string fmt);
public:
};
class InboundIdentityTableMapper : public TableMapper::InboundTableMapper {
public:
constructor(SqlUtil::Table target, hash mapv = {}, *hash opts) ;
constructor(SqlUtil::AbstractTable target, hash mapv = {}, *hash opts) ;
private:
init(hash mapv, *hash opts);
public:
static hash getStaticInputRecord(SqlUtil::AbstractTable table, *hash input);
};
class InboundTableMapperIterator : public Mapper::AbstractMapperIterator {
public:
public :
public:
private :
TableMapper::InboundTableMapper mapc;
int commit_limit;
int cnt = 0;
hash val;
public:
constructor(Qore::AbstractIterator i, InboundTableMapper mapper) ;
constructor(Qore::AbstractIterator i, SqlUtil::Table target, hash mapv, *hash opts, int commit_limit = 0) ;
constructor(Qore::AbstractIterator i, SqlUtil::AbstractTable target, hash mapv, *hash opts, int commit_limit = 0) ;
constructor(Qore::AbstractIterator i, TableMapper::InboundTableMapper mapv, int commit_limit) ;
hash getValue();
bool next();
int commitLimit();
nothing commit();
nothing rollback();
string getTableName();
int getCount();
resetCount();
Qore::SQL::AbstractDatasource getDatasource();
setRuntime(string key, auto value);
setRuntime(hash runtime);
replaceRuntime(*hash runtime);
auto getRuntime(string key);
};
class SqlStatementMapperIterator : public Mapper::AbstractMapperIterator {
public:
public :
public:
private :
Mapper::Mapper m_mapper;
public:
constructor(TableMapper::AbstractSqlStatementOutboundMapper mapper)
;
constructor(SqlUtil::AbstractTable table, hash sh, hash mapv, *hash opts)
;
constructor(SqlUtil::Table table, hash sh, hash mapv, *hash opts)
;
constructor(Qore::SQL::SQLStatement stmt, hash mapv, *hash opts)
;
private:
setup(hash mapv, *hash opts);
public:
hash getValue();
int getCount();
resetCount();
bool hasBulk();
list mapBulk(int size);
setRuntime(string key, auto value);
setRuntime(hash runtime);
replaceRuntime(*hash runtime);
auto getRuntime(string key);
}; // class SqlStatementMapperIterator
class AbstractSqlStatementOutboundMapper : public Mapper::Mapper {
public:
public :
const OptionKeys = Mapper::OptionKeys + (
"table": "(required) the AbstractTable object for the source of the data",
"sh": "(optional) an SqlUtil select hash",
"select_block" : sprintf("the row block size used when bulk DML / batch inserts are used; default: %y", OptionDefaults.select_block),
);
const OptionDefaults = (
"select_block": 1000,
);
public:
private :
// internal SQLStatement
SQLStatement m_stmt;
// a select_block size. Taken from options
int select_block;
// original option hash
*hash m_orig_opts;
public:
constructor(hash mapv, *hash opts);
hash optionKeys();
commit();
rollback();
abstract Qore::SQL::AbstractDatasource getDatasource();
private:
abstract initOptions(reference<hash> opts);
public:
private:
abstract initStatement();
public:
Qore::SQL::SQLStatement getRowIterator();
SqlStatementMapperIterator iterator();
*hash getData();
*list getDataRows();
}; // AbstractSqlStatementOutboundMapper
class SqlStatementOutboundMapper : public AbstractSqlStatementOutboundMapper {
public:
private :
// the target table object
SqlUtil::AbstractTable m_table;
// SqlUtil select hash
*hash m_sh;
public:
constructor(SqlUtil::Table source, *hash sh, hash mapv, *hash opts)
;
constructor(SqlUtil::AbstractTable source, *hash sh, hash mapv, *hash opts)
;
string getTableName();
SqlUtil::AbstractTable getTable();
Qore::SQL::AbstractDatasource getDatasource();
static *hash getStaticInputRecord(AbstractTable table, *hash select_hash, *reference<string> sql, *hash input);
initStatement();
private:
initOptions(reference<hash> opts);
public:
}; // SqlStatementOutboundMapper
class RawSqlStatementOutboundMapper : public AbstractSqlStatementOutboundMapper {
public:
private :
AbstractDatasource m_ds;
string m_sql;
*list m_sqlargs;
public:
constructor(Qore::SQL::AbstractDatasource ds, string sql, *softlist sqlargs, hash mapv, *hash opts)
;
Qore::SQL::AbstractDatasource getDatasource();
static *hash getStaticInputRecord(Qore::SQL::AbstractDatasource ds, string sql, *softlist args, *hash input);
private:
initStatement();
public:
private:
initOptions(reference<hash> opts);
public:
}; // RawSqlStatementOutboundMapper
};
Mapper::Mapper::getRuntime
auto getRuntime(string key)
sprintf
string sprintf(string fmt,...)
Mapper::Mapper::getCount
int getCount()
TableMapper::InboundTableMapper::getTableName
string getTableName()
returns the table name
Mapper::Mapper::getOutputRecord
*hash getOutputRecord()
SqlUtil::AbstractTable
TableMapper::InboundTableMapper::queueData
*hash queueData(hash rec, *hash crec)
inserts/upserts a row (or a set of rows, in case a hash of lists is passed) into the block buffer bas...
TableMapper::InboundTableMapperIterator
provides a hash iterator based on a InboundTableMapper object and an iterator input source; for each ...
Definition: TableMapper.qm.dox.h:881
TableMapper::InboundTableMapper::stmt
Qore::SQL::SQLStatement stmt
statement for inserts/upserts
Definition: TableMapper.qm.dox.h:303
TableMapper::InboundTableMapperIterator::commit_limit
int commit_limit
row commit limit (<= 0 for no commits)
Definition: TableMapper.qm.dox.h:893
TableMapper::InboundTableMapper::getReturning
*list getReturning()
returns a list argument for the SqlUtil "returning" option, if applicable
TableMapper::SqlStatementMapperIterator::m_mapper
Mapper::Mapper m_mapper
data mapper
Definition: TableMapper.qm.dox.h:1121
TableMapper::InboundTableMapper::upsert_strategy
*int upsert_strategy
upsert strategy option
Definition: TableMapper.qm.dox.h:323
TableMapper::SqlStatementOutboundMapper
provides an outbound data mapper to a Table with SqlUtil select hash as a asource ...
Definition: TableMapper.qm.dox.h:1373
TableMapper::InboundTableMapper::destructor
destructor()
throws an exception if there is data pending in the block cache
TableMapper::InboundTableMapper::hbuf
hash hbuf
buffer for bulk DML
Definition: TableMapper.qm.dox.h:309
TableMapper::InboundTableMapper::validKeys
hash validKeys()
returns a list of valid field keys for this class (can be overridden in subclasses) ...
TableMapper::InboundTableMapper::optionKeys
hash optionKeys()
returns a list of valid constructor options for this class (can be overridden in subclasses) ...
TableMapper::InboundTableMapper::addBatchToBatch
static nothing addBatchToBatch(reference< hash > hb, hash batch)
TableMapper::RawSqlStatementOutboundMapper
provides an outbound data mapper to a raw SQL statement
Definition: TableMapper.qm.dox.h:1446
TableMapper::InboundTableMapper::rollback
nothing rollback()
discards any queued data and rolls back the transaction
TableMapper::InboundTableMapper::checkMapField
checkMapField(string k, reference< auto > fh)
perform per-field pre-processing on the passed map in the constructor
TableMapper::InboundTableMapper::validTypes
hash validTypes()
returns a list of valid field types for this class (can be overridden in subclasses) ...
TableMapper::InboundTableMapperIterator::val
hash val
a copy of the last hash value mapped
Definition: TableMapper.qm.dox.h:899
TableMapper::InboundTableMapper::flush
*hash flush()
flushes any remaining batched data to the database; this method should always be called before commit...
TableMapper::InboundTableMapper::OptionDefaults
const OptionDefaults
default option values
Definition: TableMapper.qm.dox.h:276
TableMapper::InboundTableMapper::flushIntern
*hash flushIntern(bool force_flush)
False
const False
Qore::SQL::AbstractDatasource
Mapper::Mapper
list
list list(...)
TableMapper::InboundTableMapper::has_returning
bool has_returning
if the AbstractTable object supports the "returning" clause
Definition: TableMapper.qm.dox.h:291
TableMapper::InboundTableMapper::getDatasource
Qore::SQL::AbstractDatasource getDatasource()
returns the AbstractDatasource object associated with this object
TableMapper::InboundTableMapper::OptionKeys
const OptionKeys
option keys for this object
Definition: TableMapper.qm.dox.h:267
Mapper::Mapper::resetCount
resetCount()
Qore::SQL::SQLStatement
TableMapper::InboundTableMapper::insertRowNoCommit
deprecated hash insertRowNoCommit(hash rec)
Plain alias to insertRow(). Obsolete. Do not use.
Mapper::Mapper::setup
setup(hash mapv, *hash opts)
TableMapper::InboundTableMapper::getTable
SqlUtil::AbstractTable getTable()
returns the underlying SqlUtil::AbstractTable object
Mapper::AbstractMapperIterator
TableMapper::InboundTableMapper::getRecListSize
*int getRecListSize(hash rec)
TableMapper::InboundTableMapper::queueDataIntern
*hash queueDataIntern(hash rec)
inserts a row into the block buffer based on a mapped input record; does not commit the transaction ...
TableMapper::InboundTableMapper::upsert
bool upsert
upsert flag
Definition: TableMapper.qm.dox.h:320
TableMapper::InboundTableMapper::init
init(hash mapv, *hash opts)
common constructor initialization
TableMapper::InboundTableMapper::upsert_code
*code upsert_code
closure used for upserting
Definition: TableMapper.qm.dox.h:326
TableMapper::InboundTableMapper::isMapperConstant
bool isMapperConstant()
TableMapper::InboundTableMapper::commit
nothing commit()
flushes any queued data and commits the transaction
TableMapper::InboundTableMapper::record2Batch
hash record2Batch(hash h)
TableMapper::InboundTableMapper::mapFieldType
mapFieldType(string key, hash m, reference< auto > v, hash rec)
performs type handling
TableMapper::InboundTableMapper::db
SqlUtil::AbstractDatabase db
the target Database object in case sequence value need to be acquired
Definition: TableMapper.qm.dox.h:288
TableMapper::InboundTableMapper::unstable_input
bool unstable_input
"unstable input" option for non-optimized inserts/upserts (~33% performance reduction in insert/upser...
Definition: TableMapper.qm.dox.h:300
TableMapper::InboundIdentityTableMapper
maps from source to target tables with exactly the same structure
Definition: TableMapper.qm.dox.h:819
Mapper::Mapper::output
*hash output
Mapper::Mapper::setRuntime
setRuntime(string key, auto value)
TableMapper::InboundTableMapper::error
error(string fmt)
prepends the datasource description to the error string and calls Mapper::error() ...
Mapper::Mapper::constructor
constructor()
TableMapper
the TableMapper namespace contains all the definitions in the TableMapper module
Definition: TableMapper.qm.dox.h:260
TableMapper::AbstractSqlStatementOutboundMapper
provides an abstract base for all SQL based outbound mappers
Definition: TableMapper.qm.dox.h:1259
TableMapper::InboundTableMapper::error2
error2(string ex, string fmt)
prepends the datasource description to the error description and calls Mapper::error2() ...
SqlUtil::Table
Mapper::Mapper::input
*hash input
TableMapper::InboundTableMapper::ret_args
list ret_args
"returning" arguments for sequences
Definition: TableMapper.qm.dox.h:294
TableMapper::SqlStatementMapperIterator
provides a hash iterator based on a mapper object and an SQLStatement or SqlUtil select hash ...
Definition: TableMapper.qm.dox.h:1112
TableMapper::InboundTableMapper
provides an inbound data mapper to a Table target
Definition: TableMapper.qm.dox.h:262
TableMapper::InboundTableMapper::discard
discard()
discards any buffered batched data; this method should be called after using the batch APIs (queueDat...
Mapper::Mapper::replaceRuntime
replaceRuntime(*hash runtime)
TableMapper::InboundTableMapper::insertRow
hash insertRow(hash rec)
inserts or upserts a row into the target table based on a mapped input record; does not commit the tr...
TableMapper::InboundTableMapperIterator::mapc
TableMapper::InboundTableMapper mapc
data mapper
Definition: TableMapper.qm.dox.h:890
hash
hash hash(object obj)
TableMapper::InboundTableMapper::out_args
list out_args
extra arguments for sequence output binds
Definition: TableMapper.qm.dox.h:297
TableMapper::InboundTableMapper::insert_block
int insert_block
bulk DML block size (also valid for upserts despite the name)
Definition: TableMapper.qm.dox.h:306
SqlUtil::AbstractDatabase
TableMapper::InboundTableMapper::table
SqlUtil::AbstractTable table
the target table object
Definition: TableMapper.qm.dox.h:285
TableMapper::InboundTableMapper::iterator
TableMapper::InboundTableMapperIterator iterator(Qore::AbstractIterator i)
returns an iterator for the current object
Qore::AbstractIterator
TableMapper::InboundTableMapper::logOutput
logOutput(hash h)
ignore logging from Mapper since we may have to log sequence values; output logged manually in insert...
TableMapper::InboundTableMapper::rowcode
*code rowcode
per-row Closures or Call References for batch inserts/upserts
Definition: TableMapper.qm.dox.h:317
TableMapper::InboundTableMapper::setRowCode
setRowCode(*code rowc)
sets a closure or call reference that will be called when data has been sent to the database and all ...