Class: DynamicMigrations::Postgres::Server::Database::Schema::Table
- Inherits:
-
DynamicMigrations::Postgres::Server::Database::Source
- Object
- DynamicMigrations::Postgres::Server::Database::Source
- DynamicMigrations::Postgres::Server::Database::Schema::Table
- Includes:
- Columns, ForeignKeyConstraints, Indexes, Triggers, UniqueConstraints, Validations
- Defined in:
- lib/dynamic_migrations/postgres/server/database/schema/table.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/index.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/column.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/columns.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/indexes.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/trigger.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/triggers.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/validation.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/primary_key.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/validations.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/unique_constraint.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/unique_constraints.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraint.rb,
lib/dynamic_migrations/postgres/server/database/schema/table/foreign_key_constraints.rb
Overview
This class represents a postgres table.
Defined Under Namespace
Modules: Columns, ForeignKeyConstraints, Indexes, Triggers, UniqueConstraints, Validations Classes: Column, ExpectedSchemaError, ForeignKeyConstraint, Index, MissingExtensionError, PrimaryKey, PrimaryKeyAlreadyExistsError, PrimaryKeyDoesNotExistError, Trigger, UniqueConstraint, Validation
Instance Attribute Summary collapse
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#remote_foreign_key_constraints ⇒ Object
readonly
Returns the value of attribute remote_foreign_key_constraints.
-
#schema ⇒ Object
readonly
Returns the value of attribute schema.
Attributes inherited from DynamicMigrations::Postgres::Server::Database::Source
Instance Method Summary collapse
-
#add_primary_key(name, column_names, **primary_key_options) ⇒ Object
add a primary key to this table.
-
#create_temp_table(connection, temp_table_name) ⇒ Object
Used within validations and triggers when normalizing check clauses and other SQL statements which require a table to process the SQL.
-
#has_description? ⇒ Boolean
returns true if this table has a description, otehrwise false.
-
#has_primary_key? ⇒ Boolean
returns true if this table has a primary key, otherwise false.
-
#initialize(source, schema, name, description: nil) ⇒ Table
constructor
initialize a new object to represent a postgres table.
-
#primary_key ⇒ Object
returns a primary key if one exists, else raises an error.
Methods included from UniqueConstraints
#add_unique_constraint, #has_unique_constraint?, #unique_constraint, #unique_constraints, #unique_constraints_hash
Methods included from Triggers
#add_trigger, #has_trigger?, #trigger, #triggers, #triggers_hash
Methods included from ForeignKeyConstraints
#add_foreign_key_constraint, #add_remote_foreign_key_constraint, #foreign_key_constraint, #foreign_key_constraints, #foreign_key_constraints_hash, #has_foreign_key_constraint?
Methods included from Indexes
#add_index, #has_index?, #index, #indexes, #indexes_hash
Methods included from Validations
#add_validation, #has_validation?, #validation, #validations, #validations_hash
Methods included from Columns
#add_column, #column, #columns, #columns_hash, #has_column?
Methods inherited from DynamicMigrations::Postgres::Server::Database::Source
#assert_is_a_symbol!, #from_configuration?, #from_database?
Constructor Details
#initialize(source, schema, name, description: nil) ⇒ Table
initialize a new object to represent a postgres table
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 35 def initialize source, schema, name, description: nil super source raise ExpectedSchemaError, schema unless schema.is_a? Schema @schema = schema raise ExpectedSymbolError, name unless name.is_a? Symbol @name = name unless description.nil? raise ExpectedStringError, description unless description.is_a? String @description = description.strip @description = nil if description == "" end @columns = {} @validations = {} @indexes = {} @foreign_key_constraints = {} @remote_foreign_key_constraints = [] @triggers = {} @unique_constraints = {} end |
Instance Attribute Details
#description ⇒ Object (readonly)
Returns the value of attribute description.
31 32 33 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 31 def description @description end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
30 31 32 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 30 def name @name end |
#remote_foreign_key_constraints ⇒ Object (readonly)
Returns the value of attribute remote_foreign_key_constraints.
32 33 34 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 32 def remote_foreign_key_constraints @remote_foreign_key_constraints end |
#schema ⇒ Object (readonly)
Returns the value of attribute schema.
29 30 31 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 29 def schema @schema end |
Instance Method Details
#add_primary_key(name, column_names, **primary_key_options) ⇒ Object
add a primary key to this table
65 66 67 68 69 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 65 def add_primary_key name, column_names, ** raise PrimaryKeyAlreadyExistsError if @primary_key columns = column_names.map { |column_name| column column_name } @primary_key = PrimaryKey.new source, self, columns, name, ** end |
#create_temp_table(connection, temp_table_name) ⇒ Object
Used within validations and triggers when normalizing check clauses and other SQL statements which require a table to process the SQL.
This method returns a hash representation of any temporary enums created to satisfy the columns in the table
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 188 189 190 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 90 def create_temp_table connection, temp_table_name # create the temp table and add the expected columns # if any of the columns are enums, then we need to create a temporary enum type for them. # we cant just create temporary columns as text fields because postgres may automatically # add casts to those columns, which would result in a different normalized check clause temp_enums = {} # an array of sql column definitions for within the create table SQL # we process each column individually like this so that we can create temporary enums for # any enum columns columns_sql = columns.map do |column| enum = column.enum if enum # create the temporary enum type temp_enum_name = "#{temp_table_name}_enum_#{temp_enums.count}" connection.exec(<<~SQL) CREATE TYPE #{temp_enum_name} as ENUM ('#{enum.values.join("','")}'); SQL temp_enums[temp_enum_name] = enum # return the column definition used within the CREATE TABLE SQL data_type = column.array? ? "#{temp_enum_name}[]" : temp_enum_name "\"#{column.name}\" #{data_type}" else # return the column definition used within the CREATE TABLE SQL "\"#{column.name}\" #{column.data_type}" end end # in case any of the columnbs are citext columns # in case any of the columns use the citext data type required_extensions = [] if columns.any? { |column| column.data_type.start_with? "citext" } required_extensions << "citext" end if columns.any? { |column| column.data_type.start_with? "postgis" } required_extensions << "postgis" end required_extensions.each do |extension_name| extension_result = connection.exec(<<~SQL) SELECT ( SELECT 1 FROM pg_available_extensions WHERE name = '#{extension_name}' ) as is_available, ( SELECT 1 FROM pg_extension WHERE extname = '#{extension_name}' ) as is_installed SQL row = extension_result.first raise MissingExtensionError, "unexpected error" if row.nil? unless row["is_installed"] detail = if row["is_available"] <<~DETAIL The `#{extension_name}` extension is available for installation, but has not been installed for this database. DETAIL else <<~DETAIL The `#{extension_name}` extension is not installed, and does not appear to be available for installation. DETAIL end raise MissingExtensionError, <<~ERROR.tr!("\n", " ") This table uses the `#{extension_name}` data type. #{detail} Add the extension, then generate and run the migrations which will enable the extension for your database before defining validations or triggers which rely on it. Note, the `#{extension_name}` extension is required even for defining some validations and triggers. This library needs to connect to postgres and gererate normalized versions of validation check clauses and trigger action conditions before it can even compare them to validations or triggers which may or may not already exist in the database. ERROR end end # if any of the columns require postgis if required_extensions.include? "postgis" connection.exec("SET search_path TO public,postgis;") end # note, this is not actually a TEMP TABLE, it is created within a transaction # and rolled back. connection.exec(<<~SQL) CREATE TABLE #{temp_table_name} ( #{columns_sql.join(", ")} ); SQL temp_enums end |
#has_description? ⇒ Boolean
returns true if this table has a description, otehrwise false
60 61 62 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 60 def has_description? !@description.nil? end |
#has_primary_key? ⇒ Boolean
returns true if this table has a primary key, otherwise false
72 73 74 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 72 def has_primary_key? !@primary_key.nil? end |
#primary_key ⇒ Object
returns a primary key if one exists, else raises an error
77 78 79 80 81 82 83 |
# File 'lib/dynamic_migrations/postgres/server/database/schema/table.rb', line 77 def primary_key pk = @primary_key unless pk raise PrimaryKeyDoesNotExistError end pk end |