/* ************************************************************************
#
#  DivConq
#
#  http://divconq.com/
#
#  Copyright:
#    Copyright 2012 eTimeline, LLC. All rights reserved.
#
#  License:
#    See the license.txt file in the project's top-level directory for details.
#
#  Authors:
#    * Andy White
#
************************************************************************ */
package divconq.db;

import divconq.lang.FuncResult;
import divconq.lang.OperationCallback;
import divconq.lang.OperationResult;
import divconq.struct.RecordStruct;
import divconq.struct.Struct;
import divconq.util.ISettingsObfuscator;
import divconq.xml.XElement;

/**
 * Manages one or more connections to a dcDb compatible server.
 * 
 * Database Requests (IDatabaseRequest) are submitted asynchronously.  After a request has been processed 
 * a callback is triggered letting the calling code know that a result is available.
 * 
 * Database results are typically collected into an object structure (see CompositeStruct) and
 * returned in one large lump.  As an alternative database results may be processed as a stream, 
 * see ICompositeBuilder and JsonStreamBuilder.
 * 
 * See divconq.test.TestDb for usage examples.
 * 
 * @author Andy
 *
 */
public interface IDatabaseManager {
	/**
	 * Provide the setting for this database pool, but do not yet connect.
	 * 
	 * @param config configuration for this database pool
	 * @return messages about the success of this call
	 */
	OperationResult init(XElement config);
	
	/**
	 * Takes the settings from "init" and sets up the pool for operation,
	 * including making the connection to the database server.
	 * 
	 * @return messages about the success of this call
	 */
	OperationResult start();
	
	/**
	 * Gracefully stop the database pool, allowing for up to 1 minute for shutdown.
	 * 
	 * @return messages about the success of this call
	 */
	OperationResult stop();
	
	/**
	 * Asynchronously submit a database request for processing.  If the submit succeeds then look
	 * for the result (even if in error) to come to the callback.  If submit does not succeed then
	 * look for the result to come from the method return, and callback will not be called. 
	 *  
	 *  @param request request object to be processed
	 *  @param cb  the callback to use when database response is complete
	 *  @return messages about the success of this call
	 */
	OperationResult submit(IDatabaseRequest request, ObjectCallback cb);	
	
	/**
	 * Asynchronously submit a database request for processing.  If the submit succeeds then look
	 * for the result (even if in error) to come to the callback.  If submit does not succeed then
	 * look for the result to come from the method return, and callback will not be called. 
	 *  
	 *  @param request request object to be processed
	 *  @param resp object to process and hold the result
	 *  @param cb  the callback to use when database response is complete
	 *  @return messages about the success of this call
	 */
	OperationResult submit(IDatabaseRequest request, DatabaseResult resp, IDatabaseCallback cb);	
	
	/**
	 * When preparing a value for storage in the database, the value may need to be converted
	 * to some other structure, for example with MUMPS we break strings down into 4000 byte
	 * chunks and return a List.
	 * 
	 * @param obj value to store in the database
	 * @return the converted structure
	 */
	FuncResult<Struct> convertValue(Object obj);
	
	/**
	 * Get a summary of all status and counters for this database pool
	 * 
	 * @return key value pairs for the various counters and flags
	 */
	RecordStruct getStatus();
	
	
	/**
	 * Basically indicates that stored procedures have been updated and it is time
	 * to reload proc cache 
	 */
	void resetConnections();

	void syncSchema(final OperationCallback cb);
	void syncScripts(OperationCallback operationCallback);
	
	ISettingsObfuscator getObfuscator();
}
