/* Copyright (c) 2012, 2019, 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, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. 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, version 2.0, 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 #include "my_inttypes.h" #include "mysql_com.h" /* NAME_CHAR_LEN */ #include "storage/ndb/include/ndbapi/NdbApi.hpp" /* 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, 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; }; #endif