Module: N::Managed

Included in:
Entity, ManagedChild
Defined in:
lib/n/db/managed.rb

Overview

The database interfaces automatically manages classes that include this interface.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#join_fieldsObject

Use this hash to store sql join query fields. DONT create this hash unless needed!



62
63
64
# File 'lib/n/db/managed.rb', line 62

def join_fields
  @join_fields
end

Class Method Details

.eval_db_insert(klass) ⇒ Object

Precompile the insert code for the given class.

gmosx: SET the oid when inserting!



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/n/db/managed.rb', line 188

def self.eval_db_insert(klass)
	props = klass.__props
	
	values = props.collect { |p| 
		N::DbUtils.write_prop(p)
	} 

	sql = "INSERT INTO #{N::DbUtils.sql_table(klass)} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values.join(',')})"

	klass.module_eval %{
		def __db_insert(conn)
			__db_pre_insert(conn)
			conn.retry_query("#{sql}", #{klass})
		end
	}
end

.eval_db_read_row(klass) ⇒ Object

Precompile the code to read objects of the given class from the backend.

In order to allow for changing field/attribute orders we have to use a field mapping hash.



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/n/db/managed.rb', line 166

def self.eval_db_read_row(klass)
	props = klass.__props 
	code = []
	
	props.each { |p|
		if idx = $db.fields[klass][p.name]
			# more fault tolerant if a new field is added and it 
			# doesnt exist in the database.
			code << "@#{p.name} = #{N::DbUtils.read_prop(p, idx)}"
		end
	}
	klass.module_eval %{
 		def __db_read_row(rows, tuple)
			#{code.join('; ')}
		end
	}
end

.eval_db_update(klass) ⇒ Object

Precompile the update code for the given class.

gmosx: ignore the oid when updating!



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/n/db/managed.rb', line 209

def self.eval_db_update(klass)
	props = klass.__props.reject { |p| :oid == p.symbol }
	
	updates = props.collect { |p|
		"#{p.name}=#{N::DbUtils.write_prop(p)}"
	}

	# the primary key
	
	if pk = klass.new.__db_pk
		# only evaluate the update code if the object
		# defines a primary key.
		
		sql = "UPDATE #{klass::DBTABLE} SET #{updates.join(', ')} WHERE #{pk}=#\{@#{pk}\}"
	
		klass.module_eval %{
			def __db_update(conn)
				conn.retry_query("#{sql}", #{klass})
			end
		}
	end
end

.eval_dbseq(klass) ⇒ Object

Evaluate the DBSEQ constant for the given class. Classes that include the N::Sequenced marker have a custom sequence.

INVESTIGATE: how to implement this for MySQL?



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/n/db/managed.rb', line 140

def self.eval_dbseq(klass)
	if klass.include?(N::Sequenced)
		klass.module_eval %{
			DBSEQ = "#{N::DbUtils.sql_table(klass)}_oids_seq" 
		}
	else
		klass.module_eval %{
			DBSEQ = "oids_seq" 
		}
	end
end

.eval_dbtable(klass) ⇒ Object

Evaluate the DBTABLE constant for the given class.



154
155
156
157
158
# File 'lib/n/db/managed.rb', line 154

def self.eval_dbtable(klass)
	klass.module_eval %{
		DBTABLE = "#{N::DbUtils.sql_table(klass)}"
	}
end

Instance Method Details

#__ancestors_classesObject

A list of potential ancestor classes Returns an array of classes.



72
73
74
# File 'lib/n/db/managed.rb', line 72

def __ancestors_classes
	return nil
end

#__db_insert(conn) ⇒ Object

This method is called to insert a managed object in the database. This definition is ovveriden by the evaluated code from eval_db_update.



112
113
114
# File 'lib/n/db/managed.rb', line 112

def __db_insert(conn)
	# nop
end

#__db_pkObject

Define the primary key as a string.



89
90
91
# File 'lib/n/db/managed.rb', line 89

def __db_pk
	return nil
end

#__db_pre_delete(conn) ⇒ Object

Add code to be executed before the managed object is deleted. Typically used for cascading deletes, executed in a transaction, do NOT error-check here!



104
105
106
# File 'lib/n/db/managed.rb', line 104

def __db_pre_delete(conn)
	# nop
end

#__db_pre_insert(conn) ⇒ Object

Add code to be executed before the managed object is inserted. Typically creates the primary key.



96
97
98
# File 'lib/n/db/managed.rb', line 96

def __db_pre_insert(conn)
	# nop
end

#__db_update(conn) ⇒ Object

This method is called to update a managed object in the database. This definition is ovveriden by the evaluated code from eval_db_update.



128
129
130
# File 'lib/n/db/managed.rb', line 128

def __db_update(conn)
	raise "No primary key defined, cannot update" 
end

#__descendants_classesObject

A list of potential descendants classes Typically used in cascading deletes. Returns an array of classes.



80
81
82
# File 'lib/n/db/managed.rb', line 80

def __descendants_classes
	return nil
end

#initialize(*args) ⇒ Object



66
67
# File 'lib/n/db/managed.rb', line 66

def initialize(*args)
end