Class: Og::SqlStore

Inherits:
Store
  • Object
show all
Extended by:
SqlUtils
Includes:
SqlUtils
Defined in:
lib/og/store/sql.rb

Overview

A Store that persists objects into a PostgreSQL database.

Instance Attribute Summary collapse

Attributes inherited from Store

#options, #transaction_nesting

Instance Method Summary collapse

Methods included from SqlUtils

date, escape, join_table, parse_date, parse_float, parse_int, parse_timestamp, quote, table, timestamp

Methods inherited from Store

#close, create, #delete, destroy, for_name, #insert, #save, #transaction

Constructor Details

#initialize(options) ⇒ SqlStore

Returns a new instance of SqlStore.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/og/store/sql.rb', line 109

def initialize(options)
	super

	# The default Ruby <-> SQL type mappings, should be valid for most
	# RDBM systems.
	
	@typemap = {
		Integer => 'integer',
		Fixnum => 'integer',
		Float => 'float',
		String => 'text',
		Time => 'timestamp',
		Date => 'date',
		TrueClass => 'boolean',
		Object => 'text',
		Array => 'text',
		Hash => 'text'
	}
end

Instance Attribute Details

#connObject

The connection to the backend SQL RDBMS.



107
108
109
# File 'lib/og/store/sql.rb', line 107

def conn
  @conn
end

Instance Method Details

#commitObject

Commit a transaction.



286
287
288
289
# File 'lib/og/store/sql.rb', line 286

def commit
	@transaction_nesting -= 1
	exec('COMMIT') if @transaction_nesting < 1
end

#count(options) ⇒ Object



240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/og/store/sql.rb', line 240

def count(options)
	if options.is_a?(String)
		sql = options
	else
		sql = "SELECT COUNT(*) FROM #{options[:class]::OGTABLE}"
		if condition = options[:condition]
			sql << " WHERE #{condition}"
		end
	end		
	
	query(sql).first_value.to_i
end

#enable_loggingObject

– FIXME: not working. ++



133
134
135
136
137
138
139
# File 'lib/og/store/sql.rb', line 133

def enable_logging
	require 'glue/aspects'
	klass = self.class
	klass.send :include, Glue::Aspects
	klass.pre "Logger.info sql", :on => [:exec, :query]
	Glue::Aspects.wrap(klass, [:exec, :query])
end

#enchant(klass, manager) ⇒ Object

Enchants a class.



143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/og/store/sql.rb', line 143

def enchant(klass, manager)
	klass.const_set 'OGTABLE', table(klass)
	klass.module_eval 'def self.table; OGTABLE; end'
	
	super

	create_table(klass) if Og.create_schema

	eval_og_insert(klass)
	eval_og_update(klass)
	eval_og_read(klass)
	eval_og_delete(klass)
end

#find(options) ⇒ Object

Find a collection of objects.

Examples

User.find(:condition => ‘age > 15’, :order => ‘score ASC’, :offet => 10, :limit =>10) Comment.find(:include => :entry)



225
226
227
228
229
# File 'lib/og/store/sql.rb', line 225

def find(options)	
	klass = options[:class]
	sql = resolve_options(klass, options)
	read_all(query(sql), klass, options[:include])
end

#find_one(options) ⇒ Object

Find one object.



233
234
235
236
237
238
# File 'lib/og/store/sql.rb', line 233

def find_one(options)
	klass = options[:class]
	options[:limit] ||= 1				
	sql = resolve_options(klass, options)
	read_one(query(sql), klass, options[:include])
end

#join(obj1, obj2, table) ⇒ Object

Relate two objects through an intermediate join table. Typically used in joins_many and many_to_many relations.



256
257
258
259
260
261
262
# File 'lib/og/store/sql.rb', line 256

def join(obj1, obj2, table)
	if obj1.class.to_s > obj2.class.to_s
		obj1, obj2 = obj2, obj1
	end		
	
	exec "INSERT INTO #{table} (key1, key2) VALUES (#{obj1.pk}, #{obj2.pk})"
end

#load(pk, klass) ⇒ Object

Loads an object from the store using the primary key.



161
162
163
164
# File 'lib/og/store/sql.rb', line 161

def load(pk, klass)
	res = query "SELECT * FROM #{klass::OGTABLE} WHERE #{klass.pk_symbol}=#{pk}"
	read_one(res, klass)
end

#reload(obj, pk) ⇒ Object

Reloads an object from the store.



168
169
170
171
172
173
174
# File 'lib/og/store/sql.rb', line 168

def reload(obj, pk)
	raise 'Cannot reload unmanaged object' unless obj.saved?
	res = query "SELECT * FROM #{obj.class.table} WHERE #{obj.class.pk_symbol}=#{pk}"
	obj.og_read(res.next, 0)
ensure
	res.close if res
end

#rollbackObject

Rollback a transaction.



293
294
295
296
# File 'lib/og/store/sql.rb', line 293

def rollback
	@transaction_nesting -= 1
	exec('ROLLBACK') if @transaction_nesting < 1
end

#startObject

Start a new transaction.



279
280
281
282
# File 'lib/og/store/sql.rb', line 279

def start	
	exec('START TRANSACTION') if @transaction_nesting < 1
	@transaction_nesting += 1
end

#unjoin(obj1, obj2, table) ⇒ Object

Unrelate two objects be removing their relation from the join table.



267
268
269
270
271
272
273
# File 'lib/og/store/sql.rb', line 267

def unjoin(obj1, obj2, table)
	if obj1.class.to_s > obj2.class.to_s
		obj1, obj2 = obj2, obj1
	end	

	exec "DELETE FROM #{table} WHERE key1=#{obj1.pk} AND key2=#{obj2.pk}"
end

#update(obj, properties = nil) ⇒ Object

If a properties collection is provided, only updates the selected properties. Pass the required properties as symbols or strings.



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/og/store/sql.rb', line 180

def update(obj, properties = nil)
	if properties
		if properties.is_a?(Array)
			set = []
			for p in properties
				set << "#{p}=#{quote(obj.send(p))}"
			end
			set = set.join(',')
		else
			set = "#{properties}=#{quote(obj.send(properties))}"
		end
		exec "UPDATE #{obj.class.table} SET #{set} WHERE #{obj.class.pk_symbol}=#{obj.pk}"
	else
		obj.og_update(self)
	end
end

#update_properties(target, set, options = nil) ⇒ Object Also known as: pupdate, update_property

Update selected properties of an object or class of objects.



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/og/store/sql.rb', line 200

def update_properties(target, set, options = nil)
	set = set.gsub(/@/, '')
	
	if target.is_a?(Class)
		sql = "UPDATE #{target.table} SET #{set} "
		if options
			if condition = options[:condition] || options[:where]
				sql << " WHERE #{condition}"
			end
		end
		exec sql
	else
		exec "UPDATE #{target.class.table} SET #{set} WHERE #{target.class.pk_symbol}=#{target.pk}"		
	end			
end