/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 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 along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NDB_REPL_TAB_H #define NDB_REPL_TAB_H #include #ifdef HAVE_NDB_BINLOG #include /* NAME_CHAR_LEN */ #include /* Ndb_rep_tab_key This class represents the key columns of the mysql.ndb_replication system table It is used when reading values from that table */ class Ndb_rep_tab_key { public: static const uint DB_MAXLEN= NAME_CHAR_LEN - 1; static const uint TABNAME_MAXLEN= NAME_CHAR_LEN - 1; /* Char arrays in varchar format with 1 length byte and * trailing 0 */ char db[ DB_MAXLEN + 2 ]; char table_name[ TABNAME_MAXLEN + 2 ]; uint server_id; Ndb_rep_tab_key() { db[0] = 0; table_name[0] = 0; server_id = 0; } /* Constructor from normal null terminated strings */ Ndb_rep_tab_key(const char* _db, const char* _table_name, uint _server_id); /* Add null terminators to VARCHAR format string values */ void null_terminate_strings(); const char* get_db() const { return &db[1]; }; const char* get_table_name() const { return &table_name[1]; }; static const int MIN_MATCH_VAL = 1; static const int EXACT_MATCH_DB = 4; static const int EXACT_MATCH_TABLE_NAME = 2; static const int EXACT_MATCH_SERVER_ID = 1; static const int EXACT_MATCH_QUALITY = MIN_MATCH_VAL + EXACT_MATCH_DB + EXACT_MATCH_TABLE_NAME + EXACT_MATCH_SERVER_ID; /* This static method attempts an exact, then a wild match between the passed key (with optional wild characters), and the passed candidate row returns : 1 : Exact match 0 : Wild match -1 : No match */ static int attempt_match(const char* keyptr, const uint keylen, const char* candidateptr, const uint candidatelen, const int exactmatchvalue); /* This static method compares a fixed key value with * a possibly wildcard containing candidate_row. * If there is no match, 0 is returned. * >0 means there is a match, with larger numbers * indicating a better match quality. * An exact match returns EXACT_MATCH_QUALITY */ static int get_match_quality(const Ndb_rep_tab_key* key, const Ndb_rep_tab_key* candidate_row); }; /* Ndb_rep_tab_row This class represents a row in the mysql.ndb_replication table */ class Ndb_rep_tab_row { public: static const uint MAX_CONFLICT_FN_SPEC_LEN = 255; static const uint CONFLICT_FN_SPEC_BUF_LEN = MAX_CONFLICT_FN_SPEC_LEN + 1; /* Trailing '\0' */ Ndb_rep_tab_key key; uint binlog_type; bool cfs_is_null; /* Buffer has space for leading length byte */ char conflict_fn_spec[ CONFLICT_FN_SPEC_BUF_LEN + 1 ]; Ndb_rep_tab_row(); void null_terminate_strings() { key.null_terminate_strings(); uint speclen= 0; speclen = conflict_fn_spec[0]; assert(speclen <= MAX_CONFLICT_FN_SPEC_LEN); conflict_fn_spec[1 + speclen] = '\0'; } const char* get_conflict_fn_spec() { return &conflict_fn_spec[1]; } void set_conflict_fn_spec_null(bool null) { if (null) { cfs_is_null = true; conflict_fn_spec[0] = 0; conflict_fn_spec[1] = 0; } else { cfs_is_null = false; } } }; /** Ndb_rep_tab_reader A helper class for accessing the mysql.ndb_replication table */ class Ndb_rep_tab_reader { private: static const char *ndb_rep_db; static const char *ndb_replication_table; static const char *nrt_db; static const char *nrt_table_name; static const char *nrt_server_id; static const char *nrt_binlog_type; static const char *nrt_conflict_fn; Uint32 binlog_flags; char conflict_fn_buffer[ Ndb_rep_tab_row::CONFLICT_FN_SPEC_BUF_LEN ]; char warning_msg_buffer[ FN_REFLEN ]; const char* conflict_fn_spec; const char* warning_msg; /** check_schema Checks that the schema of the mysql.ndb_replication table is acceptable. Returns 0 if ok -1 if a column has an error. Col name in error_str -2 if there's a more general error. Error description in error_str */ static int check_schema(const NdbDictionary::Table* reptab, NdbDictionary::Dictionary* dict, const char** error_str); /** scan_candidates Scans the ndb_replication table for rows matching the passed db, table_name, server_id triple. Returns the quality of the match made. -1 = Error in processing, see msg 0 = No match, use defaults. >0 = Use data in best_match if msg is set on return it contains a warning. Warnings may be produces in non error scenarios */ int scan_candidates(Ndb* ndb, const NdbDictionary::Table* reptab, const char* db, const char* table_name, uint server_id, Ndb_rep_tab_row& best_match); public: Ndb_rep_tab_reader(); ~Ndb_rep_tab_reader() {}; /** lookup lookup scans the mysql.ndb_replication table for the best matching entry for the supplied db, table_name, server_id triple. A buffer for the conflict_fn spec, and for any error or warning messages must be supplied. The passed binlog_flags, conflict_fn_spec and message may be updated as a result Returns : 0 : Success. <0 : Error. */ int lookup(Ndb* ndb, /* Keys */ const char* db, const char* table_name, uint server_id); /* Following only valid after a call to lookup() */ Uint32 get_binlog_flags() const; const char* get_conflict_fn_spec() const; const char* get_warning_message() const; }; /* #ifdef HAVE_NDB_BINLOG */ #endif /* #ifdef NDB_REPL_TAB_H */ #endif