/* @class Context
 * Context is the "supertype" of Session and Batch.
 * It contains functions that are executed immediately
 * if called from a Session; or are executed when the Batch
 * is executed.
 * 
 * Users may find useful a "user" property of session and batch.
 * The mynode implementation will not ever define a property called "user".
 */

/** Find a specific instance based on primary or unique key value.
 *
 * The constructor parameter is the constructor function of a mapped domain 
 * object.
 * 
 * The parameter "keys" may be of any type. Keys must uniquely identify
 * a single row in the database. 
 * If keys is a simple type (number or string), then the parameter type must 
 * be the same type as or compatible with the primary key type of the mapped 
 * object.  
 * Otherwise, properties are taken from the parameter and matched against 
 * property names in the mapping. Primary key properties will be used if all 
 * are present, and other properties will be ignored. 
 * If keys cannot identify the primary key, property names corresponding to 
 * unique key columns will be used. If no complete primary or unique key 
 * properties are found, an error is reported.
 *
 * For multi-column primary or unique keys, all key fields must be set.
 *
 * The returned object will be loaded based on the mapping and the current
 * values in the database.
 *
 * @method find
 * @param constructor the constructor function of a mapped domain object
 * @param keys the instance to find in the database
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                    err: the node.js Error object
 *                    instance: the domain model object or null if not found
 * @return undefined
 * ASYNC
 */
find(Function constructor, Object keys, 
     Function(error, instance, ...) callback, ...);

/** Find a specific instance based on primary or unique key value.
 * See other variant for semantics.
 * 
 * @method find
 * @param tableName the table name
 * @param keys the instance to find in the database
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                    err: the node.js Error object
 *                    instance: the domain model object or null if not found
 * @return undefined
 * ASYNC
 */
find(String tableName, Object keys, Function(error, instance, ...) callback, ...);

/** Load a specific instance by matching its primary or unique key with 
 * a database row. Load will never create a new domain object.
 * 
 * The parameter "instance" must have its primary or unique key value(s) set.
 * The mapped values in the object will be loaded based on the current
 * values in the database. Unmapped properties in the object will be unchanged.
 * 
 * Primary key properties will be used if all are present,
 * and all other properties will be ignored.
 * Otherwise, property names corresponding to unique key columns
 * will be used. If no complete primary or unique key properties
 * are found, an error is reported.
 * 
 * @method load
 * @param instance the instance to load from the database
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                    err: the node.js Error object
 *                    instance: the domain model object or null if not found
 * @return undefined
 * ASYNC
 */
load(Object instance, Function(error, ...) callback, ...);

/** Insert the instance into the database.
 *
 * If the instance already exists in the database, an exception is 
 * reported in the callback.
 * 
 * For autogenerated values, the values will be present in the instance
 * when the callback is called.
 *
 * @param instance the instance to insert
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                    err: the node.js Error object
 * @return undefined
 * ASYNC
 */
persist(Object instance, Function(error, ...) callback, ...);
  
/** Insert the instance into the database. See the other variant for semantics.
 *
 * @param constructor the constructor function for a mapped domain object
 * @param values: values for the new instance
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
persist(Function constructor, Object values, Function(error, ...) callback, ...);
  
/** Insert the instance into the database. See the other variant for semantics.
 *
 * @param tableName the table name
 * @param values: values for the new instance
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
persist(String tableName, Object values, Function(error, ...) callback, ...);
  
/** Delete an instance of a class from the database by a primary or unique key.
 * The key values in the object must uniquely identify
 * a single row in the database. 
 * If the instance does not exist in the database,
 * an error is reported in the callback.
 *
 * @param the instance of a mapped domain object to delete from the database
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
remove(Object instance, Function(error, ...) callback, ...);

/** Delete a row from the database by a unique or primary key.
 * The constructor parameter is the constructor function for a mapped domain 
 * object. If keys is a simple type (number or string), then the parameter type
 * must be the same type as or compatible with the primary key type 
 * of the mapped object.
 * Otherwise, properties are taken from the parameter and matched against 
 * property names in the mapping. 
 * If all Primary Key properties are present, they will be used, 
 * and other properties will be ignored. 
 * Otherwise, if keys cannot identify the primary key, property names 
 * corresponding to unique key columns will be used. 
 * If no complete primary or unique key properties are found, an error
 * is reported.
 *
 * @param constructor the constructor for a mapped domain object
 * @param keys object containing the keys of the object to delete
 * @param callback function to be called when operation has completed, with parameters:
 *   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
remove(Function constructor, Object keys, Function(error, ...) callback, ...);

/** Delete a row from the database by a unique or primary key.
 * See other variant for semantics.
 *
 * @param tableName the table name
 * @param keys object containing the keys of the object to delete
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
remove(String tableName, Object keys, Function(error, ...) callback, ...);

/** Update the instance in the database without necessarily retrieving it.
 * The primary key field is used to determine which instance is to be updated.
 * If the instance does not exist in the database, an exception is reported
 * in the callback.
 * This method cannot be used to change the primary key.
 *
 * @param instance the instance to update
 * @param callback function to be called when operation has completed, 
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
update(Object instance, Function(error, ...) callback, ...);

/** Update the instance in the database without necessarily retrieving it.
 * Unique key field(s) of the keys object determine which instance
 * is to be updated. The values object provides values to be updated.
 * If the keys object contains all fields corresponding to the primary key,
 * the primary key will identify the instance. If not, unique keys will be
 * chosen non-deterministically.
 * If the instance does not exist in the database, an exception is reported
 * in the callback.
 * This method cannot be used to change the primary key.
 *
 * @param constructor constructor function of a mapped domain object
 * @param keys an object containing unique keys for the instance to update
 * @param values an object containing values to update
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
update(Function constructor, keys, values, Function(error, ...) callback, ...);

/** Update the instance in the database without necessarily retrieving it.
 * See other variant for semantics.
 *
 * @param tableName the table name
 * @param keys an object containing unique keys for the instance to update
 * @param values an object containing values to update
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
update(String tableName, keys, values, Function(error, ...) callback, ...);

/** Save the instance in the database without checking for existence.
 * The id field is used to determine which instance is to be saved.
 * If the instance exists in the database it will be updated.
 * If the instance does not exist, it will be created.
 *
 * @param instance the instance to insert or update
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
save(Object instance, Function(error, ...) callback, ...);

/** Save the instance in the database without checking for existence.
 * See other variant for semantics.
 *
 * @param constructor the constructor function of a mapped domain object
 * @param values the values to insert or update
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
save(Function constructor, Object values, Function(error, ...) callback, ...);

/** Save the instance in the database without checking for existence.
 * See other variant for semantics.
 *
 * @param tableName the name of the table
 * @param values the values to insert or update
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                   err: the node.js Error object
 * @return undefined
 * ASYNC
 */
save(String tableName, Object values, Function(error, ...) callback, ...);

/** Is "this" a batch?
 * @return true if this context is a batch; false if this context is a session
 * IMMEDIATE
 */
isBatch();
