Qore TableMapper Module Reference  1.1
 All Classes Namespaces Functions Variables Groups Pages
TableMapper::InboundTableMapper Class Reference

provides an inbound data mapper to a Table target More...

Inheritance diagram for TableMapper::InboundTableMapper:

Public Member Functions

private checkMapField (string k, reference fh)
 perform per-field pre-processing on the passed map in the constructor More...
 
nothing commit ()
 flushes any queued data and commits the transaction
 
 constructor (SqlUtil::Table target, hash mapv, *hash opts)
 builds the object based on a hash providing field mappings, data constraints, and optionally custom mapping logic More...
 
 constructor (SqlUtil::AbstractTable target, hash mapv, *hash opts)
 builds the object based on a hash providing field mappings, data constraints, and optionally custom mapping logic More...
 
 destructor ()
 throws an exception if there is data pending in the block cache More...
 
 discard ()
 discards any buffered batched data; this method should be called after using the batch APIs (queueData()) and an error occurs More...
 
private error (string fmt)
 prepends the datasource description to the error string and calls Mapper::error()
 
private error2 (string ex, string fmt)
 prepends the datasource description to the error description and calls Mapper::error2()
 
*hash flush ()
 flushes any remaining batched data to the database; this method should always be called before committing the transaction or destroying the object More...
 
private hash flushIntern ()
 flushes queued data to the database
 
Qore::SQL::AbstractDatasource getDatasource ()
 returns the AbstractDatasource object associated with this object
 
*list getReturning ()
 returns a list argument for the SqlUtil "returning" option, if applicable
 
SqlUtil::AbstractTable getTable ()
 returns the underlying SqlUtil::AbstractTable object
 
string getTableName ()
 returns the table name
 
private init (hash mapv, *hash opts)
 common constructor initialization
 
hash insertRow (hash rec)
 inserts a row into the target table based on a mapped input record; does not commit the transaction More...
 
deprecated hash insertRowNoCommit (hash rec)
 Plain alias to insertRow(). Obsolete. Do not use.
 
 logOutput (hash h)
 ignore logging from Mapper since we may have to log sequence values; output logged manually in insertRow()
 
private mapFieldType (string key, hash m, reference v, hash rec)
 performs type handling
 
hash optionKeys ()
 returns a list of valid constructor options for this class (can be overridden in subclasses) More...
 
*hash queueData (hash rec, *hash crec)
 inserts a row (or a set of rows, in case a hash of lists is passed) into the block buffer based on a mapped input record; the block buffer is flushed to the DB if the buffer size reaches the limit defined by the "insert_block" option; does not commit the transaction More...
 
*hash queueData (AbstractIterator iter, *hash crec)
 inserts a set of rows (list of hashes) into the block buffer based on a mapped input record; the block buffer is flushed to the DB if the buffer size reaches the limit defined by the "insert_block" option; does not commit the transaction More...
 
private *hash queueDataIntern (hash rec)
 inserts a row into the block buffer based on a mapped input record; does not commit the transaction More...
 
nothing rollback ()
 discards any queued data and rolls back the transaction
 
 setRowCode (*code rowc)
 sets a closure or call reference that will be called when data has been sent to the database and all output data is available; must accept a hash argument that represents the data written to the database including any output arguments. This code will be reset, once the transaction is commited. More...
 
hash validKeys ()
 returns a list of valid field keys for this class (can be overridden in subclasses) More...
 
hash validTypes ()
 returns a list of valid field types for this class (can be overridden in subclasses) More...
 

Static Public Member Functions

static hash getOutputRecord (*string mname, AbstractTable table, *hash output)
 returns a description of the output record based on the AbstractTable target
 

Public Attributes

const OptionDefaults
 default option values
 
const OptionKeys
 option keys for this object
 

Private Attributes

SqlUtil::AbstractDatabase db
 the target Database object in case sequence value need to be acquired
 
bool has_returning
 if the AbstractTable object supports the "returning" clause
 
hash hbuf
 buffer for bulk inserts
 
int insert_block
 bulk insert block size
 
list out_args = ()
 extra arguments for sequence output binds
 
list ret_args = ()
 "returning" arguments for sequences
 
*code rowcode
 per-row Closures or Call References for batch inserts
 
SQLStatement stmt
 statement for inserts
 
SqlUtil::AbstractTable table
 the target table object
 
bool unstable_input = False
 "unstable input" option for non-optimized inserts (~33% performance reduction in insert speed)
 

Detailed Description

provides an inbound data mapper to a Table target

Member Function Documentation

private TableMapper::InboundTableMapper::checkMapField ( string  k,
reference  fh 
)

perform per-field pre-processing on the passed map in the constructor

Parameters
kthe field name
fha reference to the field's value in the map
TableMapper::InboundTableMapper::constructor ( SqlUtil::Table  target,
hash  mapv,
*hash  opts 
)

builds the object based on a hash providing field mappings, data constraints, and optionally custom mapping logic

The target table is also scanned using SqlUtil and column definitions are used to update the target record specification, also if there are any columns with NOT NULL constraints and no default value, mapping, or constant value, then a MAP-ERROR exception is thrown

Example:
1 const DbMapper = (
2  "id": ("sequence": "seq_inventory_example"),
3  "store_code": "StoreCode",
4  "product_code": "ProductCode",
5  "product_desc": "ProductDescription",
6  "ordered": "Ordered",
7  "available": "Available",
8  "in_transit": "InTransit",
9  "status": ("constant": "01"),
10  "total": int sub (any x, hash rec) { return rec.Available.toInt() + rec.Ordered.toInt() + rec.InTransit.toInt(); },
11  );
12 
13 InboundTableMapper mapper(table, DbMapper);
Parameters
targetthe target table object
mapva hash providing field mappings; each hash key is the name in lower case of the output column in the target table; each value is either True (meaning no translations are done; the data is copied 1:1) or a hash describing the mapping; see TableMapper Specification Format for detailed documentation for this option
optsan optional hash of options for the mapper; see Mapper Options for a description of valid mapper options plus the following options specific to this object:
  • "unstable_input": set this option to True (default False) if the input passed to the mapper is unstable, meaning that different hash keys or a different hash key order can be passed as input data in each call to insertRow(); if this option is set, then insert speed will be reduced by about 33%; when this option is not set, an optimized insert approach is used which allows for better performance
  • "insert_block": for DB drivers supporting bulk DML (for use with the queueData(), flush(), and discard() methods), the number of rows inserted at once (default: 1000, only used when "unstable_input" is False) and bulk inserts are supported in the table object; see InboundTableMapper Bulk Insert API for more information
  • "rowcode": a per-row Closures or Call References for batch inserts; this must take a single hash argument and will be called for every row after a bulk insert; the hash argument representing the row inserted will also contain any output values if applicable
Exceptions
MAP-ERRORthe map hash has a logical error (ex: "trunc" key given without "maxlen", invalid map key)
See Also
setRowCode()
TableMapper::InboundTableMapper::constructor ( SqlUtil::AbstractTable  target,
hash  mapv,
*hash  opts 
)

builds the object based on a hash providing field mappings, data constraints, and optionally custom mapping logic

The target table is also scanned using SqlUtil and column definitions are used to update the target record specification, also if there are any columns with NOT NULL constraints and no default value, mapping, or constant value, then a MAP-ERROR exception is thrown

Example:
1 const DbMapper = (
2  "id": ("sequence": "seq_inventory_example"),
3  "store_code": "StoreCode",
4  "product_code": "ProductCode",
5  "product_desc": "ProductDescription",
6  "ordered": "Ordered",
7  "available": "Available",
8  "in_transit": "InTransit",
9  "status": ("constant": "01"),
10  "total": int sub (any x, hash rec) { return rec.Available.toInt() + rec.Ordered.toInt() + rec.InTransit.toInt(); },
11  );
12 
13 InboundTableMapper mapper(table, DbMapper);
Parameters
targetthe target table object
mapva hash providing field mappings; each hash key is the name of the output field; each value is either True (meaning no translations are done; the data is copied 1:1) or a hash describing the mapping; see TableMapper Specification Format for detailed documentation for this option
optsan optional hash of options for the mapper; see Mapper Options for a description of valid mapper options plus the following options specific to this object:
  • "unstable_input": set this option to True (default False) if the input passed to the mapper is unstable, meaning that different hash keys or a different hash key order can be passed as input data in each call to insertRow(); if this option is set, then insert speed will be reduced by about 33%; when this option is not set, an optimized insert approach is used which allows for better performance
  • "insert_block": for DB drivers supporting bulk DML (for use with the queueData(), flush(), and discard() methods), the number of rows inserted at once (default: 1000, only used when "unstable_input" is False) and bulk inserts are supported in the table object; see InboundTableMapper Bulk Insert API for more information
  • "rowcode": a per-row Closures or Call References for batch inserts; this must take a single hash argument and will be called for every row after a bulk insert; the hash argument representing the row inserted will also contain any output values if applicable
Exceptions
MAP-ERRORthe map hash has a logical error (ex: "trunc" key given without "maxlen", invalid map key)
TABLE-ERRORthe table includes a column using an unknown native data type
See Also
setRowCode()
TableMapper::InboundTableMapper::destructor ( )

throws an exception if there is data pending in the block cache

Exceptions
BLOCK-ERRORthere is unflushed data in the block cache; make sure to call flush() or discard() before destroying the object
TableMapper::InboundTableMapper::discard ( )

discards any buffered batched data; this method should be called after using the batch APIs (queueData()) and an error occurs

Example:
1 on_success table_mapper.commit();
2 on_error table_mapper.rollback();
3 {
4  on_success table_mapper.flush();
5  on_error table_mapper.discard();
6 
7  map table_mapper.queueData($1), data.iterator();
8 }
Note
  • flush() or discard() needs to be executed for each mapper used in the block when using multiple mappers whereas the DB transaction needs to be committed or rolled back once per datasource
  • also clears any row Closures or Call References set for batch operations
  • if an error occurs flushing data, the count is reset by calling Mapper::resetCount()
See Also
*hash TableMapper::InboundTableMapper::flush ( )

flushes any remaining batched data to the database; this method should always be called before committing the transaction or destroying the object

Example:
1 on_success table_mapper.commit();
2 on_error table_mapper.rollback();
3 {
4  on_success table_mapper.flush();
5  on_error table_mapper.discard();
6 
7  map table_mapper.queueData($1), data.iterator();
8 }
Returns
if batch data was inserted then a hash (columns) of lists (row data) of all data inserted and potentially returned (in case of sequences) from the database server is returned
Note
  • flush() or discard() needs to be executed for each mapper used in the block when using multiple mappers whereas the DB transaction needs to be committed or rolled back once per datasource
  • also clears any row Closures or Call References set for batch operations
  • if an error occurs flushing data, the count is reset by calling Mapper::resetCount()
See Also
hash TableMapper::InboundTableMapper::insertRow ( hash  rec)

inserts a row into the target table based on a mapped input record; does not commit the transaction

Parameters
recthe input record
Returns
a hash of the row values inserted (row name: value)
Exceptions
MISSING-INPUTa field marked mandatory is missing
STRING-TOO-LONGa field value exceeds the maximum value and the 'trunc' key is not set
INVALID-NUMBERthe field is marked as numeric but the input value contains non-numeric data
hash TableMapper::InboundTableMapper::optionKeys ( )

returns a list of valid constructor options for this class (can be overridden in subclasses)

Returns
a list of valid constructor options for this class (can be overridden in subclasses)
*hash TableMapper::InboundTableMapper::queueData ( hash  rec,
*hash  crec 
)

inserts a row (or a set of rows, in case a hash of lists is passed) into the block buffer based on a mapped input record; the block buffer is flushed to the DB if the buffer size reaches the limit defined by the "insert_block" option; does not commit the transaction

Example:
1 on_success table_mapper.commit();
2 on_error table_mapper.rollback();
3 {
4  on_success table_mapper.flush();
5  on_error table_mapper.discard();
6 
7  map table_mapper.queueData($1), data.iterator();
8 }

Data is only inserted if the block buffer size reaches the limit defined by the "insert_block" option, in which case this method returns all the data inserted. In case the mapped data is only inserted into the cache, no value is returned.

Parameters
recthe input record or record set in case a hash of lists is passed
crecan optional simple hash of data to be added to each row
Returns
if batch data was inserted then a hash (columns) of lists (row data) of all data inserted and potentially returned (in case of sequences) from the database server is returned
Note
  • make sure to call flush() before committing the transaction or discard() before rolling back the transaction or destroying the object when using this method
  • flush() or discard() needs to be executed for each mapper used in the block when using multiple mappers whereas the DB transaction needs to be committed or rolled back once per datasource
  • this method and batched inserts in general cannot be used when the "unstable_input" option is given in the constructor
  • if the "insert_block" option is set to 1, then this method simply calls insertRow()
  • if an error occurs flushing data, the count is reset by calling Mapper::resetCount()
See Also
Exceptions
MAPPER-BATCH-ERRORthis exception is thrown if this method is called when the "unstable_input" option was given in the constructor
MISSING-INPUTa field marked mandatory is missing
STRING-TOO-LONGa field value exceeds the maximum value and the 'trunc' key is not set
INVALID-NUMBERthe field is marked as numeric but the input value contains non-numeric data
*hash TableMapper::InboundTableMapper::queueData ( AbstractIterator  iter,
*hash  crec 
)

inserts a set of rows (list of hashes) into the block buffer based on a mapped input record; the block buffer is flushed to the DB if the buffer size reaches the limit defined by the "insert_block" option; does not commit the transaction

Example:
1 on_success table_mapper.commit();
2 on_error table_mapper.rollback();
3 {
4  on_success table_mapper.flush();
5  on_error table_mapper.discard();
6 
7  table_mapper.queueData(data.iterator());
8 }

Data is only inserted if the block buffer size reaches the limit defined by the "insert_block" option, in which case this method returns all the data inserted. In case the mapped data is only inserted into the cache, no value is returned.

Parameters
iteriterator over the record set (list of hashes)
crecan optional simple hash of data to be added to each row
Returns
if batch data was inserted then a hash (columns) of lists (row data) of all data inserted and potentially returned (in case of sequences) from the database server is returned
Note
  • make sure to call flush() before committing the transaction or discard() before rolling back the transaction or destroying the object when using this method
  • flush() or discard() needs to be executed for each mapper used in the block when using multiple mappers whereas the DB transaction needs to be committed or rolled back once per datasource
  • this method and batched inserts in general cannot be used when the "unstable_input" option is given in the constructor
  • if the "insert_block" option is set to 1, then this method simply calls insertRow()
  • if an error occurs flushing data, the count is reset by calling Mapper::resetCount()
See Also
Exceptions
MAPPER-BATCH-ERRORthis exception is thrown if this method is called when the "unstable_input" option was given in the constructor
MISSING-INPUTa field marked mandatory is missing
STRING-TOO-LONGa field value exceeds the maximum value and the 'trunc' key is not set
INVALID-NUMBERthe field is marked as numeric but the input value contains non-numeric data
private *hash TableMapper::InboundTableMapper::queueDataIntern ( hash  rec)

inserts a row into the block buffer based on a mapped input record; does not commit the transaction

Data is only inserted if the block buffer size reaches the limit defined by the "insert_block" option, in which case this method returns all the data inserted. In case the mapped data is only inserted into the cache, no value is returned.

Parameters
reca hash representing a single input record
Returns
if batch data was inserted then a hash (columns) of lists (row data) of all data inserted and potentially returned (in case of sequences) from the database server is returned
Exceptions
MAPPER-BATCH-ERRORthis exception is thrown if this method is called when the "unstable_input" option was given in the constructor
MISSING-INPUTa field marked mandatory is missing
STRING-TOO-LONGa field value exceeds the maximum value and the 'trunc' key is not set
INVALID-NUMBERthe field is marked as numeric but the input value contains non-numeric data
TableMapper::InboundTableMapper::setRowCode ( *code  rowc)

sets a closure or call reference that will be called when data has been sent to the database and all output data is available; must accept a hash argument that represents the data written to the database including any output arguments. This code will be reset, once the transaction is commited.

Example:
1 code rowcode = sub (hash row) {
2  # process row data
3 };
4 table_mapper.setRowCode(rowcode);
Parameters
rowca closure or call reference that will be called when data has been sent to the database and all output data is available; must accept a hash argument that represents the data written to the database including any output arguments
Note
the per-row closure or call reference can also be set by using the "rowcode" option in the constructor()
hash TableMapper::InboundTableMapper::validKeys ( )

returns a list of valid field keys for this class (can be overridden in subclasses)

Returns
a list of valid field keys for this class (can be overridden in subclasses)
hash TableMapper::InboundTableMapper::validTypes ( )

returns a list of valid field types for this class (can be overridden in subclasses)

Returns
a list of valid types for this class (can be overridden in subclasses)