Class: Perpetuity::Postgres

Inherits:
Object
  • Object
show all
Defined in:
lib/perpetuity/postgres.rb,
lib/perpetuity/postgres/query.rb,
lib/perpetuity/postgres/table.rb,
lib/perpetuity/postgres/version.rb,
lib/perpetuity/postgres/json_hash.rb,
lib/perpetuity/postgres/nil_query.rb,
lib/perpetuity/postgres/sql_value.rb,
lib/perpetuity/postgres/connection.rb,
lib/perpetuity/postgres/expression.rb,
lib/perpetuity/postgres/json_array.rb,
lib/perpetuity/postgres/null_value.rb,
lib/perpetuity/postgres/serializer.rb,
lib/perpetuity/postgres/sql_select.rb,
lib/perpetuity/postgres/sql_update.rb,
lib/perpetuity/postgres/table_name.rb,
lib/perpetuity/postgres/text_value.rb,
lib/perpetuity/postgres/query_union.rb,
lib/perpetuity/postgres/boolean_value.rb,
lib/perpetuity/postgres/negated_query.rb,
lib/perpetuity/postgres/numeric_value.rb,
lib/perpetuity/postgres/connection_pool.rb,
lib/perpetuity/postgres/query_attribute.rb,
lib/perpetuity/postgres/serialized_data.rb,
lib/perpetuity/postgres/table/attribute.rb,
lib/perpetuity/postgres/timestamp_value.rb,
lib/perpetuity/postgres/query_expression.rb,
lib/perpetuity/postgres/json_string_value.rb,
lib/perpetuity/postgres/query_intersection.rb,
lib/perpetuity/postgres/value_with_attribute.rb

Defined Under Namespace

Classes: BooleanValue, Connection, ConnectionPool, Expression, JSONArray, JSONHash, JSONStringValue, NegatedQuery, NilQuery, NullValue, NumericValue, Query, QueryAttribute, QueryExpression, QueryIntersection, QueryUnion, SQLSelect, SQLUpdate, SQLValue, SerializedData, Serializer, Table, TableName, TextValue, TimestampValue, ValueWithAttribute

Constant Summary collapse

VERSION =
"0.0.1"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Postgres

Returns a new instance of Postgres.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/perpetuity/postgres.rb', line 17

def initialize options
  @host      = options.fetch(:host) { 'localhost' }
  @port      = options.fetch(:port) { 5432 }
  @db        = options.fetch(:db)
  @pool_size = options.fetch(:pool_size) { 5 }
  @username  = options.fetch(:username) { ENV['USER'] }
  @password  = options.fetch(:password) {}

  @connection ||= ConnectionPool.new(
    db:       db,
    host:     host,
    port:     port,
    username: username,
    password: password,
    pool_size: pool_size
  )
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def connection
  @connection
end

#dbObject (readonly)

Returns the value of attribute db.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def db
  @db
end

#hostObject (readonly)

Returns the value of attribute host.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def host
  @host
end

#passwordObject (readonly)

Returns the value of attribute password.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def password
  @password
end

#pool_sizeObject (readonly)

Returns the value of attribute pool_size.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def pool_size
  @pool_size
end

#portObject (readonly)

Returns the value of attribute port.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def port
  @port
end

#usernameObject (readonly)

Returns the value of attribute username.



14
15
16
# File 'lib/perpetuity/postgres.rb', line 14

def username
  @username
end

Instance Method Details

#count(klass, query = 'TRUE', options = {}, &block) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/perpetuity/postgres.rb', line 59

def count klass, query='TRUE', options={}, &block
  where = if block_given?
            query(&block)
          else
            query
          end
  options = translate_options(options).merge(from: klass, where: where)
  table = table_name(klass)
  sql = select 'COUNT(*)', options
  connection.execute(sql).to_a.first['count'].to_i
rescue PG::UndefinedTable
  # Table does not exist, so there are 0 records
  0
end

#create_table(name, attributes) ⇒ Object



136
137
138
# File 'lib/perpetuity/postgres.rb', line 136

def create_table name, attributes
  connection.execute Table.new(name, attributes).create_table_sql
end

#create_table_with_attributes(klass, attributes) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/perpetuity/postgres.rb', line 160

def create_table_with_attributes klass, attributes
  table_attributes = attributes.map do |attr|
    name = attr.name
    type = attr.type
    options = attr.options
    Table::Attribute.new name, type, options
  end
  create_table klass.to_s, table_attributes
end

#delete(id, klass) ⇒ Object



52
53
54
55
56
57
# File 'lib/perpetuity/postgres.rb', line 52

def delete id, klass
  table = TableName.new(klass)
  id_string = TextValue.new(id)
  sql = "DELETE FROM #{table} WHERE id = #{id_string}"
  connection.execute(sql).to_a
end

#delete_all(klass) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/perpetuity/postgres.rb', line 82

def delete_all klass
  table = table_name(klass)
  sql = "DELETE FROM #{table}"
  connection.execute(sql)
rescue PG::UndefinedTable
  # Do nothing. There is already nothing here.
end

#drop_table(name) ⇒ Object



132
133
134
# File 'lib/perpetuity/postgres.rb', line 132

def drop_table name
  connection.execute "DROP TABLE IF EXISTS #{table_name(name)}"
end

#find(klass, id) ⇒ Object



74
75
76
# File 'lib/perpetuity/postgres.rb', line 74

def find klass, id
  retrieve(klass, query { |o| o.id == id }.to_db).first
end

#has_table?(name) ⇒ Boolean

Returns:

  • (Boolean)


140
141
142
# File 'lib/perpetuity/postgres.rb', line 140

def has_table? name
  connection.tables.include? name
end

#insert(klass, serialized_objects, attributes) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/perpetuity/postgres.rb', line 35

def insert klass, serialized_objects, attributes
  table = TableName.new(klass)
  data = serialized_objects.reduce(:+)
  sql = "INSERT INTO #{table} #{data} RETURNING id"

  results = connection.execute(sql).to_a
  ids = results.map { |result| result['id'] }

  ids
rescue PG::UndefinedTable => e # Table doesn't exist, so we create it.
  retries ||= 0
  retries += 1
  create_table_with_attributes klass, attributes
  retry unless retries > 1
  raise e
end

#negate_query(&block) ⇒ Object



94
95
96
# File 'lib/perpetuity/postgres.rb', line 94

def negate_query &block
  NegatedQuery.new(&block)
end

#postgresify(value) ⇒ Object



144
145
146
# File 'lib/perpetuity/postgres.rb', line 144

def postgresify value
  Serializer.new(nil).serialize_attribute value
end

#query(&block) ⇒ Object



90
91
92
# File 'lib/perpetuity/postgres.rb', line 90

def query &block
  Query.new(&block)
end

#retrieve(klass, criteria, options = {}) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/perpetuity/postgres.rb', line 98

def retrieve klass, criteria, options={}
  options = translate_options(options).merge from: klass, where: criteria

  sql = select options
  connection.execute(sql).to_a
rescue PG::UndefinedTable
  []
end

#select(*args) ⇒ Object



128
129
130
# File 'lib/perpetuity/postgres.rb', line 128

def select *args
  SQLSelect.new(*args).to_s
end

#serialize(object, mapper) ⇒ Object



148
149
150
# File 'lib/perpetuity/postgres.rb', line 148

def serialize object, mapper
  Serializer.new(mapper).serialize object
end

#serialize_changed_attributes(object, original, mapper) ⇒ Object



152
153
154
# File 'lib/perpetuity/postgres.rb', line 152

def serialize_changed_attributes object, original, mapper
  Serializer.new(mapper).serialize_changes object, original
end

#table_name(klass) ⇒ Object



78
79
80
# File 'lib/perpetuity/postgres.rb', line 78

def table_name klass
  TableName.new(klass)
end

#translate_options(options) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/perpetuity/postgres.rb', line 112

def translate_options options
  options = options.dup
  if options[:attribute]
    options[:order] = options.delete(:attribute)
    if direction = options.delete(:direction)
      direction = direction.to_s[/\w{1,2}sc/i]
      options[:order] = { options[:order] => direction }
    end
  end
  if options[:skip]
    options[:offset] = options.delete(:skip)
  end

  options
end

#unserialize(data, mapper) ⇒ Object



156
157
158
# File 'lib/perpetuity/postgres.rb', line 156

def unserialize data, mapper
  Serializer.new(mapper).unserialize data
end

#update(klass, id, attributes) ⇒ Object



107
108
109
110
# File 'lib/perpetuity/postgres.rb', line 107

def update klass, id, attributes
  sql = SQLUpdate.new(klass, id, attributes).to_s
  connection.execute(sql).to_a
end