summaryrefslogtreecommitdiff
path: root/sql/vtmd.h
blob: d77ed117248866ef2fb97f5f9af5ce88620e0192 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#ifndef VTMD_INCLUDED
#define VTMD_INCLUDED

#include <mysqld_error.h>

#include "mariadb.h"
#include "sql_priv.h"

#include "my_sys.h"
#include "table.h"
#include "unireg.h"

#include "vers_utils.h"

class key_buf_t
{
  uchar* buf;

  key_buf_t(const key_buf_t&); // disabled
  key_buf_t& operator= (const key_buf_t&); // disabled

public:
  key_buf_t() : buf(NULL)
  {}

  ~key_buf_t()
  {
    if (buf)
      my_free(buf);
  }

  bool allocate(size_t alloc_size)
  {
    DBUG_ASSERT(!buf);
    buf= static_cast<uchar *>(my_malloc(alloc_size, MYF(0)));
    if (!buf)
    {
      my_message(ER_VERS_VTMD_ERROR, "failed to allocate key buffer", MYF(0));
      return true;
    }
    return false;
  }

  operator uchar* ()
  {
    DBUG_ASSERT(buf);
    return reinterpret_cast<uchar *>(buf);
  }
};

class THD;

class VTMD_table
{
  Open_tables_backup open_tables_backup;

protected:
  TABLE_LIST vtmd;
  TABLE_LIST &about;
  SString_t vtmd_name;

private:
  VTMD_table(const VTMD_table&); // prohibit copying references

public:
  enum {
    FLD_START= 0,
    FLD_END,
    FLD_NAME,
    FLD_ARCHIVE_NAME,
    FLD_COL_RENAMES,
    FIELD_COUNT
  };

  enum {
    IDX_TRX_END= 0,
    IDX_ARCHIVE_NAME
  };

  VTMD_table(TABLE_LIST &_about) :
    about(_about)
  {
    vtmd.table= NULL;
  }

  bool create(THD *thd);
  bool find_record(ulonglong sys_trx_end, bool &found);
  bool open(THD *thd, Local_da &local_da, bool *created= NULL);
  bool update(THD *thd, const char* archive_name= NULL);
  bool setup_select(THD *thd);

  static void archive_name(THD *thd, const char *table_name, char *new_name, size_t new_name_size);
  void archive_name(THD *thd, char *new_name, size_t new_name_size)
  {
    archive_name(thd, about.table_name, new_name, new_name_size);
  }

  bool find_archive_name(THD *thd, String &out);
  static bool get_archive_tables(THD *thd, const char *db, size_t db_length,
                                 Dynamic_array<String> &result);
};

class VTMD_exists : public VTMD_table
{
protected:
  handlerton *hton;

public:
  bool exists;

public:
  VTMD_exists(TABLE_LIST &_about) :
    VTMD_table(_about),
    hton(NULL),
    exists(false)
  {}

  bool check_exists(THD *thd); // returns error status
};

class VTMD_rename : public VTMD_exists
{
  SString_t vtmd_new_name;

public:
  VTMD_rename(TABLE_LIST &_about) :
    VTMD_exists(_about)
  {}

  bool try_rename(THD *thd, LString new_db, LString new_alias, const char* archive_name= NULL);
  bool revert_rename(THD *thd, LString new_db);

private:
  bool move_archives(THD *thd, LString &new_db);
  bool move_table(THD *thd, SString_fs &table_name, LString &new_db);
};

class VTMD_drop : public VTMD_exists
{
  char archive_name_[NAME_CHAR_LEN];

public:
  VTMD_drop(TABLE_LIST &_about) :
    VTMD_exists(_about)
  {
    *archive_name_= 0;
  }

  const char* archive_name(THD *thd)
  {
    VTMD_table::archive_name(thd, archive_name_, sizeof(archive_name_));
    return archive_name_;
  }

  const char* archive_name() const
  {
    DBUG_ASSERT(*archive_name_);
    return archive_name_;
  }

  bool update(THD *thd)
  {
    DBUG_ASSERT(*archive_name_);
    return VTMD_exists::update(thd, archive_name_);
  }
};


inline
bool
VTMD_exists::check_exists(THD *thd)
{
  if (about.vers_vtmd_name(vtmd_name))
    return true;

  exists= ha_table_exists(thd, about.db, vtmd_name, &hton);

  if (exists && !hton)
  {
    my_printf_error(ER_VERS_VTMD_ERROR, "`%s.%s` handlerton empty!", MYF(0),
                        about.db, vtmd_name.ptr());
    return true;
  }
  return false;
}

#endif // VTMD_INCLUDED