Module: DataMapper::Constraints::Adapters::DataObjectsAdapter

Includes:
SQL
Included in:
MysqlAdapter, OracleAdapter, PostgresAdapter, SqlserverAdapter
Defined in:
lib/data_mapper/constraints/adapters/do_adapter.rb

Defined Under Namespace

Modules: SQL

Instance Method Summary collapse

Instance Method Details

#constraint_exists?(storage_name, constraint_name) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Determine if a constraint exists for a table

Parameters:

  • storage_name (Symbol)

    name of table to check constraint on

  • constraint_name (~String)

    name of constraint to check for

Returns:

  • (Boolean)

17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/data_mapper/constraints/adapters/do_adapter.rb', line 17

def constraint_exists?(storage_name, constraint_name)
  statement = DataMapper::Ext::String.compress_lines(<<-SQL)
    SELECT COUNT(*)
    FROM #{quote_name('information_schema')}.#{quote_name('table_constraints')}
    WHERE #{quote_name('constraint_type')} = 'FOREIGN KEY'
    AND #{quote_name('table_schema')} = ?
    AND #{quote_name('table_name')} = ?
    AND #{quote_name('constraint_name')} = ?
  SQL

  select(statement, schema_name, storage_name, constraint_name).first > 0
end

#create_relationship_constraint(relationship) ⇒ true, false

Create the constraint for a relationship

Parameters:

  • relationship (Relationship)

    the relationship to create the constraint for

Returns:

  • (true, false)

    true if creating the constraints was successful


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
# File 'lib/data_mapper/constraints/adapters/do_adapter.rb', line 40

def create_relationship_constraint(relationship)
  return false unless valid_relationship_for_constraint?(relationship)

  source_storage_name = relationship.source_model.storage_name(name)
  target_storage_name = relationship.target_model.storage_name(name)
  constraint_name     = constraint_name(source_storage_name, relationship.name)

  return false if constraint_exists?(source_storage_name, constraint_name)

  constraint_type =
    case relationship.inverse.constraint
    when :protect            then 'NO ACTION'
    # TODO: support :cascade as an option:
    #   (destroy doesn't communicate the UPDATE constraint)
    when :destroy, :destroy! then 'CASCADE'
    when :set_nil            then 'SET NULL'
    end

  return false if constraint_type.nil?

  source_keys = relationship.source_key.map { |p| property_to_column_name(p, false) }
  target_keys = relationship.target_key.map { |p| property_to_column_name(p, false) }

  create_constraints_statement = create_constraints_statement(
    constraint_name,
    constraint_type,
    source_storage_name,
    source_keys,
    target_storage_name,
    target_keys)

  execute(create_constraints_statement)
end

#destroy_relationship_constraint(relationship) ⇒ true, false

Remove the constraint for a relationship

Parameters:

  • relationship (Relationship)

    the relationship to remove the constraint for

Returns:

  • (true, false)

    true if destroying the constraint was successful


84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/data_mapper/constraints/adapters/do_adapter.rb', line 84

def destroy_relationship_constraint(relationship)
  return false unless valid_relationship_for_constraint?(relationship)

  storage_name    = relationship.source_model.storage_name(name)
  constraint_name = constraint_name(storage_name, relationship.name)

  return false unless constraint_exists?(storage_name, constraint_name)

  destroy_constraints_statement =
    destroy_constraints_statement(storage_name, constraint_name)

  execute(destroy_constraints_statement)
end