Class: Vorpal::Driver::Postgresql

Inherits:
Object
  • Object
show all
Defined in:
lib/vorpal/driver/postgresql.rb

Overview

Interface between the database and Vorpal for PostgreSQL using ActiveRecord.

Instance Method Summary collapse

Constructor Details

#initializePostgresql

Returns a new instance of Postgresql.



7
8
9
# File 'lib/vorpal/driver/postgresql.rb', line 7

def initialize
  @sequence_names = {}
end

Instance Method Details

#build_db_class(model_class, table_name) ⇒ Class

Builds an ORM Class for accessing data in the given DB table.

Parameters:

  • model_class (Class)

    The PORO class that we are creating a DB interface class for.

  • table_name (String)

    Name of the DB table the DB class should interface with.

Returns:

  • (Class)

    ActiveRecord::Base Class



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
# File 'lib/vorpal/driver/postgresql.rb', line 77

def build_db_class(model_class, table_name)
  db_class = Class.new(ActiveRecord::Base) do
    class << self
      # This is overridden for two reasons:
      # 1) For anonymous classes, #name normally returns nil. Class names in Ruby come from the
      #   name of the constant they are assigned to.
      # 2) Because the default implementation for Class#name for anonymous classes is very, very
      #   slow. https://bugs.ruby-lang.org/issues/11119
      # Remove this override once #2 has been fixed!
      def name
        @name ||= "Vorpal_generated_ActiveRecord__Base_class_for_#{vorpal_model_class_name}"
      end

      # Overridden because, like #name, the default implementation for anonymous classes is very,
      # very slow.
      def to_s
        name
      end

      attr_accessor :vorpal_model_class_name
    end
  end

  db_class.vorpal_model_class_name = Util::StringUtils.escape_class_name(model_class.name)
  db_class.table_name = table_name
  db_class
end

#destroy(db_class, ids) ⇒ Object



39
40
41
# File 'lib/vorpal/driver/postgresql.rb', line 39

def destroy(db_class, ids)
  db_class.where(id: ids).delete_all
end

#get_primary_keys(db_class, count) ⇒ [Integer]

Fetches primary key values to be used for new entities.

Parameters:

  • db_class (Class)

    A subclass of ActiveRecord::Base

Returns:

  • ([Integer])

    An array of unused primary keys.



67
68
69
70
# File 'lib/vorpal/driver/postgresql.rb', line 67

def get_primary_keys(db_class, count)
  result = execute("select nextval($1) from generate_series(1,$2);", [sequence_name(db_class), count])
  result.rows.map(&:first).map(&:to_i)
end

#insert(db_class, db_objects) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/vorpal/driver/postgresql.rb', line 11

def insert(db_class, db_objects)
  if ActiveRecord::VERSION::MAJOR >= 6
    return if db_objects.empty?

    update_timestamps_on_create(db_class, db_objects)
    db_class.insert_all!(db_objects.map(&:attributes))
  elsif defined? ActiveRecord::Import
    db_class.import(db_objects, validate: false)
  else
    db_objects.each do |db_object|
      db_object.save!(validate: false)
    end
  end
end

#load_by_foreign_key(db_class, id, foreign_key_info) ⇒ [Object]

Loads instances of the given class whose foreign key has the given value.

Parameters:

  • db_class (Class)

    A subclass of ActiveRecord::Base

  • id (Integer)

    The value of the foreign key to find by. (Can also be an array of ids.)

  • foreign_key_info (ForeignKeyInfo)

    Meta data for the foreign key.

Returns:

  • ([Object])

    An array of entities.



57
58
59
60
61
# File 'lib/vorpal/driver/postgresql.rb', line 57

def load_by_foreign_key(db_class, id, foreign_key_info)
  arel = db_class.where(foreign_key_info.fk_column => id)
  arel = arel.where(foreign_key_info.fk_type_column => foreign_key_info.fk_type) if foreign_key_info.polymorphic?
  arel.to_a
end

#load_by_unique_key(db_class, ids, column_name) ⇒ [Object]

Loads instances of the given class by a unique key.

Parameters:

  • db_class (Class)

    A subclass of ActiveRecord::Base

Returns:

  • ([Object])

    An array of entities.



47
48
49
# File 'lib/vorpal/driver/postgresql.rb', line 47

def load_by_unique_key(db_class, ids, column_name)
  db_class.where(column_name => ids).to_a
end

#query(db_class, aggregate_mapper) ⇒ Object

Builds a composable query object (e.g. ActiveRecord::Relation) with Vorpal methods mixed in for querying for instances of the given AR::Base class.

Parameters:

  • db_class (Class)

    A subclass of ActiveRecord::Base



109
110
111
# File 'lib/vorpal/driver/postgresql.rb', line 109

def query(db_class, aggregate_mapper)
  db_class.unscoped.extending(ArelQueryMethods.new(aggregate_mapper))
end

#update(db_class, db_objects) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/vorpal/driver/postgresql.rb', line 26

def update(db_class, db_objects)
  if ActiveRecord::VERSION::MAJOR >= 6
    return if db_objects.empty?

    update_timestamps_on_update(db_class, db_objects)
    db_class.upsert_all(db_objects.map(&:attributes))
  else
    db_objects.each do |db_object|
      db_object.save!(validate: false)
    end
  end
end