/*
** Functions for use with the sqlite library.
*/

#ifndef SQAUX_BASE_H
#define SQAUX_BASE_H

#include "sqlite.h"

/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif

typedef int BOOL;

#ifndef TRUE
#define TRUE (1)
#endif

#ifndef FALSE
#define FALSE (0)
#endif

/**********************************************************************************************************************/
/* Callback functions */

/*
** Empty callback function needed to call sqlite_exec(),
**   which won't accept NULL for the callback argument.
** Return zero on success, non-zero on failure.
*/
int callback_empty(void *pArg, int nArg, char **azArg, char **azCol);

/* All uses of sqlite_exec() REQUIRE a callback function.
 * This function outputs the row data to stdout with tab delimiters.
 * <pArg> is an app-supplied argument passed into sqlite_exec().
 * <argc> is the number of columns of data.
 * <argv> is an array of the column data.
 * <azColName> is an array of the column names.
 */
int callback_output_tabbed(void *pArg, int argc, char **argv, char **azColName);

/*
** Set the database to use with callback_query().
*/
void callback_query_set_db(sqlite* db);

/*
** Get the database to use with callback_query().
*/
sqlite *callback_query_get_db();

/*
** Callback function called to perform a query using the result row data.
** This acts on a static database pointer.
** <pQuery> is a query string passed into the original sqlite_exec() call.
** It will contain %s fields which will be replaced by the row data.
** The number of %s occurrances must match the number of columns in the result.
** NULL result strings will be inserted as "NULL" in the query string.
** Return zero on success, non-zero on failure.
*/
int callback_query(void *pArg, int nArg, char **azArg, char **azCol);


/**********************************************************************************************************************/
/* Utility functions */

/*
** Get the name of an open sqlite database.
*/
const char *sqaux_get_filename(sqlite *db);

/*
** Open another connection to an open sqlite database.
** <db> is a currently open sqlite database.
** <mode> is currently unused by sqlite_open().
** <pzErrMsg> points to a string pointer, and can be NULL.
*/
sqlite *sqaux_dup(sqlite *db, int mode, char **pzErrMsg);

/*
** Compute the maximum size required by sqlite_encode_binary().
** This doesn't include the NUL byte which terminates the string.
*/
int sqaux_encode_maxsize(int datasize);

/*
** Retrieve the first data string returned by a query.
** Retrieve NULL if the query had no results.
** The string must be freed by sqaux_free_string().
** Returns an integer error value.
*/
int sqaux_get_string(
  sqlite* db,            /* An open database */
  const char *sql,       /* SQL to be executed */
  char **resultp,        /* Result written to a char* that this points to */
  char **errmsg          /* Error msg written here */
);

/*
** Version of sqaux_get_string() that takes vprintf-style arguments.
*/
int sqaux_get_string_vprintf(
  sqlite* db,           /* An open database */
  const char *sqlfmt,   /* printf-style format string for the SQL */
  char **resultp,       /* Result written to a char* that this points to. */
						/* This argument must be non-null. */
  char **errmsg,        /* Error msg written here */
  va_list ap            /* Arguments to the format string. */
);

/*
** Version of sqaux_get_string() that takes printf-style arguments.
*/
int sqaux_get_string_printf(
  sqlite* db,           /* An open database */
  const char *sqlfmt,   /* printf-style format string for the SQL */
  char **resultp,       /* Result written to a char* that this points to. */
						/* This argument must be non-null. */
  char **errmsg,        /* Error msg written here */
  ...					/* Arguments to the format string. */
);

/*
** Free a string returned by sqaux_get_string().
*/
void sqaux_free_string(char* str);

/*
** Retrieves the first data string returned by a query.
** Converts the string to an integer and 'returns' it.
** If no string is obtained, the original long is
**   left unchanged, but no error value is returned
**   unless the original query had an error.
** Returns an integer error value.
*/
int sqaux_get_long(
  sqlite* db,            /* An open database */
  const char *sql,       /* SQL to be executed */
  long *resultp,         /* Result written to a long that this points to */
  char **errmsg          /* Error msg written here */
);

/*
** Find out if a table/index/view/... exists in the database.
** This finds both normal and temporary features.
** <type> is the type of a feature as it exists in SQLITE_[TEMP_]MASTER:
**   "index", "table", "view".
**   This will NOT check if a TRIGGER exists -- this isn't stored in SQLITE_MASTER.
** <name> is the name of a feature as it exists in SQLITE_[TEMP_]MASTER.
*/
BOOL sqaux_feature_exists(sqlite* db, const char *type, const char *name);

/*
** Find out if a [temporary] table exists in the database.
*/
BOOL sqaux_table_exists(sqlite* db, const char *name);

/*
** Find out if a trigger is registered with the database.
** Triggers aren't stored in the database -- they are runtime only.
*/ 
BOOL sqaux_trigger_exists(sqlite* db, const char *trigger);

/*
** Find the version of a sqlite database from the file.
** This is done without calling sqlite_open(), so an older version
**   database won't automatically be converted to a newer version.
**   When sqlite_open() is called on a database with file_format <= 2,
**   it is automatically upgraded to 3 without prompting.
** This function was adapted from sqlite_open().
** <zFilename> is the full name of the file to open.
** <pfile_format> is a pointer to return the file_format in.
** The various file formats are as follows:
**   file_format==-1   Set on error by this function
**   file_format== 1   Version 2.1.0.
**   file_format== 2   Version 2.2.0. Add support for INTEGER PRIMARY KEY.
**   file_format== 3   Version 2.6.0. Fix empty-string index bug.
**   file_format== 4   Version 2.7.0. Add support for separate numeric and text datatypes.
** Returns SQLITE_OK on success, nonzero on error.
*/
int sqaux_get_file_format(const char *zFilename, int *pfile_format);

/*
** Backup the sqlite values which are used by sqlite_exec()
** and overwrite with values that will allow a recursive call.
** sqaux_end_recurse() must be called afterwards.
** <pmagic> holds the sqlite internal data backed up.
** These are related to helpers sqliteSafetyOn/Off().
** Returns 0 on success, non-zero on error.
*/
int sqaux_begin_recurse(sqlite* db, int *pmagic);

/*
** Restore the sqlite values which are used by sqlite_exec()
** with the data saved by sqaux_begin_recurse().
** <pmagic> holds the sqlite internal data backed up.
** These are related to helpers sqliteSafetyOn/Off().
** Returns 0 on success, non-zero on error.
*/
int sqaux_end_recurse(sqlite* db, int *pmagic);


/**********************************************************************************************************************/

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

#endif /* SQAUX_BASE_H */
