X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fcats%2Fcats.h;h=a22878c37514aefc5f13bc006dbca2628dd29e85;hb=f5e7d95ce741ea5c296d605b2f411805a65462d6;hp=9e0e5060c3241185d3d13a1814f61d32b105cc7f;hpb=4c0d3aa12e80a948c8b1722910307011d75c8e48;p=bacula%2Fbacula diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index 9e0e5060c3..a22878c375 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -1,12 +1,12 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2010 Free Software Foundation Europe e.V. + Copyright (C) 2000-2011 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public + modify it under the terms of version three of the GNU Affero General Public License as published by the Free Software Foundation and included in the file LICENSE. @@ -15,7 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -26,18 +26,12 @@ Switzerland, email:ftf@fsfeurope.org. */ /* - * SQL header file + * Catalog header file * - * by Kern E. Sibbald - * - * Anyone who accesses the database will need to include - * this file. - * - * This file contains definitions common to sql.c and - * the external world, and definitions destined only - * for the external world. This is control with - * the define __SQL_C, which is defined only in sql.c + * by Kern E. Sibbald * + * Anyone who accesses the database will need to include + * this file. */ /* @@ -57,748 +51,9 @@ am 100% sure there will be no more changes, the update script will be copied to the updatedb directory with the correct name (in the present case 8 to 9). - - Now, in principle, each of the different DB implementations - can have a different version, but in practice they are all - the same (simplifies things). The exception is the internal - database, which is no longer used, and hence, no longer changes. */ - - -#ifndef __SQL_H_ -#define __SQL_H_ 1 - -enum { - SQL_TYPE_MYSQL = 0, - SQL_TYPE_POSTGRESQL = 1, - SQL_TYPE_SQLITE = 2, - SQL_TYPE_SQLITE3 = 3, - SQL_TYPE_INGRES = 4 -}; - - -typedef void (DB_LIST_HANDLER)(void *, const char *); -typedef int (DB_RESULT_HANDLER)(void *, int, char **); - -#define db_lock(mdb) _db_lock(__FILE__, __LINE__, mdb) -#define db_unlock(mdb) _db_unlock(__FILE__, __LINE__, mdb) - -#ifdef __SQL_C - -#if defined(BUILDING_CATS) -#ifdef HAVE_SQLITE -#error "SQLite2 is now deprecated, use SQLite3 instead." - -#define BDB_VERSION 12 - -#include - -/* Define opaque structure for sqlite */ -struct sqlite { - char dummy; -}; - -#define IS_NUM(x) ((x) == 1) -#define IS_NOT_NULL(x) ((x) == 1) - -typedef struct s_sql_field { - char *name; /* name of column */ - int length; /* length */ - int max_length; /* max length */ - uint32_t type; /* type */ - uint32_t flags; /* flags */ -} SQL_FIELD; - -/* - * This is the "real" definition that should only be - * used inside sql.c and associated database interface - * subroutines. - * S Q L I T E - */ -struct B_DB { - dlink link; /* queue control */ - brwlock_t lock; /* transaction lock */ - struct sqlite *db; - char **result; - int status; - int nrow; /* nrow returned from sqlite */ - int ncolumn; /* ncolum returned from sqlite */ - int num_rows; /* used by code */ - int row; /* seek row */ - int field; /* seek field */ - SQL_FIELD **fields; /* defined fields */ - int ref_count; - char *db_name; - char *db_user; - char *db_address; /* host name address */ - char *db_socket; /* socket for local access */ - char *db_password; - int db_port; /* port for host name address */ - bool connected; /* connection made to db */ - bool fields_defined; /* set when fields defined */ - char *sqlite_errmsg; /* error message returned by sqlite */ - POOLMEM *errmsg; /* nicely edited error message */ - POOLMEM *cmd; /* SQL command string */ - POOLMEM *cached_path; /* cached path name */ - int cached_path_len; /* length of cached path */ - uint32_t cached_path_id; /* cached path id */ - bool allow_transactions; /* transactions allowed */ - bool transaction; /* transaction started */ - int changes; /* changes during transaction */ - POOLMEM *fname; /* Filename only */ - POOLMEM *path; /* Path only */ - POOLMEM *esc_name; /* Escaped file name */ - POOLMEM *esc_path; /* Escaped path name */ - int fnl; /* file name length */ - int pnl; /* path name length */ -}; - - -/* - * "Generic" names for easier conversion - * - * S Q L I T E - */ -#define sql_store_result(x) (x)->result -#define sql_free_result(x) my_sqlite_free_table(x) -#define sql_fetch_row(x) my_sqlite_fetch_row(x) -#define sql_query(x, y) my_sqlite_query((x), (y)) -#define sql_insert_autokey_record(x, y, z) my_sqlite_insert_autokey_record((x), (y), (z)) -#ifdef HAVE_SQLITE3 -#define sql_close(x) sqlite3_close((x)->db) -#define sql_affected_rows(x) sqlite3_changes((x)->db) -#else -#define sql_close(x) sqlite_close((x)->db) -#define sql_affected_rows(x) 1 -#endif -#define sql_strerror(x) (x)->sqlite_errmsg?(x)->sqlite_errmsg:"unknown" -#define sql_num_rows(x) (x)->nrow -#define sql_data_seek(x, i) (x)->row = (i) -#define sql_field_seek(x, y) my_sqlite_field_seek((x), (y)) -#define sql_fetch_field(x) my_sqlite_fetch_field(x) -#define sql_num_fields(x) ((x)->ncolumn) -#define SQL_ROW char** -#define SQL_MATCH "MATCH" - -#define sql_batch_start(x,y) my_batch_start(x,y) -#define sql_batch_end(x,y,z) my_batch_end(x,y,z) -#define sql_batch_insert(x,y,z) my_batch_insert(x,y,z) -#define sql_batch_lock_path_query my_sqlite_batch_lock_query -#define sql_batch_lock_filename_query my_sqlite_batch_lock_query -#define sql_batch_unlock_tables_query my_sqlite_batch_unlock_query -#define sql_batch_fill_filename_query my_sqlite_batch_fill_filename_query -#define sql_batch_fill_path_query my_sqlite_batch_fill_path_query - -/* In cats/sqlite.c */ -void my_sqlite_free_table(B_DB *mdb); -SQL_ROW my_sqlite_fetch_row(B_DB *mdb); -int my_sqlite_query(B_DB *mdb, const char *cmd); -void my_sqlite_field_seek(B_DB *mdb, int field); -SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb); -int my_sqlite_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name); -extern const char* my_sqlite_batch_lock_query; -extern const char* my_sqlite_batch_unlock_query; -extern const char* my_sqlite_batch_fill_filename_query; -extern const char* my_sqlite_batch_fill_path_query; - - -#else - -/* S Q L I T E 3 */ - - -#ifdef HAVE_SQLITE3 - - -#define BDB_VERSION 12 - -#include - -/* Define opaque structure for sqlite */ -struct sqlite3 { - char dummy; -}; - -#define IS_NUM(x) ((x) == 1) -#define IS_NOT_NULL(x) ((x) == 1) - -typedef struct s_sql_field { - char *name; /* name of column */ - int length; /* length */ - int max_length; /* max length */ - uint32_t type; /* type */ - uint32_t flags; /* flags */ -} SQL_FIELD; - -/* - * This is the "real" definition that should only be - * used inside sql.c and associated database interface - * subroutines. - * S Q L I T E - */ -struct B_DB { - dlink link; /* queue control */ - brwlock_t lock; /* transaction lock */ - struct sqlite3 *db; - char **result; - int status; - int nrow; /* nrow returned from sqlite */ - int ncolumn; /* ncolum returned from sqlite */ - int num_rows; /* used by code */ - int row; /* seek row */ - int field; /* seek field */ - SQL_FIELD **fields; /* defined fields */ - int ref_count; - char *db_name; - char *db_user; - char *db_address; /* host name address */ - char *db_socket; /* socket for local access */ - char *db_password; - int db_port; /* port for host name address */ - bool connected; /* connection made to db */ - bool fields_defined; /* set when fields defined */ - char *sqlite_errmsg; /* error message returned by sqlite */ - POOLMEM *errmsg; /* nicely edited error message */ - POOLMEM *cmd; /* SQL command string */ - POOLMEM *cached_path; /* cached path name */ - int cached_path_len; /* length of cached path */ - uint32_t cached_path_id; /* cached path id */ - bool allow_transactions; /* transactions allowed */ - bool transaction; /* transaction started */ - int changes; /* changes during transaction */ - POOLMEM *fname; /* Filename only */ - POOLMEM *path; /* Path only */ - POOLMEM *esc_name; /* Escaped file name */ - POOLMEM *esc_path; /* Escaped path name */ - int fnl; /* file name length */ - int pnl; /* path name length */ -}; - -/* - * Conversion of sqlite 2 names to sqlite3 - */ -#define sqlite_last_insert_rowid sqlite3_last_insert_rowid -#define sqlite_open sqlite3_open -#define sqlite_close sqlite3_close -#define sqlite_result sqlite3_result -#define sqlite_exec sqlite3_exec -#define sqlite_get_table sqlite3_get_table -#define sqlite_free_table sqlite3_free_table - - -/* - * "Generic" names for easier conversion - * - * S Q L I T E 3 - */ -#define sql_store_result(x) (x)->result -#define sql_free_result(x) my_sqlite_free_table(x) -#define sql_fetch_row(x) my_sqlite_fetch_row(x) -#define sql_query(x, y) my_sqlite_query((x), (y)) -#define sql_insert_autokey_record(x, y, z) my_sqlite_insert_autokey_record((x), (y), (z)) -#ifdef HAVE_SQLITE3 -#define sql_close(x) sqlite3_close((x)->db) -#else -#define sql_close(x) sqlite_close((x)->db) -#endif -#define sql_strerror(x) (x)->sqlite_errmsg?(x)->sqlite_errmsg:"unknown" -#define sql_num_rows(x) (x)->nrow -#define sql_data_seek(x, i) (x)->row = (i) -#define sql_affected_rows(x) sqlite3_changes((x)->db) -#define sql_field_seek(x, y) my_sqlite_field_seek((x), (y)) -#define sql_fetch_field(x) my_sqlite_fetch_field(x) -#define sql_num_fields(x) ((x)->ncolumn) -#define sql_batch_start(x,y) my_batch_start(x,y) -#define sql_batch_end(x,y,z) my_batch_end(x,y,z) -#define sql_batch_insert(x,y,z) my_batch_insert(x,y,z) -#define SQL_ROW char** -#define SQL_MATCH "MATCH" -#define sql_batch_lock_path_query my_sqlite_batch_lock_query -#define sql_batch_lock_filename_query my_sqlite_batch_lock_query -#define sql_batch_unlock_tables_query my_sqlite_batch_unlock_query -#define sql_batch_fill_filename_query my_sqlite_batch_fill_filename_query -#define sql_batch_fill_path_query my_sqlite_batch_fill_path_query - -/* In cats/sqlite.c */ -void my_sqlite_free_table(B_DB *mdb); -SQL_ROW my_sqlite_fetch_row(B_DB *mdb); -int my_sqlite_query(B_DB *mdb, const char *cmd); -void my_sqlite_field_seek(B_DB *mdb, int field); -SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb); -int my_sqlite_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name); -extern const char* my_sqlite_batch_lock_query; -extern const char* my_sqlite_batch_unlock_query; -extern const char* my_sqlite_batch_fill_filename_query; -extern const char* my_sqlite_batch_fill_path_query; - - -#else - -#ifdef HAVE_MYSQL - -#define BDB_VERSION 12 - -#include - -/* - * This is the "real" definition that should only be - * used inside sql.c and associated database interface - * subroutines. - * - * M Y S Q L - */ -struct B_DB { - dlink link; /* queue control */ - brwlock_t lock; /* transaction lock */ - MYSQL mysql; - MYSQL *db; - MYSQL_RES *result; - int status; - my_ulonglong num_rows; - int ref_count; - char *db_name; - char *db_user; - char *db_password; - char *db_address; /* host address */ - char *db_socket; /* socket for local access */ - int db_port; /* port of host address */ - bool connected; - POOLMEM *errmsg; /* nicely edited error message */ - POOLMEM *cmd; /* SQL command string */ - POOLMEM *cached_path; - int cached_path_len; /* length of cached path */ - uint32_t cached_path_id; - bool allow_transactions; /* transactions allowed */ - int changes; /* changes made to db */ - POOLMEM *fname; /* Filename only */ - POOLMEM *path; /* Path only */ - POOLMEM *esc_name; /* Escaped file name */ - POOLMEM *esc_path; /* Escaped path name */ - int fnl; /* file name length */ - int pnl; /* path name length */ -}; - -#define DB_STATUS int - -/* "Generic" names for easier conversion */ -#define sql_store_result(x) mysql_store_result((x)->db) -#define sql_use_result(x) mysql_use_result((x)->db) -#define sql_free_result(x) my_mysql_free_result(x) -#define sql_fetch_row(x) mysql_fetch_row((x)->result) -#define sql_query(x, y) mysql_query((x)->db, (y)) -#define sql_strerror(x) mysql_error((x)->db) -#define sql_num_rows(x) mysql_num_rows((x)->result) -#define sql_data_seek(x, i) mysql_data_seek((x)->result, (i)) -#define sql_affected_rows(x) mysql_affected_rows((x)->db) -#define sql_insert_autokey_record(x, y, z) my_mysql_insert_autokey_record((x), (y), (z)) -#define sql_field_seek(x, y) mysql_field_seek((x)->result, (y)) -#define sql_fetch_field(x) mysql_fetch_field((x)->result) -#define sql_num_fields(x) (int)mysql_num_fields((x)->result) -#define SQL_ROW MYSQL_ROW -#define SQL_FIELD MYSQL_FIELD -#define SQL_MATCH "MATCH" - -#define sql_batch_start(x,y) my_batch_start(x,y) -#define sql_batch_end(x,y,z) my_batch_end(x,y,z) -#define sql_batch_insert(x,y,z) my_batch_insert(x,y,z) -#define sql_batch_lock_path_query my_mysql_batch_lock_path_query -#define sql_batch_lock_filename_query my_mysql_batch_lock_filename_query -#define sql_batch_unlock_tables_query my_mysql_batch_unlock_tables_query -#define sql_batch_fill_filename_query my_mysql_batch_fill_filename_query -#define sql_batch_fill_path_query my_mysql_batch_fill_path_query - - -extern const char* my_mysql_batch_lock_path_query; -extern const char* my_mysql_batch_lock_filename_query; -extern const char* my_mysql_batch_unlock_tables_query; -extern const char* my_mysql_batch_fill_filename_query; -extern const char* my_mysql_batch_fill_path_query; -extern void my_mysql_free_result(B_DB *mdb); -extern int my_mysql_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name); - -#else - -#ifdef HAVE_POSTGRESQL - -#define BDB_VERSION 12 - -#include - -/* TEMP: the following is taken from select OID, typname from pg_type; */ -#define IS_NUM(x) ((x) == 20 || (x) == 21 || (x) == 23 || (x) == 700 || (x) == 701) -#define IS_NOT_NULL(x) ((x) == 1) - -typedef char **POSTGRESQL_ROW; -typedef struct pg_field { - char *name; - int max_length; - unsigned int type; - unsigned int flags; // 1 == not null -} POSTGRESQL_FIELD; - - -/* - * This is the "real" definition that should only be - * used inside sql.c and associated database interface - * subroutines. - * - * P O S T G R E S Q L - */ -struct B_DB { - dlink link; /* queue control */ - brwlock_t lock; /* transaction lock */ - PGconn *db; - PGresult *result; - int status; - POSTGRESQL_ROW row; - POSTGRESQL_FIELD *fields; - int num_rows; - int row_size; /* size of malloced rows */ - int num_fields; - int fields_size; /* size of malloced fields */ - int row_number; /* row number from my_postgresql_data_seek */ - int field_number; /* field number from my_postgresql_field_seek */ - int ref_count; - char *db_name; - char *db_user; - char *db_password; - char *db_address; /* host address */ - char *db_socket; /* socket for local access */ - int db_port; /* port of host address */ - bool connected; - POOLMEM *errmsg; /* nicely edited error message */ - POOLMEM *cmd; /* SQL command string */ - POOLMEM *cached_path; - int cached_path_len; /* length of cached path */ - uint32_t cached_path_id; - bool allow_transactions; /* transactions allowed */ - bool transaction; /* transaction started */ - int changes; /* changes made to db */ - POOLMEM *fname; /* Filename only */ - POOLMEM *path; /* Path only */ - POOLMEM *esc_name; /* Escaped file name */ - POOLMEM *esc_path; /* Escaped path name */ - int fnl; /* file name length */ - int pnl; /* path name length */ -}; - -void my_postgresql_free_result(B_DB *mdb); -POSTGRESQL_ROW my_postgresql_fetch_row (B_DB *mdb); -int my_postgresql_query (B_DB *mdb, const char *query); -void my_postgresql_data_seek (B_DB *mdb, int row); -int my_postgresql_insert_autokey_record (B_DB *mdb, const char *query, const char *table_name); -void my_postgresql_field_seek (B_DB *mdb, int row); -POSTGRESQL_FIELD * my_postgresql_fetch_field(B_DB *mdb); - -int my_postgresql_batch_start(JCR *jcr, B_DB *mdb); -int my_postgresql_batch_end(JCR *jcr, B_DB *mdb, const char *error); -typedef struct ATTR_DBR ATTR_DBR; -int my_postgresql_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); -char *my_postgresql_copy_escape(char *dest, char *src, size_t len); - -extern const char* my_pg_batch_lock_path_query; -extern const char* my_pg_batch_lock_filename_query; -extern const char* my_pg_batch_unlock_tables_query; -extern const char* my_pg_batch_fill_filename_query; -extern const char* my_pg_batch_fill_path_query; - -/* "Generic" names for easier conversion */ -#define sql_store_result(x) ((x)->result) -#define sql_free_result(x) my_postgresql_free_result(x) -#define sql_fetch_row(x) my_postgresql_fetch_row(x) -#define sql_query(x, y) my_postgresql_query((x), (y)) -#define sql_close(x) PQfinish((x)->db) -#define sql_strerror(x) PQerrorMessage((x)->db) -#define sql_num_rows(x) ((unsigned) PQntuples((x)->result)) -#define sql_data_seek(x, i) my_postgresql_data_seek((x), (i)) -#define sql_affected_rows(x) ((unsigned) atoi(PQcmdTuples((x)->result))) -#define sql_insert_autokey_record(x, y, z) my_postgresql_insert_autokey_record((x), (y), (z)) -#define sql_field_seek(x, y) my_postgresql_field_seek((x), (y)) -#define sql_fetch_field(x) my_postgresql_fetch_field(x) -#define sql_num_fields(x) ((x)->num_fields) - -#define sql_batch_start(x,y) my_postgresql_batch_start(x,y) -#define sql_batch_end(x,y,z) my_postgresql_batch_end(x,y,z) -#define sql_batch_insert(x,y,z) my_postgresql_batch_insert(x,y,z) -#define sql_batch_lock_path_query my_pg_batch_lock_path_query -#define sql_batch_lock_filename_query my_pg_batch_lock_filename_query -#define sql_batch_unlock_tables_query my_pg_batch_unlock_tables_query -#define sql_batch_fill_filename_query my_pg_batch_fill_filename_query -#define sql_batch_fill_path_query my_pg_batch_fill_path_query - -#define SQL_ROW POSTGRESQL_ROW -#define SQL_FIELD POSTGRESQL_FIELD -#define SQL_MATCH "~" - -#else - -#ifdef HAVE_INGRES - -#include "myingres.h" - -#define BDB_VERSION 12 - -/* TEMP: the following is taken from select OID, typname from pg_type; */ /*SRE: huh? */ -#define IS_NUM(x) ((x) == 20 || (x) == 21 || (x) == 23 || (x) == 700 || (x) == 701) -#define IS_NOT_NULL(x) ((x) == 1) - -typedef char **INGRES_ROW; - -/* - * This is the "real" definition that should only be - * used inside sql.c and associated database interface - * subroutines. - * - * I N G R E S - */ -struct B_DB { - dlink link; /* queue control */ - brwlock_t lock; /* transaction lock */ - INGconn *db; - INGresult *result; - int status; - INGRES_ROW row; - INGRES_FIELD *fields; - int num_rows; - int row_size; /* size of malloced rows */ - int num_fields; - int fields_size; /* size of malloced fields */ - int row_number; /* row number from my_ingres_data_seek */ - int field_number; /* field number from my_ingres_field_seek */ - int ref_count; - char *db_name; - char *db_user; - char *db_password; - char *db_address; /* host address */ - char *db_socket; /* socket for local access */ - int db_port; /* port of host address */ - int session_id; /* unique session id */ - bool connected; - POOLMEM *errmsg; /* nicely edited error message */ - POOLMEM *cmd; /* SQL command string */ - POOLMEM *cached_path; - int cached_path_len; /* length of cached path */ - uint32_t cached_path_id; - bool allow_transactions; /* transactions allowed */ - bool transaction; /* transaction started */ - int changes; /* changes made to db */ - POOLMEM *fname; /* Filename only */ - POOLMEM *path; /* Path only */ - POOLMEM *esc_name; /* Escaped file name */ - POOLMEM *esc_path; /* Escaped path name */ - alist *query_filters; /* Filters to convert sql queries into supported Ingres SQL */ - int fnl; /* file name length */ - int pnl; /* path name length */ -}; - -void my_ingres_free_result(B_DB *mdb); -INGRES_ROW my_ingres_fetch_row (B_DB *mdb); -int my_ingres_query (B_DB *mdb, const char *query); -void my_ingres_data_seek (B_DB *mdb, int row); -void my_ingres_field_seek (B_DB *mdb, int row); -INGRES_FIELD * my_ingres_fetch_field(B_DB *mdb); -void my_ingres_close (B_DB *mdb); -int my_ingres_insert_autokey_record (B_DB *mdb, const char *query, const char *table_name); - -bool my_ingres_batch_start(JCR *jcr, B_DB *mdb); -bool my_ingres_batch_end(JCR *jcr, B_DB *mdb, const char *error); -typedef struct ATTR_DBR ATTR_DBR; -bool my_ingres_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); -char *my_ingres_copy_escape(char *dest, char *src, size_t len); - -extern const char* my_ingres_batch_lock_path_query; -extern const char* my_ingres_batch_lock_filename_query; -extern const char* my_ingres_batch_unlock_tables_query; -extern const char* my_ingres_batch_fill_filename_query; -extern const char* my_ingres_batch_fill_path_query; - -/* "Generic" names for easier conversion */ -#define sql_store_result(x) ((x)->result) -#define sql_free_result(x) my_ingres_free_result(x) -#define sql_fetch_row(x) my_ingres_fetch_row(x) -#define sql_query(x, y) my_ingres_query((x), (y)) -#define sql_close(x) my_ingres_close(x) -#define sql_strerror(x) INGerrorMessage((x)->db) -#define sql_num_rows(x) ((unsigned) INGntuples((x)->result)) -#define sql_data_seek(x, i) my_ingres_data_seek((x), (i)) -#define sql_affected_rows(x) ((x)->num_rows) -#define sql_insert_autokey_record(x, y, z) my_ingres_insert_autokey_record((x), (y), (z)) -#define sql_field_seek(x, y) my_ingres_field_seek((x), (y)) -#define sql_fetch_field(x) my_ingres_fetch_field(x) -#define sql_num_fields(x) ((x)->num_fields) - -#define sql_batch_start(x,y) my_ingres_batch_start(x,y) -#define sql_batch_end(x,y,z) my_ingres_batch_end(x,y,z) -#define sql_batch_insert(x,y,z) my_ingres_batch_insert(x,y,z) -#define sql_batch_lock_path_query my_ingres_batch_lock_path_query -#define sql_batch_lock_filename_query my_ingres_batch_lock_filename_query -#define sql_batch_unlock_tables_query my_ingres_batch_unlock_tables_query -#define sql_batch_fill_filename_query my_ingres_batch_fill_filename_query -#define sql_batch_fill_path_query my_ingres_batch_fill_path_query - -#define SQL_ROW INGRES_ROW -#define SQL_FIELD INGRES_FIELD -#define SQL_MATCH "~" - -#else - -#ifdef HAVE_DBI - -#define BDB_VERSION 12 - -#include - -#ifdef HAVE_BATCH_FILE_INSERT -#include -#endif //HAVE_BATCH_FILE_INSERT - -#define IS_NUM(x) ((x) == 1 || (x) == 2 ) -#define IS_NOT_NULL(x) ((x) == (1 << 0)) - -typedef char **DBI_ROW; -typedef struct dbi_field { - char *name; - int max_length; - unsigned int type; - unsigned int flags; // 1 == not null -} DBI_FIELD; - -typedef struct dbi_field_get { - dlink link; - char *value; -} DBI_FIELD_GET; - -/* - * This is the "real" definition that should only be - * used inside sql.c and associated database interface - * subroutines. - * - * D B I - */ -struct B_DB { - dlink link; /* queue control */ - brwlock_t lock; /* transaction lock */ - dbi_conn *db; - dbi_result *result; - dbi_inst instance; - dbi_error_flag status; - DBI_ROW row; - DBI_FIELD *fields; - DBI_FIELD_GET *field_get; - int num_rows; - int row_size; /* size of malloced rows */ - int num_fields; - int fields_size; /* size of malloced fields */ - int row_number; /* row number from my_postgresql_data_seek */ - int field_number; /* field number from my_postgresql_field_seek */ - int ref_count; - int db_type; /* DBI driver defined */ - char *db_driverdir ; /* DBI driver dir */ - char *db_driver; /* DBI type database */ - char *db_name; - char *db_user; - char *db_password; - char *db_address; /* host address */ - char *db_socket; /* socket for local access */ - int db_port; /* port of host address */ - bool connected; - POOLMEM *errmsg; /* nicely edited error message */ - POOLMEM *cmd; /* SQL command string */ - POOLMEM *cached_path; - int cached_path_len; /* length of cached path */ - uint32_t cached_path_id; - bool allow_transactions; /* transactions allowed */ - bool transaction; /* transaction started */ - int changes; /* changes made to db */ - POOLMEM *fname; /* Filename only */ - POOLMEM *path; /* Path only */ - POOLMEM *esc_name; /* Escaped file name */ - POOLMEM *esc_path; /* Escaped path name */ - int fnl; /* file name length */ - int pnl; /* path name length */ -}; - -void my_dbi_free_result(B_DB *mdb); -DBI_ROW my_dbi_fetch_row (B_DB *mdb); -int my_dbi_query (B_DB *mdb, const char *query); -void my_dbi_data_seek (B_DB *mdb, int row); -void my_dbi_field_seek (B_DB *mdb, int row); -DBI_FIELD * my_dbi_fetch_field(B_DB *mdb); -const char * my_dbi_strerror (B_DB *mdb); -int my_dbi_getisnull (dbi_result *result, int row_number, int column_number); -char * my_dbi_getvalue (dbi_result *result, int row_number, unsigned int column_number); -//int my_dbi_getvalue (dbi_result *result, int row_number, unsigned int column_number, char *value); -int my_dbi_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name); - -int my_dbi_batch_start(JCR *jcr, B_DB *mdb); -int my_dbi_batch_end(JCR *jcr, B_DB *mdb, const char *error); -typedef struct ATTR_DBR ATTR_DBR; -int my_dbi_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar); -char *my_postgresql_copy_escape(char *dest, char *src, size_t len); -// typedefs for libdbi work with postgresql copy insert -typedef int (*custom_function_insert_t)(void*, const char*, int); -typedef char* (*custom_function_error_t)(void*); -typedef int (*custom_function_end_t)(void*, const char*); - -extern const char* my_dbi_batch_lock_path_query[5]; -extern const char* my_dbi_batch_lock_filename_query[5]; -extern const char* my_dbi_batch_unlock_tables_query[5]; -extern const char* my_dbi_batch_fill_filename_query[5]; -extern const char* my_dbi_batch_fill_path_query[5]; -extern const char* my_dbi_match[5]; - -/* "Generic" names for easier conversion */ -#define sql_store_result(x) (x)->result -#define sql_free_result(x) my_dbi_free_result(x) -#define sql_fetch_row(x) my_dbi_fetch_row(x) -#define sql_query(x, y) my_dbi_query((x), (y)) -#define sql_close(x) dbi_conn_close((x)->db) -#define sql_strerror(x) my_dbi_strerror(x) -#define sql_num_rows(x) dbi_result_get_numrows((x)->result) -#define sql_data_seek(x, i) my_dbi_data_seek((x), (i)) -#define SQL_MATCH my_dbi_match[db_type] -/* #define sql_affected_rows(x) dbi_result_get_numrows_affected((x)->result) */ -#define sql_affected_rows(x) 1 -#define sql_insert_autokey_record(x, y, z) my_dbi_insert_autokey_record((x), (y), (z)) -#define sql_field_seek(x, y) my_dbi_field_seek((x), (y)) -#define sql_fetch_field(x) my_dbi_fetch_field(x) -#define sql_num_fields(x) ((x)->num_fields) -#define sql_batch_start(x,y) my_dbi_batch_start(x,y) -#define sql_batch_end(x,y,z) my_dbi_batch_end(x,y,z) -#define sql_batch_insert(x,y,z) my_dbi_batch_insert(x,y,z) -#define sql_batch_lock_path_query my_dbi_batch_lock_path_query[db_type] -#define sql_batch_lock_filename_query my_dbi_batch_lock_filename_query[db_type] -#define sql_batch_unlock_tables_query my_dbi_batch_unlock_tables_query[db_type] -#define sql_batch_fill_filename_query my_dbi_batch_fill_filename_query[db_type] -#define sql_batch_fill_path_query my_dbi_batch_fill_path_query[db_type] - -#define SQL_ROW DBI_ROW -#define SQL_FIELD DBI_FIELD - -#endif /* HAVE_SQLITE3 */ -#endif /* HAVE_MYSQL */ -#endif /* HAVE_SQLITE */ -#endif /* HAVE_POSTGRESQL */ -#endif /* HAVE_INGRES */ -#endif /* HAVE_DBI */ -#endif - -/* Use for better error location printing */ -#define UPDATE_DB(jcr, db, cmd) UpdateDB(__FILE__, __LINE__, jcr, db, cmd) -#define INSERT_DB(jcr, db, cmd) InsertDB(__FILE__, __LINE__, jcr, db, cmd) -#define QUERY_DB(jcr, db, cmd) QueryDB(__FILE__, __LINE__, jcr, db, cmd) -#define DELETE_DB(jcr, db, cmd) DeleteDB(__FILE__, __LINE__, jcr, db, cmd) - - -#else /* not __SQL_C */ - -/* This is a "dummy" definition for use outside of sql.c - */ -struct B_DB { - int dummy; /* for SunOS compiler */ -}; - -#endif /* __SQL_C */ +#ifndef __CATS_H_ +#define __CATS_H_ 1 /* ============================================================== * @@ -807,8 +62,6 @@ struct B_DB { * cats directory. */ -extern uint32_t bacula_db_version; - #define faddr_t long /* @@ -828,9 +81,6 @@ public: ~dbid_list(); /* in sql.c */ }; - - - /* Job information passed to create job record and update * job record at end of job. Note, although this record * contains all the fields found in the Job database record, @@ -929,6 +179,7 @@ struct ATTR_DBR { uint32_t FileIndex; uint32_t Stream; uint32_t FileType; + uint32_t DeltaSeq; JobId_t JobId; DBId_t ClientId; DBId_t PathId; @@ -943,6 +194,7 @@ struct ROBJECT_DBR { char *object; char *plugin_name; uint32_t object_len; + uint32_t object_full_len; uint32_t object_index; int32_t object_compression; uint32_t FileIndex; @@ -961,6 +213,7 @@ struct FILE_DBR { DBId_t FilenameId; DBId_t PathId; JobId_t MarkId; + uint32_t DeltaSeq; char LStat[256]; char Digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; int DigestType; /* NO_SIG/MD5_SIG/SHA1_SIG */ @@ -1118,9 +371,16 @@ struct FILESET_DBR { }; /* Call back context for getting a 32/64 bit value from the database */ -struct db_int64_ctx { +class db_int64_ctx { +public: int64_t value; /* value returned */ int count; /* number of values seen */ + + db_int64_ctx() : value(0), count(0) {}; + ~db_int64_ctx() {}; +private: + db_int64_ctx(const db_int64_ctx&); /* prohibit pass by value */ + db_int64_ctx &operator=(const db_int64_ctx&); /* prohibit class assignment */ }; /* Call back context for getting a list of comma separated strings from the @@ -1131,36 +391,186 @@ public: POOLMEM *list; /* list */ int count; /* number of values seen */ - db_list_ctx() { list = get_pool_memory(PM_FNAME); *list = 0; count = 0; } + db_list_ctx() { list = get_pool_memory(PM_FNAME); reset(); } ~db_list_ctx() { free_pool_memory(list); list = NULL; } - + void reset() { *list = 0; count = 0;} + void add(const db_list_ctx &str) { + if (str.count > 0) { + if (*list) { + pm_strcat(list, ","); + } + pm_strcat(list, str.list); + count += str.count; + } + } + void add(const char *str) { + if (count > 0) { + pm_strcat(list, ","); + } + pm_strcat(list, str); + count++; + } private: db_list_ctx(const db_list_ctx&); /* prohibit pass by value */ db_list_ctx &operator=(const db_list_ctx&); /* prohibit class assignment */ }; +typedef enum { + SQL_INTERFACE_TYPE_MYSQL = 0, + SQL_INTERFACE_TYPE_POSTGRESQL = 1, + SQL_INTERFACE_TYPE_SQLITE3 = 2, + SQL_INTERFACE_TYPE_INGRES = 3, + SQL_INTERFACE_TYPE_DBI = 4 +} SQL_INTERFACETYPE; + +typedef enum { + SQL_TYPE_MYSQL = 0, + SQL_TYPE_POSTGRESQL = 1, + SQL_TYPE_SQLITE3 = 2, + SQL_TYPE_INGRES = 3, + SQL_TYPE_UNKNOWN = 99 +} SQL_DBTYPE; + +typedef void (DB_LIST_HANDLER)(void *, const char *); +typedef int (DB_RESULT_HANDLER)(void *, int, char **); + +#define db_lock(mdb) mdb->_db_lock(__FILE__, __LINE__) +#define db_unlock(mdb) mdb->_db_unlock(__FILE__, __LINE__) + +/* Current database version number for all drivers */ +#define BDB_VERSION 14 + +class B_DB: public SMARTALLOC { +protected: + brwlock_t m_lock; /* transaction lock */ + dlink m_link; /* queue control */ + SQL_INTERFACETYPE m_db_interface_type; /* type of backend used */ + SQL_DBTYPE m_db_type; /* database type */ + int m_ref_count; /* reference count */ + bool m_connected; /* connection made to db */ + bool m_have_batch_insert; /* have batch insert support ? */ + char *m_db_driver; /* database driver */ + char *m_db_driverdir; /* database driver dir */ + char *m_db_name; /* database name */ + char *m_db_user; /* database user */ + char *m_db_address; /* host name address */ + char *m_db_socket; /* socket for local access */ + char *m_db_password; /* database password */ + int m_db_port; /* port for host name address */ + bool m_disabled_batch_insert; /* explicitly disabled batch insert mode ? */ + +public: + POOLMEM *errmsg; /* nicely edited error message */ + POOLMEM *cmd; /* SQL command string */ + POOLMEM *cached_path; /* cached path name */ + int cached_path_len; /* length of cached path */ + uint32_t cached_path_id; /* cached path id */ + int changes; /* changes during transaction */ + POOLMEM *fname; /* Filename only */ + POOLMEM *path; /* Path only */ + POOLMEM *esc_name; /* Escaped file name */ + POOLMEM *esc_path; /* Escaped path name */ + POOLMEM *esc_obj; /* Escaped restore object */ + int fnl; /* file name length */ + int pnl; /* path name length */ + + /* methods */ + B_DB() {}; + virtual ~B_DB() {}; + const char *get_db_name(void) { return m_db_name; }; + const char *get_db_user(void) { return m_db_user; }; + bool is_connected(void) { return m_connected; }; + bool batch_insert_available(void) { return m_have_batch_insert; }; + void increment_refcount(void) { m_ref_count++; }; + + /* low level methods */ + bool db_match_database(const char *db_driver, const char *db_name, + const char *db_address, int db_port); + B_DB *db_clone_database_connection(JCR *jcr, bool mult_db_connections); + int db_get_type_index(void) { return m_db_type; }; + const char *db_get_type(void); + void _db_lock(const char *file, int line); + void _db_unlock(const char *file, int line); + bool db_sql_query(const char *query, int flags=0); + void print_lock_info(FILE *fp); + + /* Pure virtual low level methods */ + virtual bool db_open_database(JCR *jcr) = 0; + virtual void db_close_database(JCR *jcr) = 0; + virtual void db_thread_cleanup(void) = 0; + virtual void db_escape_string(JCR *jcr, char *snew, char *old, int len) = 0; + virtual char *db_escape_object(JCR *jcr, char *old, int len) = 0; + virtual void db_unescape_object(JCR *jcr, char *from, int32_t expected_len, + POOLMEM **dest, int32_t *len) = 0; + virtual void db_start_transaction(JCR *jcr) = 0; + virtual void db_end_transaction(JCR *jcr) = 0; + virtual bool db_sql_query(const char *query, DB_RESULT_HANDLER *result_handler, void *ctx) = 0; + + /* By default, we use db_sql_query */ + virtual bool db_big_sql_query(const char *query, + DB_RESULT_HANDLER *result_handler, void *ctx) { + return db_sql_query(query, result_handler, ctx); + }; +}; + +/* sql_query Query Flags */ +#define QF_STORE_RESULT 0x01 + +/* Use for better error location printing */ +#define UPDATE_DB(jcr, db, cmd) UpdateDB(__FILE__, __LINE__, jcr, db, cmd) +#define INSERT_DB(jcr, db, cmd) InsertDB(__FILE__, __LINE__, jcr, db, cmd) +#define QUERY_DB(jcr, db, cmd) QueryDB(__FILE__, __LINE__, jcr, db, cmd) +#define DELETE_DB(jcr, db, cmd) DeleteDB(__FILE__, __LINE__, jcr, db, cmd) #include "protos.h" #include "jcr.h" #include "sql_cmds.h" -/* - * Exported globals from sql.c - */ -extern int CATS_IMP_EXP db_type; /* SQL engine type index */ +/* Object used in db_list_xxx function */ +class LIST_CTX { +public: + char line[256]; /* Used to print last dash line */ + int32_t num_rows; + + e_list_type type; /* Vertical/Horizontal */ + DB_LIST_HANDLER *send; /* send data back */ + bool once; /* Used to print header one time */ + void *ctx; /* send() user argument */ + B_DB *mdb; + JCR *jcr; + + void empty() { + once = false; + line[0] = '\0'; + } + + void send_dashes() { + if (*line) { + send(ctx, line); + } + } + + LIST_CTX(JCR *j, B_DB *m, DB_LIST_HANDLER *h, void *c, e_list_type t) { + line[0] = '\0'; + once = false; + num_rows = 0; + type = t; + send = h; + ctx = c; + jcr = j; + mdb = m; + } +}; /* - * Some functions exported by sql.c for use within the - * cats directory. + * Some functions exported by sql.c for use within the cats directory. */ -void list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type); +int list_result(void *vctx, int cols, char **row); +int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type); void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx); int get_sql_record_max(JCR *jcr, B_DB *mdb); bool check_tables_version(JCR *jcr, B_DB *mdb); bool db_check_max_connections(JCR *jcr, B_DB *mdb, uint32_t nb); -void _db_unlock(const char *file, int line, B_DB *mdb); -void _db_lock(const char *file, int line, B_DB *mdb); -const char *db_get_type(void); void print_dashes(B_DB *mdb); void print_result(B_DB *mdb); @@ -1169,4 +579,4 @@ int InsertDB(const char *file, int line, JCR *jcr, B_DB *db, char *select_cmd); int DeleteDB(const char *file, int line, JCR *jcr, B_DB *db, char *delete_cmd); int UpdateDB(const char *file, int line, JCR *jcr, B_DB *db, char *update_cmd); void split_path_and_file(JCR *jcr, B_DB *mdb, const char *fname); -#endif /* __SQL_H_ */ +#endif /* __CATS_H_ */