Template base class for doing a join. More...

#include "rdm_db_query.h"

Inheritance diagram for RDM::DB::QUERY::join_rows< table_id, NEXT >:
Inheritance graph

Public Member Functions

uint8_t * serialize (uint8_t *buffer)
uint8_t * unserialize (uint8_t *buffer)
join_rows ()
~join_rows ()
uint32_t init_tables_to_write_lock (RDM_TABLE_ID *tables)
IDs of the tables where rows are inserted. More...
uint32_t init_tables_to_read_lock (RDM_TABLE_ID *tables)
IDs of the tables where rows are read. More...
RDM_RETCODE init (RDM_DB p_db)
Initialize this object. More...
void reset (void)
Reset this object. More...
RDM_RETCODE fetch_first ()
Fetch the first. More...
RDM_RETCODE fetch_prev ()
Fetch the previous. More...
RDM_RETCODE fetch_next ()
Fetch the next. More...
RDM_RETCODE fetch_last ()
Fetch the last. More...
template<class TARGET_ROW_T >
RDM_RETCODE bind_row (TARGET_ROW_T *target_row, bool *target_all_columns_null=NULL)
Bind a row. More...

Static Public Member Functions

constexpr static int get_serialize_size (void)
Get the size of a buffer for serialization to hold its state. More...
constexpr static int number_of_tables_to_write_lock (void)
Number of tables where rows are inserted. More...
constexpr static int number_of_tables_to_read_lock (void)
Number of tables where rows are read. More...

Data Fields

NEXT next

Protected Member Functions

virtual RDM_RETCODE setup_cursor_for_join (RDM_CURSOR cursor)=0
Set up the cursor for the join. More...
virtual RDM_RETCODE fetch (direction dir, bool first_or_last)=0
Fetch a row. More...

Protected Attributes

RDM_DB db
RDM_CURSOR cursor
void * target_row
uint32_t target_size
bool * target_all_columns_null
bool outer_join
bool keyed_join
position pos

Detailed Description

template<RDM_TABLE_ID table_id, class NEXT>
class RDM::DB::QUERY::join_rows< table_id, NEXT >

Template base class for doing a join.

Don't use this template class directly. Instead, use one of the derived classes.

Template Parameters
table_id The ID of the table
NEXT The class in the chain to fetch data from

Constructor & Destructor Documentation

join_rows()

template<RDM_TABLE_ID table_id, class NEXT >
RDM::DB::QUERY::join_rows< table_id, NEXT >::join_rows ( )
inline
205 : cursor (NULL), target_row (NULL), target_all_columns_null (NULL), pos (POS_NOT_SET)
206 {
207 }

~join_rows()

template<RDM_TABLE_ID table_id, class NEXT >
RDM::DB::QUERY::join_rows< table_id, NEXT >::~join_rows ( )
inline
210 {
211if (cursor)
212 {
214 }
215 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::cursor, and rdm_cursorFree().

Here is the call graph for this function:

Member Function Documentation

bind_row()

template<RDM_TABLE_ID table_id, class NEXT >
template<class TARGET_ROW_T >
RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::bind_row ( TARGET_ROW_T * target_row,
bool * target_all_columns_null = NULL
)
inline

Bind a row.

Bind an application target row. For each row or set of rows that are fetched, one actual row in that set will be populated into the buffers specified here unless all columns are 'null' in the case of no matching rows.

Two buffers can be provided. One buffer for the actual row data and another buffer with a boolean that is set to the boolean value 'true', if all columns are 'null' due to an outer join, where there were no matching rows.

Be aware that when there are no matching rows, the target row will not be updated at all. Therefore, an application should always provide a buffer with a boolean for the second parameter in the case of an outer join.

To get the result of all rows in the set of rows that are calculated by a give chain of classes, the bind_row methode for each class in that chain should be called. Each of these buffers will only be populated when the corresponding class does a fetch. Therefore, care should be taken to not overwrite any of these buffers with other data between each fetch.

Template Parameters
TARGET_ROW_T The type for the application target row struct definition
Parameters
[in] target_row The target the rows are fetched into
[in] target_all_columns_null Whether all the columns are NULL due to the extra row needed for outer joins
458 {
460target_size = sizeof (TARGET_ROW_T);
462
463return sOKAY;
464 }

References sOKAY, RDM::DB::QUERY::join_rows< table_id, NEXT >::target_all_columns_null, RDM::DB::QUERY::join_rows< table_id, NEXT >::target_row, and RDM::DB::QUERY::join_rows< table_id, NEXT >::target_size.

fetch()

template<RDM_TABLE_ID table_id, class NEXT >
virtual RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch ( direction dir,
bool first_or_last
)
protectedpure virtual

Fetch a row.

Fetch a row or combination of rows for what the actual class is computing. This navigation may be done based on a previously set position, and a new position will be establshed for a successful return.

This method must be implemented in the derived classes.

Return values
sOKAY Normal, successful return.
sENDOFCURSOR Reached the end of the cursor collection.
eINVITERATION Invalid attempt to move cursor before 'BeforeFirst' or past 'AfterLast'.
eNOSTARTREAD A read operation was attempted when no rdm_dbStartSnapshot(), rdm_dbStartRead(), or rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eDBNOTOPEN Database not open.
eCATMISMATCH Catalog in memory does not match Catalog on disk.
eNOCURRENTROW The cursor is not positioned to a valid row.
eOWNERDELETED The owner row for a set cursor has been deleted.
eSINGLETONDELETED The row for a singleton cursor has been deleted.
Parameters
[in] dir The direction we are fetching
[in] first_or_last Wheter we are fetching one of the extremes such as the first or the last as opposed to the next or the previous

Referenced by RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_first(), RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_last(), RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_next(), and RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_prev().

Here is the caller graph for this function:

fetch_first()

template<RDM_TABLE_ID table_id, class NEXT >
RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_first ( )
inline

Fetch the first.

Fetch the first row or combination of rows for what the actual class is computing. This navigation is done independent of any previously set position. A new position will be establshed for a successful return.

Return values
sOKAY Normal, successful return.
sENDOFCURSOR Reached the end of the cursor collection.
eINVITERATION Invalid attempt to move cursor before 'BeforeFirst' or past 'AfterLast'.
eNOSTARTREAD A read operation was attempted when no rdm_dbStartSnapshot(), rdm_dbStartRead(), or rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eDBNOTOPEN Database not open.
eCATMISMATCH Catalog in memory does not match Catalog on disk.
eNOCURRENTROW The cursor is not positioned to a valid row.
eOWNERDELETED The owner row for a set cursor has been deleted.
eSINGLETONDELETED The row for a singleton cursor has been deleted.
329 {
331if (rc == sNULLVAL)
332 {
333 rc = sOKAY;
334 }
335
336return rc;
337 }

References RDM::DB::direction_forward, RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch(), sNULLVAL, and sOKAY.

Here is the call graph for this function:

fetch_last()

template<RDM_TABLE_ID table_id, class NEXT >
RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_last ( )
inline

Fetch the last.

Fetch the last row or combination of rows for what the actual class is computing. This navigation is done independent of any previously set position. A new position will be establshed for a successful return.

Return values
sOKAY Normal, successful return.
sENDOFCURSOR Reached the end of the cursor collection.
eINVITERATION Invalid attempt to move cursor before 'BeforeFirst' or past 'AfterLast'.
eNOSTARTREAD A read operation was attempted when no rdm_dbStartSnapshot(), rdm_dbStartRead(), or rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eDBNOTOPEN Database not open.
eCATMISMATCH Catalog in memory does not match Catalog on disk.
eNOCURRENTROW The cursor is not positioned to a valid row.
eOWNERDELETED The owner row for a set cursor has been deleted.
eSINGLETONDELETED The row for a singleton cursor has been deleted.
416 {
418if (rc == sNULLVAL)
419 {
420 rc = sOKAY;
421 }
422
423return rc;
424 }

References RDM::DB::direction_backward, RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch(), sNULLVAL, and sOKAY.

Here is the call graph for this function:

fetch_next()

template<RDM_TABLE_ID table_id, class NEXT >
RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_next ( )
inline

Fetch the next.

Fetch the next row or combination of rows for what the actual class is computing. This navigation is done based on a previously set position, and a new position will be establshed for a successful return.

Return values
sOKAY Normal, successful return.
sENDOFCURSOR Reached the end of the cursor collection.
eINVITERATION Invalid attempt to move cursor before 'BeforeFirst' or past 'AfterLast'.
eNOSTARTREAD A read operation was attempted when no rdm_dbStartSnapshot(), rdm_dbStartRead(), or rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eDBNOTOPEN Database not open.
eCATMISMATCH Catalog in memory does not match Catalog on disk.
eNOCURRENTROW The cursor is not positioned to a valid row.
eOWNERDELETED The owner row for a set cursor has been deleted.
eSINGLETONDELETED The row for a singleton cursor has been deleted.
387 {
389if (rc == sNULLVAL)
390 {
391 rc = sOKAY;
392 }
393
394return rc;
395 }

References RDM::DB::direction_forward, RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch(), sNULLVAL, and sOKAY.

Here is the call graph for this function:

fetch_prev()

template<RDM_TABLE_ID table_id, class NEXT >
RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch_prev ( )
inline

Fetch the previous.

Fetch the previous row or combination of rows for what the actual class is computing. This navigation is done based on a previously set position, and a new position will be establshed for a successful return.

Return values
sOKAY Normal, successful return.
sENDOFCURSOR Reached the end of the cursor collection.
eINVITERATION Invalid attempt to move cursor before 'BeforeFirst' or past 'AfterLast'.
eNOSTARTREAD A read operation was attempted when no rdm_dbStartSnapshot(), rdm_dbStartRead(), or rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eDBNOTOPEN Database not open.
eCATMISMATCH Catalog in memory does not match Catalog on disk.
eNOCURRENTROW The cursor is not positioned to a valid row.
eOWNERDELETED The owner row for a set cursor has been deleted.
eSINGLETONDELETED The row for a singleton cursor has been deleted.
358 {
360if (rc == sNULLVAL)
361 {
362 rc = sOKAY;
363 }
364
365return rc;
366 }

References RDM::DB::direction_backward, RDM::DB::QUERY::join_rows< table_id, NEXT >::fetch(), sNULLVAL, and sOKAY.

Here is the call graph for this function:

get_serialize_size()

template<RDM_TABLE_ID table_id, class NEXT >
constexpr static int RDM::DB::QUERY::join_rows< table_id, NEXT >::get_serialize_size ( void )
inlinestaticconstexpr

Get the size of a buffer for serialization to hold its state.

Get the size needed for a buffer to hold the state of this object.

115 {
116return sizeof(pos) + NEXT::get_serialize_size ();
117 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::pos.

init()

template<RDM_TABLE_ID table_id, class NEXT >
RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::init ( RDM_DB p_db )
inline

Initialize this object.

Call this method before querying for any data.

Return values
sOKAY Normal, successful return.
eINVARG Invalid argument.
eDBNOTOPEN Database not open.
eCURSORDB Cursor is associated with a different database.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
Parameters
p_db [IN] Use this database for chained classes that need to insert rows
287 {
288RDM_RETCODE rc = next.init (p_db);
289if (rc == sOKAY)
290 {
291join_rows::db = p_db;
292 }
293return rc;
294 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::db, RDM::DB::QUERY::join_rows< table_id, NEXT >::next, and sOKAY.

init_tables_to_read_lock()

template<RDM_TABLE_ID table_id, class NEXT >
uint32_t RDM::DB::QUERY::join_rows< table_id, NEXT >::init_tables_to_read_lock ( RDM_TABLE_ID * tables )
inline

IDs of the tables where rows are read.

Use this method to initialize an array of table IDs. This array can then be used to start a transaction where those tables are specified for locking.

263 {
264 uint32_t num_tables{next.init_tables_to_read_lock (tables)};
265
266if (this->keyed_join)
267 {
268 *(tables + num_tables) = table_id;
269 ++num_tables;
270 }
271
272return num_tables;
273 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::next.

init_tables_to_write_lock()

template<RDM_TABLE_ID table_id, class NEXT >
uint32_t RDM::DB::QUERY::join_rows< table_id, NEXT >::init_tables_to_write_lock ( RDM_TABLE_ID * tables )
inline

IDs of the tables where rows are inserted.

Use this method to initialize an array of table IDs. This array can then be used to start a transaction where those tables are specified.

234 {
235 uint32_t num_tables{next.init_tables_to_write_lock (tables)};
236
237if (this->keyed_join)
238 {
239 *(tables + num_tables) = table_id;
240 ++num_tables;
241 }
242
243return num_tables;
244 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::next.

number_of_tables_to_read_lock()

template<RDM_TABLE_ID table_id, class NEXT >
constexpr static int RDM::DB::QUERY::join_rows< table_id, NEXT >::number_of_tables_to_read_lock ( void )
inlinestaticconstexpr

Number of tables where rows are read.

Constant expression method used to statically calculate the size of the array needed for table locking.

252 {
253return NEXT::number_of_tables_to_read_lock ();
254 }

number_of_tables_to_write_lock()

template<RDM_TABLE_ID table_id, class NEXT >
constexpr static int RDM::DB::QUERY::join_rows< table_id, NEXT >::number_of_tables_to_write_lock ( void )
inlinestaticconstexpr

Number of tables where rows are inserted.

Constant expression method used to statically calculate the size of the array needed for table locking.

223 {
224return NEXT::number_of_tables_to_write_lock ();
225 }

reset()

template<RDM_TABLE_ID table_id, class NEXT >
void RDM::DB::QUERY::join_rows< table_id, NEXT >::reset ( void )
inline

Reset this object.

Call this method to discard internally kept state and get ready to query data again.

Any alternative implementation of this method in a sub class would call this method to reset the next class.

305 {
306RDM_RETCODE rc = next.reset (db);
308 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::db, RDM::DB::QUERY::join_rows< table_id, NEXT >::next, RDM::DB::QUERY::join_rows< table_id, NEXT >::pos, and RDM::DB::QUERY::POS_NOT_SET.

serialize()

template<RDM_TABLE_ID table_id, class NEXT >
uint8_t* RDM::DB::QUERY::join_rows< table_id, NEXT >::serialize ( uint8_t * buffer )
inline
126 {
127 memcpy (buffer, &pos, sizeof (pos));
128return next.serialize (buffer + sizeof (pos));
129 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::next, and RDM::DB::QUERY::join_rows< table_id, NEXT >::pos.

setup_cursor_for_join()

template<RDM_TABLE_ID table_id, class NEXT >
virtual RDM_RETCODE RDM::DB::QUERY::join_rows< table_id, NEXT >::setup_cursor_for_join ( RDM_CURSOR cursor )
protectedpure virtual

Set up the cursor for the join.

This methode is called each time we have a row fetched from the next class in the chain of classes. It must be implemented in the derived classes. For each of these calls, join_rows::cursor is associated with the rows in the join result for this class.

For cases that can return more than one row, the cursor has to be positioned at the before first position. For cases that can only return zero or one row, the cursor has to be positioned at the row and return an error code of sENDOFCURSOR if there are no rows.

Return values
sOKAY Normal, successful return.
sENDOFCURSOR Reached the end of the cursor collection.
eNOSTARTREAD A read operation was attempted when no rdm_dbStartSnapshot(), rdm_dbStartRead(), or rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eCURSORDB Cursor is associated with a different database.
eDBNOTOPEN Database not open.
eINVKEYID Invalid key id.
eISRTREE The key specified is an rtree index.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
Parameters
cursor [IN] A cursor with the row we fetched from the next class

unserialize()

template<RDM_TABLE_ID table_id, class NEXT >
uint8_t* RDM::DB::QUERY::join_rows< table_id, NEXT >::unserialize ( uint8_t * buffer )
inline
138 {
139 memcpy (&pos, buffer, sizeof (pos));
140return next.unserialize (buffer + sizeof (pos));
141 }

References RDM::DB::QUERY::join_rows< table_id, NEXT >::next, and RDM::DB::QUERY::join_rows< table_id, NEXT >::pos.

Field Documentation

cursor

template<RDM_TABLE_ID table_id, class NEXT >
RDM_CURSOR RDM::DB::QUERY::join_rows< table_id, NEXT >::cursor
protected

The cursor we use for navigating and reading rows

Referenced by RDM::DB::QUERY::join_rows< table_id, NEXT >::~join_rows().

db

template<RDM_TABLE_ID table_id, class NEXT >
RDM_DB RDM::DB::QUERY::join_rows< table_id, NEXT >::db
protected

keyed_join

template<RDM_TABLE_ID table_id, class NEXT >
bool RDM::DB::QUERY::join_rows< table_id, NEXT >::keyed_join
protected

next

outer_join

pos

target_all_columns_null

template<RDM_TABLE_ID table_id, class NEXT >
bool* RDM::DB::QUERY::join_rows< table_id, NEXT >::target_all_columns_null
protected

The target "all columns null" for each fetch we do

Referenced by RDM::DB::QUERY::join_rows< table_id, NEXT >::bind_row().

target_row

template<RDM_TABLE_ID table_id, class NEXT >
void* RDM::DB::QUERY::join_rows< table_id, NEXT >::target_row
protected

The target row for each fetch we do

Referenced by RDM::DB::QUERY::join_rows< table_id, NEXT >::bind_row().

target_size

template<RDM_TABLE_ID table_id, class NEXT >
uint32_t RDM::DB::QUERY::join_rows< table_id, NEXT >::target_size
protected

The size of the target row

Referenced by RDM::DB::QUERY::join_rows< table_id, NEXT >::bind_row().


The documentation for this class was generated from the following file:
NEXT next
Definition: rdm_db_query.h:109
bool keyed_join
Definition: rdm_db_query.h:150
uint32_t target_size
Definition: rdm_db_query.h:147
@ sOKAY
Definition: rdmretcodetypes.h:100
@ sNULLVAL
Definition: rdmretcodetypes.h:73
void * target_row
Definition: rdm_db_query.h:146
RDM_RETCODE rdm_cursorFree(RDM_CURSOR cursor)
Free an RDM_CURSOR.
RDM_CURSOR cursor
Definition: rdm_db_query.h:145
enum RDM_RETCODE_E RDM_RETCODE
RaimaDB status and error return codes.
@ direction_forward
Definition: rdm_db.h:46
@ direction_backward
Definition: rdm_db.h:47
RDM_DB db
Definition: rdm_db_query.h:144
bool * target_all_columns_null
Definition: rdm_db_query.h:148
@ POS_NOT_SET
Definition: rdm_db_query.h:89
position pos
Definition: rdm_db_query.h:151
virtual RDM_RETCODE fetch(direction dir, bool first_or_last)=0
Fetch a row.