Class: Innodb::DataDictionary
- Inherits:
-
Object
- Object
- Innodb::DataDictionary
- Defined in:
- lib/innodb/data_dictionary.rb
Defined Under Namespace
Classes: MysqlType, SysColumnsPrimary, SysFieldsPrimary, SysIndexesPrimary, SysTablesId, SysTablesPrimary
Constant Summary collapse
- DATA_DICTIONARY_RECORD_DESCRIBERS =
A hash of hashes of table name and index name to describer class.
{ SYS_TABLES: { PRIMARY: SysTablesPrimary, ID: SysTablesId, }.freeze, SYS_COLUMNS: { PRIMARY: SysColumnsPrimary }.freeze, SYS_INDEXES: { PRIMARY: SysIndexesPrimary }.freeze, SYS_FIELDS: { PRIMARY: SysFieldsPrimary }.freeze, }.freeze
- MYSQL_TYPE =
A hash of MySQL’s internal type system to the stored values for those types, and the ‘external’ SQL type. rubocop:disable Layout/HashAlignment rubocop:disable Layout/CommentIndentation
{ # DECIMAL: MysqlType.new(value: 0, type: :DECIMAL), TINY: MysqlType.new(value: 1, type: :TINYINT), SHORT: MysqlType.new(value: 2, type: :SMALLINT), LONG: MysqlType.new(value: 3, type: :INT), FLOAT: MysqlType.new(value: 4, type: :FLOAT), DOUBLE: MysqlType.new(value: 5, type: :DOUBLE), # NULL: MysqlType.new(value: 6, type: nil), TIMESTAMP: MysqlType.new(value: 7, type: :TIMESTAMP), LONGLONG: MysqlType.new(value: 8, type: :BIGINT), INT24: MysqlType.new(value: 9, type: :MEDIUMINT), # DATE: MysqlType.new(value: 10, type: :DATE), TIME: MysqlType.new(value: 11, type: :TIME), DATETIME: MysqlType.new(value: 12, type: :DATETIME), YEAR: MysqlType.new(value: 13, type: :YEAR), NEWDATE: MysqlType.new(value: 14, type: :DATE), VARCHAR: MysqlType.new(value: 15, type: :VARCHAR), BIT: MysqlType.new(value: 16, type: :BIT), NEWDECIMAL: MysqlType.new(value: 246, type: :CHAR), # ENUM: MysqlType.new(value: 247, type: :ENUM), # SET: MysqlType.new(value: 248, type: :SET), TINY_BLOB: MysqlType.new(value: 249, type: :TINYBLOB), MEDIUM_BLOB: MysqlType.new(value: 250, type: :MEDIUMBLOB), LONG_BLOB: MysqlType.new(value: 251, type: :LONGBLOB), BLOB: MysqlType.new(value: 252, type: :BLOB), # VAR_STRING: MysqlType.new(value: 253, type: :VARCHAR), STRING: MysqlType.new(value: 254, type: :CHAR), GEOMETRY: MysqlType.new(value: 255, type: :GEOMETRY), }.freeze
- MYSQL_TYPE_BY_VALUE =
A hash of MYSQL_TYPE keys by value :value key.
MYSQL_TYPE.transform_values(&:value).invert.freeze
- COLUMN_MTYPE =
A hash of InnoDB’s internal type system to the values stored for each type.
{ VARCHAR: 1, CHAR: 2, FIXBINARY: 3, BINARY: 4, BLOB: 5, INT: 6, SYS_CHILD: 7, SYS: 8, FLOAT: 9, DOUBLE: 10, DECIMAL: 11, VARMYSQL: 12, MYSQL: 13, }.freeze
- COLUMN_MTYPE_BY_VALUE =
A hash of COLUMN_MTYPE keys by value.
COLUMN_MTYPE.invert.freeze
- COLUMN_PRTYPE_FLAG =
A hash of InnoDB ‘precise type’ bitwise flags.
{ NOT_NULL: 256, UNSIGNED: 512, BINARY: 1024, LONG_TRUE_VARCHAR: 4096, }.freeze
- COLUMN_PRTYPE_FLAG_BY_VALUE =
A hash of COLUMN_PRTYPE keys by value.
COLUMN_PRTYPE_FLAG.invert.freeze
- COLUMN_PRTYPE_MYSQL_TYPE_MASK =
The bitmask to extract the MySQL internal type from the InnoDB ‘precise type’.
0xFF
- INDEX_TYPE_FLAG =
A hash of InnoDB’s index type flags.
{ CLUSTERED: 1, UNIQUE: 2, UNIVERSAL: 4, IBUF: 8, CORRUPT: 16, FTS: 32, }.freeze
- INDEX_TYPE_FLAG_BY_VALUE =
A hash of INDEX_TYPE_FLAG keys by value.
INDEX_TYPE_FLAG.invert.freeze
Instance Attribute Summary collapse
-
#system_space ⇒ Object
readonly
Returns the value of attribute system_space.
Class Method Summary collapse
-
.mtype_prtype_to_data_type(mtype, prtype, len, prec) ⇒ Object
Return a full data type given an mtype and prtype, such as [‘VARCHAR(10)’, :NOT_NULL] or [:INT, :UNSIGNED].
-
.mtype_prtype_to_type_string(mtype, prtype, len, prec) ⇒ Object
Return the ‘external’ SQL type string (such as ‘VARCHAR’ or ‘INT’) given the stored mtype and prtype from the InnoDB data dictionary.
Instance Method Summary collapse
-
#_make_column_description(type, record) ⇒ Object
Produce a Innodb::RecordDescriber-compatible column description given a type (:key, :row) and data dictionary SYS_COLUMNS record.
-
#clustered_index_name_by_table_name(table_name) ⇒ Object
Return the name of the clustered index (usually ‘PRIMARY’, but not always) for a given table name.
-
#column_by_name(table_name, column_name) ⇒ Object
Lookup a column by table name and column name.
-
#data_dictionary_index(table_name, index_name) ⇒ Object
Return an Innodb::Index object initialized to the internal data dictionary index with an appropriate record describer so that records can be recursed.
- #data_dictionary_index?(table_name, index_name) ⇒ Boolean
- #data_dictionary_index_describer(table_name, index_name) ⇒ Object
- #data_dictionary_index_ids ⇒ Object
-
#data_dictionary_indexes ⇒ Object
A helper method to reach inside the system space and retrieve the data dictionary index locations from the data dictionary header.
- #data_dictionary_table?(table_name) ⇒ Boolean
-
#each_column ⇒ Object
Iterate through the records in the SYS_COLUMNS data dictionary table.
-
#each_column_by_table_id(table_id) ⇒ Object
Iterate through all columns in a table by table ID.
-
#each_column_by_table_name(table_name, &block) ⇒ Object
Iterate through all columns in a table by table name.
-
#each_column_description_by_index_name(table_name, index_name) ⇒ Object
Iterate through Innodb::RecordDescriber-compatible column descriptions for a given index by table name and index name.
-
#each_column_in_index_by_name(table_name, index_name) ⇒ Object
Iterate through all columns in an index by table name and index name.
-
#each_column_not_in_index_by_name(table_name, index_name) ⇒ Object
Iterate through all columns not in an index by table name and index name.
-
#each_data_dictionary_index ⇒ Object
Iterate through all data dictionary indexes, yielding the table name, index name, and the index itself as an Innodb::Index.
-
#each_data_dictionary_index_root_page_number ⇒ Object
Iterate through all data dictionary indexes, yielding the table name, index name, and root page number.
-
#each_field ⇒ Object
Iterate through the records in the SYS_FIELDS data dictionary table.
-
#each_field_by_index_id(index_id) ⇒ Object
Iterate through all fields in an index by index ID.
-
#each_field_by_index_name(table_name, index_name, &block) ⇒ Object
Iterate through all fields in an index by index name.
-
#each_index ⇒ Object
Iterate through the records in the SYS_INDEXES dictionary table.
-
#each_index_by_space_id(space_id) ⇒ Object
Iterate through indexes by space ID.
-
#each_index_by_table_id(table_id) ⇒ Object
Iterate through all indexes in a table by table ID.
-
#each_index_by_table_name(table_name, &block) ⇒ Object
Iterate through all indexes in a table by table name.
-
#each_record_from_data_dictionary_index(table, index, &block) ⇒ Object
Iterate through records from a data dictionary index yielding each record as a Innodb::Record object.
-
#each_table ⇒ Object
Iterate through the records in the SYS_TABLES data dictionary table.
-
#found? ⇒ Boolean
Check if the data dictionary indexes are all available.
-
#index_by_id(index_id) ⇒ Object
Lookup an index by index ID.
-
#index_by_name(table_name, index_name) ⇒ Object
Lookup an index by table name and index name.
-
#initialize(system_space) ⇒ DataDictionary
constructor
A new instance of DataDictionary.
-
#object_by_field(method, field, value) ⇒ Object
A helper to iterate the method provided and return the first record where the record’s field matches the provided value.
-
#object_by_two_fields(method, field1, value1, field2, value2) ⇒ Object
A helper to iterate the method provided and return the first record where the record’s fields f1 and f2 match the provided values v1 and v2.
-
#record_describer_by_index_id(index_id) ⇒ Object
Return an Innodb::RecordDescriber object describing the records in a given index by index ID.
-
#record_describer_by_index_name(table_name, index_name) ⇒ Object
Return an Innodb::RecordDescriber object describing records for a given index by table name and index name.
-
#table_by_id(table_id) ⇒ Object
Lookup a table by table ID.
-
#table_by_name(table_name) ⇒ Object
Lookup a table by table name.
-
#table_by_space_id(space_id) ⇒ Object
Lookup a table by space ID.
Constructor Details
#initialize(system_space) ⇒ DataDictionary
Returns a new instance of DataDictionary.
227 228 229 |
# File 'lib/innodb/data_dictionary.rb', line 227 def initialize(system_space) @system_space = system_space end |
Instance Attribute Details
#system_space ⇒ Object (readonly)
Returns the value of attribute system_space.
225 226 227 |
# File 'lib/innodb/data_dictionary.rb', line 225 def system_space @system_space end |
Class Method Details
.mtype_prtype_to_data_type(mtype, prtype, len, prec) ⇒ Object
Return a full data type given an mtype and prtype, such as [‘VARCHAR(10)’, :NOT_NULL] or [:INT, :UNSIGNED].
214 215 216 217 218 219 220 221 222 223 |
# File 'lib/innodb/data_dictionary.rb', line 214 def self.mtype_prtype_to_data_type(mtype, prtype, len, prec) type = mtype_prtype_to_type_string(mtype, prtype, len, prec) raise "Unsupported type (mtype #{mtype}, prtype #{prtype})" unless type data_type = [type] data_type << :NOT_NULL if prtype & COLUMN_PRTYPE_FLAG[:NOT_NULL] != 0 data_type << :UNSIGNED if prtype & COLUMN_PRTYPE_FLAG[:UNSIGNED] != 0 data_type end |
.mtype_prtype_to_type_string(mtype, prtype, len, prec) ⇒ Object
Return the ‘external’ SQL type string (such as ‘VARCHAR’ or ‘INT’) given the stored mtype and prtype from the InnoDB data dictionary. Note that not all types are extractable into fully defined SQL types due to the lossy nature of the MySQL-to-InnoDB interface regarding types.
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/innodb/data_dictionary.rb', line 174 def self.mtype_prtype_to_type_string(mtype, prtype, len, prec) mysql_type = prtype & COLUMN_PRTYPE_MYSQL_TYPE_MASK internal_type = MYSQL_TYPE_BY_VALUE[mysql_type] external_type = MYSQL_TYPE[internal_type].type case external_type when :VARCHAR # One-argument: length. "%s(%i)" % [external_type, len] when :FLOAT, :DOUBLE # Two-argument: length and precision. "%s(%i,%i)" % [external_type, len, prec] when :CHAR if COLUMN_MTYPE_BY_VALUE[mtype] == :MYSQL # When the mtype is :MYSQL, the column is actually # stored as VARCHAR despite being a CHAR. This is # done for CHAR columns having multi-byte character # sets in order to limit size. Note that such data # are still space-padded to at least len. "VARCHAR(%i)" % [len] else "CHAR(%i)" % [len] end when :DECIMAL # The DECIMAL type is designated as DECIMAL(M,D) # however the M and D definitions are not stored # in the InnoDB data dictionary. We need to define # the column as something which will extract the # raw bytes in order to read the column, but we # can't figure out the right decimal type. The # len stored here is actually the on-disk storage # size. "CHAR(%i)" % [len] else external_type end end |
Instance Method Details
#_make_column_description(type, record) ⇒ Object
Produce a Innodb::RecordDescriber-compatible column description given a type (:key, :row) and data dictionary SYS_COLUMNS record.
548 549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/innodb/data_dictionary.rb', line 548 def _make_column_description(type, record) { type: type, name: record["NAME"], description: self.class.mtype_prtype_to_data_type( record["MTYPE"], record["PRTYPE"], record["LEN"], record["PREC"] ), } end |
#clustered_index_name_by_table_name(table_name) ⇒ Object
Return the name of the clustered index (usually ‘PRIMARY’, but not always) for a given table name.
538 539 540 541 542 543 544 |
# File 'lib/innodb/data_dictionary.rb', line 538 def clustered_index_name_by_table_name(table_name) table_record = table_by_name(table_name) raise "Table #{table_name} not found" unless table_record index_record = object_by_two_fields(:each_index, "TABLE_ID", table_record["ID"], "TYPE", 3) index_record["NAME"] if index_record end |
#column_by_name(table_name, column_name) ⇒ Object
Lookup a column by table name and column name.
410 411 412 413 414 415 |
# File 'lib/innodb/data_dictionary.rb', line 410 def column_by_name(table_name, column_name) table = table_by_name(table_name) return unless table object_by_two_fields(:each_column, "TABLE_ID", table["ID"], "NAME", column_name) end |
#data_dictionary_index(table_name, index_name) ⇒ Object
Return an Innodb::Index object initialized to the internal data dictionary index with an appropriate record describer so that records can be recursed.
284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/innodb/data_dictionary.rb', line 284 def data_dictionary_index(table_name, index_name) raise "Data Dictionary not found; is the MySQL version supported?" unless found? table_entry = data_dictionary_indexes[table_name] raise "Unknown data dictionary table #{table_name}" unless table_entry index_root_page = table_entry[index_name] raise "Unknown data dictionary index #{table_name}.#{index_name}" unless index_root_page # If we have a record describer for this index, load it. record_describer = data_dictionary_index_describer(table_name, index_name) system_space.index(index_root_page, record_describer) end |
#data_dictionary_index?(table_name, index_name) ⇒ Boolean
269 270 271 272 273 |
# File 'lib/innodb/data_dictionary.rb', line 269 def data_dictionary_index?(table_name, index_name) return false unless data_dictionary_table?(table_name) DATA_DICTIONARY_RECORD_DESCRIBERS[table_name.to_sym].include?(index_name.to_sym) end |
#data_dictionary_index_describer(table_name, index_name) ⇒ Object
275 276 277 278 279 |
# File 'lib/innodb/data_dictionary.rb', line 275 def data_dictionary_index_describer(table_name, index_name) return unless data_dictionary_index?(table_name, index_name) DATA_DICTIONARY_RECORD_DESCRIBERS[table_name.to_sym][index_name.to_sym].new end |
#data_dictionary_index_ids ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/innodb/data_dictionary.rb', line 243 def data_dictionary_index_ids raise "Data Dictionary not found; is the MySQL version supported?" unless found? return @data_dictionary_index_ids if @data_dictionary_index_ids # TODO: This could probably be done a lot more Ruby-like. @data_dictionary_index_ids = {} data_dictionary_indexes.each do |table, indexes| indexes.each do |index, root_page_number| root_page = system_space.page(root_page_number) next unless root_page @data_dictionary_index_ids[root_page.index_id] = { table: table, index: index, } end end @data_dictionary_index_ids end |
#data_dictionary_indexes ⇒ Object
A helper method to reach inside the system space and retrieve the data dictionary index locations from the data dictionary header.
234 235 236 |
# File 'lib/innodb/data_dictionary.rb', line 234 def data_dictionary_indexes system_space.data_dictionary_page.data_dictionary_header[:indexes] end |
#data_dictionary_table?(table_name) ⇒ Boolean
265 266 267 |
# File 'lib/innodb/data_dictionary.rb', line 265 def data_dictionary_table?(table_name) DATA_DICTIONARY_RECORD_DESCRIBERS.include?(table_name.to_sym) end |
#each_column ⇒ Object
Iterate through the records in the SYS_COLUMNS data dictionary table.
350 351 352 353 354 355 356 357 358 |
# File 'lib/innodb/data_dictionary.rb', line 350 def each_column return enum_for(:each_column) unless block_given? each_record_from_data_dictionary_index(:SYS_COLUMNS, :PRIMARY) do |record| yield record.fields end nil end |
#each_column_by_table_id(table_id) ⇒ Object
Iterate through all columns in a table by table ID.
488 489 490 491 492 493 494 495 496 |
# File 'lib/innodb/data_dictionary.rb', line 488 def each_column_by_table_id(table_id) return enum_for(:each_column_by_table_id, table_id) unless block_given? each_column do |record| yield record if record["TABLE_ID"] == table_id end nil end |
#each_column_by_table_name(table_name, &block) ⇒ Object
Iterate through all columns in a table by table name.
499 500 501 502 503 504 505 506 |
# File 'lib/innodb/data_dictionary.rb', line 499 def each_column_by_table_name(table_name, &block) return enum_for(:each_column_by_table_name, table_name) unless block_given? raise "Table #{table_name} not found" unless (table = table_by_name(table_name)) each_column_by_table_id(table["ID"], &block) nil end |
#each_column_description_by_index_name(table_name, index_name) ⇒ Object
Iterate through Innodb::RecordDescriber-compatible column descriptions for a given index by table name and index name.
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
# File 'lib/innodb/data_dictionary.rb', line 563 def each_column_description_by_index_name(table_name, index_name) return enum_for(:each_column_description_by_index_name, table_name, index_name) unless block_given? unless (index = index_by_name(table_name, index_name)) raise "Index #{index_name} for table #{table_name} not found" end columns_in_index = {} each_column_in_index_by_name(table_name, index_name) do |record| columns_in_index[record["NAME"]] = 1 yield _make_column_description(:key, record) end if (index["TYPE"] & INDEX_TYPE_FLAG[:CLUSTERED]).zero? clustered_index_name = clustered_index_name_by_table_name(table_name) each_column_in_index_by_name(table_name, clustered_index_name) do |record| yield _make_column_description(:row, record) end else each_column_by_table_name(table_name) do |record| yield _make_column_description(:row, record) unless columns_in_index.include?(record["NAME"]) end end nil end |
#each_column_in_index_by_name(table_name, index_name) ⇒ Object
Iterate through all columns in an index by table name and index name.
509 510 511 512 513 514 515 516 517 |
# File 'lib/innodb/data_dictionary.rb', line 509 def each_column_in_index_by_name(table_name, index_name) return enum_for(:each_column_in_index_by_name, table_name, index_name) unless block_given? each_field_by_index_name(table_name, index_name) do |record| yield column_by_name(table_name, record["COL_NAME"]) end nil end |
#each_column_not_in_index_by_name(table_name, index_name) ⇒ Object
Iterate through all columns not in an index by table name and index name. This is useful when building index descriptions for secondary indexes.
521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
# File 'lib/innodb/data_dictionary.rb', line 521 def each_column_not_in_index_by_name(table_name, index_name) return enum_for(:each_column_not_in_index_by_name, table_name, index_name) unless block_given? columns_in_index = {} each_column_in_index_by_name(table_name, index_name) do |record| columns_in_index[record["NAME"]] = 1 end each_column_by_table_name(table_name) do |record| yield record unless columns_in_index.include?(record["NAME"]) end nil end |
#each_data_dictionary_index ⇒ Object
Iterate through all data dictionary indexes, yielding the table name, index name, and the index itself as an Innodb::Index.
315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/innodb/data_dictionary.rb', line 315 def each_data_dictionary_index return enum_for(:each_data_dictionary_index) unless block_given? data_dictionary_indexes.each do |table_name, indexes| indexes.each_key do |index_name| yield table_name, index_name, data_dictionary_index(table_name, index_name) end end nil end |
#each_data_dictionary_index_root_page_number ⇒ Object
Iterate through all data dictionary indexes, yielding the table name, index name, and root page number.
301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/innodb/data_dictionary.rb', line 301 def each_data_dictionary_index_root_page_number return enum_for(:each_data_dictionary_index_root_page_number) unless block_given? data_dictionary_indexes.each do |table_name, indexes| indexes.each do |index_name, root_page_number| yield table_name, index_name, root_page_number end end nil end |
#each_field ⇒ Object
Iterate through the records in the SYS_FIELDS data dictionary table.
372 373 374 375 376 377 378 379 380 |
# File 'lib/innodb/data_dictionary.rb', line 372 def each_field return enum_for(:each_field) unless block_given? each_record_from_data_dictionary_index(:SYS_FIELDS, :PRIMARY) do |record| yield record.fields end nil end |
#each_field_by_index_id(index_id) ⇒ Object
Iterate through all fields in an index by index ID.
465 466 467 468 469 470 471 472 473 |
# File 'lib/innodb/data_dictionary.rb', line 465 def each_field_by_index_id(index_id) return enum_for(:each_field_by_index_id, index_id) unless block_given? each_field do |record| yield record if record["INDEX_ID"] == index_id end nil end |
#each_field_by_index_name(table_name, index_name, &block) ⇒ Object
Iterate through all fields in an index by index name.
476 477 478 479 480 481 482 483 484 485 |
# File 'lib/innodb/data_dictionary.rb', line 476 def each_field_by_index_name(table_name, index_name, &block) return enum_for(:each_field_by_index_name, table_name, index_name) unless block_given? index = index_by_name(table_name, index_name) raise "Index #{index_name} for table #{table_name} not found" unless index each_field_by_index_id(index["ID"], &block) nil end |
#each_index ⇒ Object
Iterate through the records in the SYS_INDEXES dictionary table.
361 362 363 364 365 366 367 368 369 |
# File 'lib/innodb/data_dictionary.rb', line 361 def each_index return enum_for(:each_index) unless block_given? each_record_from_data_dictionary_index(:SYS_INDEXES, :PRIMARY) do |record| yield record.fields end nil end |
#each_index_by_space_id(space_id) ⇒ Object
Iterate through indexes by space ID.
431 432 433 434 435 436 437 438 439 |
# File 'lib/innodb/data_dictionary.rb', line 431 def each_index_by_space_id(space_id) return enum_for(:each_index_by_space_id, space_id) unless block_given? each_index do |record| yield record if record["SPACE"] == space_id end nil end |
#each_index_by_table_id(table_id) ⇒ Object
Iterate through all indexes in a table by table ID.
442 443 444 445 446 447 448 449 450 |
# File 'lib/innodb/data_dictionary.rb', line 442 def each_index_by_table_id(table_id) return enum_for(:each_index_by_table_id, table_id) unless block_given? each_index do |record| yield record if record["TABLE_ID"] == table_id end nil end |
#each_index_by_table_name(table_name, &block) ⇒ Object
Iterate through all indexes in a table by table name.
453 454 455 456 457 458 459 460 461 462 |
# File 'lib/innodb/data_dictionary.rb', line 453 def each_index_by_table_name(table_name, &block) return enum_for(:each_index_by_table_name, table_name) unless block_given? table = table_by_name(table_name) raise "Table #{table_name} not found" unless table each_index_by_table_id(table["ID"], &block) nil end |
#each_record_from_data_dictionary_index(table, index, &block) ⇒ Object
Iterate through records from a data dictionary index yielding each record as a Innodb::Record object.
330 331 332 333 334 335 336 |
# File 'lib/innodb/data_dictionary.rb', line 330 def each_record_from_data_dictionary_index(table, index, &block) return enum_for(:each_record_from_data_dictionary_index, table, index) unless block_given? data_dictionary_index(table, index).each_record(&block) nil end |
#each_table ⇒ Object
Iterate through the records in the SYS_TABLES data dictionary table.
339 340 341 342 343 344 345 346 347 |
# File 'lib/innodb/data_dictionary.rb', line 339 def each_table return enum_for(:each_table) unless block_given? each_record_from_data_dictionary_index(:SYS_TABLES, :PRIMARY) do |record| yield record.fields end nil end |
#found? ⇒ Boolean
Check if the data dictionary indexes are all available.
239 240 241 |
# File 'lib/innodb/data_dictionary.rb', line 239 def found? data_dictionary_indexes.values.map(&:values).flatten.none?(&:zero?) end |
#index_by_id(index_id) ⇒ Object
Lookup an index by index ID.
418 419 420 |
# File 'lib/innodb/data_dictionary.rb', line 418 def index_by_id(index_id) object_by_field(:each_index, "ID", index_id) end |
#index_by_name(table_name, index_name) ⇒ Object
Lookup an index by table name and index name.
423 424 425 426 427 428 |
# File 'lib/innodb/data_dictionary.rb', line 423 def index_by_name(table_name, index_name) table = table_by_name(table_name) return unless table object_by_two_fields(:each_index, "TABLE_ID", table["ID"], "NAME", index_name) end |
#object_by_field(method, field, value) ⇒ Object
A helper to iterate the method provided and return the first record where the record’s field matches the provided value.
384 385 386 |
# File 'lib/innodb/data_dictionary.rb', line 384 def object_by_field(method, field, value) send(method).select { |o| o[field] == value }.first end |
#object_by_two_fields(method, field1, value1, field2, value2) ⇒ Object
A helper to iterate the method provided and return the first record where the record’s fields f1 and f2 match the provided values v1 and v2.
390 391 392 |
# File 'lib/innodb/data_dictionary.rb', line 390 def object_by_two_fields(method, field1, value1, field2, value2) send(method).select { |o| o[field1] == value1 && o[field2] == value2 }.first end |
#record_describer_by_index_id(index_id) ⇒ Object
Return an Innodb::RecordDescriber object describing the records in a given index by index ID.
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
# File 'lib/innodb/data_dictionary.rb', line 622 def record_describer_by_index_id(index_id) if (dd_index = data_dictionary_index_ids[index_id]) return data_dictionary_index_describer(dd_index[:table], dd_index[:index]) end unless (index = index_by_id(index_id)) raise "Index #{index_id} not found" end unless (table = table_by_id(index["TABLE_ID"])) raise "Table #{INDEX['TABLE_ID']} not found" end record_describer_by_index_name(table["NAME"], index["NAME"]) end |
#record_describer_by_index_name(table_name, index_name) ⇒ Object
Return an Innodb::RecordDescriber object describing records for a given index by table name and index name.
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 |
# File 'lib/innodb/data_dictionary.rb', line 593 def record_describer_by_index_name(table_name, index_name) return data_dictionary_index_describer(table_name, index_name) if data_dictionary_index?(table_name, index_name) unless (index = index_by_name(table_name, index_name)) raise "Index #{index_name} for table #{table_name} not found" end describer = Innodb::RecordDescriber.new if (index["TYPE"] & INDEX_TYPE_FLAG[:CLUSTERED]).zero? describer.type :secondary else describer.type :clustered end each_column_description_by_index_name(table_name, index_name) do |column| case column[:type] when :key describer.key column[:name], *column[:description] when :row describer.row column[:name], *column[:description] end end describer end |
#table_by_id(table_id) ⇒ Object
Lookup a table by table ID.
395 396 397 |
# File 'lib/innodb/data_dictionary.rb', line 395 def table_by_id(table_id) object_by_field(:each_table, "ID", table_id) end |
#table_by_name(table_name) ⇒ Object
Lookup a table by table name.
400 401 402 |
# File 'lib/innodb/data_dictionary.rb', line 400 def table_by_name(table_name) object_by_field(:each_table, "NAME", table_name) end |
#table_by_space_id(space_id) ⇒ Object
Lookup a table by space ID.
405 406 407 |
# File 'lib/innodb/data_dictionary.rb', line 405 def table_by_space_id(space_id) object_by_field(:each_table, "SPACE", space_id) end |