/* @Class Session
 * 
 */
 
/** Find a specific instance based on primary or unique key value.
 * ASYNC
 *
 * 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.
 * If the first parameter is a Projection, the find operation will return
 * the object corresponding to the key. Additionally, the properties 
 * defined in the projection as relationship properties will be fetched,
 * recursively.
 *
 * For multi-column primary or unique keys, all key fields must be set.
 *
 * The returned object will be loaded based on the mapping, the Projection,
 * and the current values in the database.
 *
 * This function returns a promise.  On success, the promise will be fulfilled 
 * with the found object.  The optional callback receives an error value and the 
 * found object.  Any extra arguments passed after the callback will
 * be passed to the callback function verbatim as parameters following 
 * the found instance value.
 *
 * @method find
 * @param constructorOrProjection the constructor function of a mapped domain object
 * or a Projection 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 promise
 */
find(Function constructorOrProjection, Object keys, [callback], [...]);

/** Find a specific instance based on primary or unique key value.
 * See other variant for semantics.
 * ASYNC
 * 
 * @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 promise
 */
find(String tableName, Object keys, [callback], [...]);

/** Load a specific instance by matching its primary or unique key with 
 * a database row. Load will never create a new domain object.
 * ASYNC
 * 
 * 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.
 *
 * This function returns a promise.  On success, the promise will be fulfilled 
 * with the loaded instance.  The optional callback receives an error value and 
 * the loaded instance.  Any extra arguments passed after the callback will 
 * be passed to the callback function verbatim as parameters following 
 * the loaded instance value.
 * 
 * @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 promise
 */
load(Object instance, [callback], [...]);

/** Insert the instance into the database.
 * ASYNC
 *
 * 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.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 */
persist(Object instance, [callback], [...]);
  
/** Insert the instance into the database. See the other variant for semantics.
 * ASYNC
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 */
persist(Function constructor, Object values, [callback], [...]);
  
/** Insert the instance into the database. See the other variant for semantics.
 * ASYNC
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 */
persist(String tableName, Object values, [callback]. [...]);
  
/** Delete an instance of a class from the database by a primary or unique key.
 * ASYNC
 * 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.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 * 
 * @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 promise
 */
remove(Object instance, [callback], [...]);

/** Delete a row from the database by a unique or primary key.
 * ASYNC
 * 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.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 */
remove(Function constructor, Object keys, [callback], [...]);

/** Delete a row from the database by a unique or primary key.
 * ASYNC
 * See other variant for semantics.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 */
remove(String tableName, Object keys, [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 error is reported.
 * This method cannot be used to change the primary key.
 *
 * To efficiently perform read/modify/write, the user should find the object,
 * modify the fields to be updated, set the fields *not* to be updated
 * to undefined, and call update on the object.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 * ASYNC
 */
update(Object instance, [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 error is reported.
 * This method cannot be used to change the primary key.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 * ASYNC
 */
update(Function constructor, keys, values,  [callback], [...]);

/** Update the instance in the database without necessarily retrieving it.
 * See other variant for semantics.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 * ASYNC
 */
update(String tableName, keys, values, [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.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 * ASYNC
 */
save(Object instance, [callback], [...]);

/** Save the instance in the database without checking for existence.
 * See other variant for semantics.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 * ASYNC
 */
save(Function constructor, Object values,  [callback], [...]);

/** Save the instance in the database without checking for existence.
 * See other variant for semantics.
 *
 * This function returns a promise.  On success, the promise will be fulfilled.
 * The optional callback receives only an error value.  Any extra arguments 
 * passed after the callback will be passed to the callback function verbatim
 * as parameters following the error value.
 *
 * @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 promise
 * ASYNC
 */
save(String tableName, Object values, [callback], [...]);

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

/** Get mappings for a table or class. 
 * The result is a fully resolved TableMapping
 * The parameter may be a table name, a mapped constructor function, or
 * a domain object. 
 *
 * This function returns a promise.  On success, the promise will be fulfilled
 * with a resolved TableMapping value.  The optional callback receives an error 
 * value and the resolved mapping.  Any extra arguments passed after the 
 * callback will be passed to the callback function verbatim as parameters 
 * following the resolved mapping.
 *
 * @method getMapping
 * @param table the table name or constructor of a mapped class
 * @param callback function to be called when operation has completed,
 *                 with parameters:
 *                    err: the node.js Error object
 *                    mapping: the mapping for the parameter
 * @throws Error if the parameter is not an object, string, or function
 * @return promise
 * ASYNC
 */
getMapping(domainObjectTableNameOrConstructor, [callback], [...]);

/** Create a query object that can be used to query the database.
 * The first parameter is:
 *    an object of a type whose constructor has been annotated, or
 *    a constructor that has been annotated, or 
 *    the name of a table.
 * The created query object implements the behavior of Query. 
 * 
 * This function returns a promise.  On success, the promise will be fulfilled
 * with a Query instance.  The optional callback receives an error 
 * value and Query instance.  Any extra arguments passed after the 
 * callback will be passed to the callback function verbatim as parameters 
 * following the Query.
 *
 * @method createQuery
 * @param table name, mapped instance, or constructor of a mapped class
 * @return promise
 * ASYNC
 */
createQuery(domainObjectTableNameOrConstructor, [callback], [...]);

/** Create an empty batch.
 *
 * The batch is used to collect multiple operations to be executed together. 
 *
 *
 * @method createQuery
 * @return Batch
 * IMMEDIATE
 */ 
Batch createBatch();

/** List all current batches.
 * IMMEDIATE
 * @method listBatches
 * @return Array
 */
Array listBatches();

/** Get the current Transaction. 
 * @method currentTransaction
 * @return the transaction
 * IMMEDIATE
 */
Transaction currentTransaction();

/** Close this session. This must be called when the session is
 * no longer needed.
 * 
 * @method close
 * @param callback
 @ async
 */
void close(Function(error) callback);

/** Is this session closed?
 *
 * @method isClosed
 * @return {Boolean} true if the session is closed
 * IMMEDIATE
 */
boolean isClosed();

/** Set the partition key for the next transaction.
 *
 * Normally, this is not needed. Mysql-js will automatically set
 * the partition key based on the first operation in the transaction.
 * If the user needs explicit control over the partition key,
 * this is the way to do it.
 * 
 * The instance must be an object that is capable of being persisted. 
 * The values of the partition key will be taken from the values
 * in the instance.
 * 
 * @method setPartitionKey
 * @param instance the object with all partition key properties set
 * @return an Error object or null if no error
 * IMMEDIATE
 */
Error setPartitionKey(instance);

/** Set the partition key for the next transaction.
 *
 * Normally, this is not needed. Mysql-js will automatically set
 * the partition key based on the first operation in the transaction.
 * If the user needs explicit control over the partition key,
 * this is the way to do it.
 * 
 * The mapping is an object obtained from a class after the
 * class has been annotated. 
 * The parameter "keys" may be of a type that can 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.
 * The returned object will be loaded based on the mapping and the current
 * values in the database.
 * 
 * @return an Error object or null if no error
 * IMMEDIATE
 */
Error setPartitionKey(mapping, keys);

/** Set the lock mode for read operations. This will take effect immediately
 * and will remain in effect until this session is closed or this method
 * is called again.
 * @param lockmode the LockMode: 'EXCLUSIVE', 'SHARED', or 'NONE'
 *
 * IMMEDIATE
 */
void setLockMode(lockmode);


/** listTables(database, callback) 
 *  ASYNC
 *  
 *  list tables in database
 */
listTables(databaseName, callback);


/** getTableMetadata(databaseName, tableName, callback) 
 *  ASYNC
 *
 *  Fetch metadata for table 
 */
getTableMetadata(databaseName, tableName, callback);
}

/* 
 * Users may find useful a "user" property of session and batch.
 * The mynode implementation will not ever define a property called "user".
 */

