voraz-dr_nic_magic_models 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/History.txt +33 -0
- data/Manifest.txt +56 -0
- data/README +0 -0
- data/Rakefile +149 -0
- data/install.rb +30 -0
- data/lib/base.rb +12 -0
- data/lib/connection_adapters/abstract/schema_statements.rb +0 -0
- data/lib/connection_adapters/abstract_adapter.rb +32 -0
- data/lib/connection_adapters/mysql_adapter.rb +42 -0
- data/lib/connection_adapters/postgresql_adapter.rb +45 -0
- data/lib/dr_nic_magic_models/inflector.rb +14 -0
- data/lib/dr_nic_magic_models/magic_model.rb +135 -0
- data/lib/dr_nic_magic_models/schema.rb +270 -0
- data/lib/dr_nic_magic_models/validations.rb +46 -0
- data/lib/dr_nic_magic_models/version.rb +9 -0
- data/lib/dr_nic_magic_models.rb +34 -0
- data/lib/module.rb +33 -0
- data/lib/rails.rb +19 -0
- data/scripts/txt2html +66 -0
- data/scripts/txt2js +58 -0
- data/test/abstract_unit.rb +70 -0
- data/test/connections/native_mysql/connection.rb +14 -0
- data/test/connections/native_postgresql/connection.rb +12 -0
- data/test/connections/native_sqlite/connection.rb +10 -0
- data/test/dummy_test.rb +13 -0
- data/test/env_test.rb +10 -0
- data/test/fixtures/.DS_Store +0 -0
- data/test/fixtures/adjectives.yml +3 -0
- data/test/fixtures/adjectives_fun_users.yml +3 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +4 -0
- data/test/fixtures/db_definitions/mysql.sql +58 -0
- data/test/fixtures/db_definitions/postgresql.sql +56 -0
- data/test/fixtures/db_definitions/sqlite.sql +49 -0
- data/test/fixtures/fun_users.yml +14 -0
- data/test/fixtures/group_memberships.yml +4 -0
- data/test/fixtures/group_tag.yml +11 -0
- data/test/fixtures/groups.yml +12 -0
- data/test/foreign_keys_test.rb +0 -0
- data/test/fun_user_plus.rb +2 -0
- data/test/invisible_model_access_test.rb +71 -0
- data/test/invisible_model_assoc_test.rb +61 -0
- data/test/invisible_model_classes_test.rb +23 -0
- data/test/magic_module_test.rb +20 -0
- data/test/test_existing_model.rb +20 -0
- data/test.db +0 -0
- data/website/index.html +409 -0
- data/website/index.txt +291 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +106 -0
- data/website/template.js +3 -0
- data/website/template.rhtml +55 -0
- data/website/version-raw.js +3 -0
- data/website/version-raw.txt +2 -0
- data/website/version.js +4 -0
- data/website/version.txt +3 -0
- metadata +123 -0
@@ -0,0 +1,270 @@
|
|
1
|
+
module DrNicMagicModels
|
2
|
+
|
3
|
+
# ONE Schema per namespace module
|
4
|
+
# Person, Company, etc share the Object namespace module, ie. ::Person, ::Company
|
5
|
+
# Blog::Post, Blog::Comment, share the Blog namespace module
|
6
|
+
class Schema
|
7
|
+
attr_reader :modul
|
8
|
+
|
9
|
+
def initialize(modul)
|
10
|
+
@modul = modul
|
11
|
+
@table_name_prefix = modul.instance_variable_get("@table_name_prefix") rescue ''
|
12
|
+
logger.info "Create Schema for #{@modul}, table_name_prefix '#{@table_name_prefix}'"
|
13
|
+
end
|
14
|
+
|
15
|
+
cattr_accessor :inflector
|
16
|
+
cattr_accessor :superklass
|
17
|
+
|
18
|
+
# Need to store models etc per-module, not in @ @models
|
19
|
+
def inflector
|
20
|
+
@inflector ||= Inflector.new
|
21
|
+
end
|
22
|
+
|
23
|
+
# all in lower case please
|
24
|
+
ReservedTables = [:schema_info, :sessions]
|
25
|
+
@models = nil
|
26
|
+
|
27
|
+
def logger
|
28
|
+
@logger ||= DrNicMagicModels::Logger
|
29
|
+
end
|
30
|
+
|
31
|
+
def models
|
32
|
+
load_schema if @models.nil?
|
33
|
+
@models
|
34
|
+
end
|
35
|
+
|
36
|
+
def tables
|
37
|
+
load_schema if @tables.nil?
|
38
|
+
@tables
|
39
|
+
end
|
40
|
+
|
41
|
+
def table_names
|
42
|
+
load_schema if @table_names.nil?
|
43
|
+
@table_names
|
44
|
+
end
|
45
|
+
|
46
|
+
def fks_on_table(table_name)
|
47
|
+
load_schema if @models.nil?
|
48
|
+
@fks_by_table[table_name.to_s] || []
|
49
|
+
end
|
50
|
+
|
51
|
+
# active record only support 2 column link tables, otherwise use a model table, has_many and through
|
52
|
+
def is_link_table?(table_name)
|
53
|
+
load_schema if @models.nil?
|
54
|
+
return @link_tables[table_name] if ! @link_tables[table_name].nil?
|
55
|
+
column_names = @conn.columns(table_name).map{|x| x.name }
|
56
|
+
@link_tables[table_name] = ! column_names.include?("id") && column_names.length == 2 && column_names.select { |x| x =~ /_id$/ } == column_names
|
57
|
+
return @link_tables[table_name]
|
58
|
+
end
|
59
|
+
|
60
|
+
def link_tables_for_class(klass)
|
61
|
+
load_schema if @models.nil?
|
62
|
+
end
|
63
|
+
|
64
|
+
def load_schema(preload = false)
|
65
|
+
return if !@models.nil?
|
66
|
+
|
67
|
+
@superklass ||= ActiveRecord::Base
|
68
|
+
raise "No database connection" if !(@conn = @superklass.connection)
|
69
|
+
|
70
|
+
@models = ModelHash.new
|
71
|
+
@tables = Hash.new
|
72
|
+
@fks_by_table = Hash.new
|
73
|
+
@link_tables = Hash.new
|
74
|
+
|
75
|
+
@table_names = @conn.tables
|
76
|
+
@table_names = @table_names.grep(/^#{@table_name_prefix}/) if @table_name_prefix
|
77
|
+
@table_names = @table_names.sort
|
78
|
+
|
79
|
+
logger.info "For #{modul} tables are #{@table_names.inspect}"
|
80
|
+
|
81
|
+
# Work out which tables are in the model and which aren't
|
82
|
+
@table_names.each do |table_name|
|
83
|
+
|
84
|
+
# deal with reserved tables & link_tables && other stray id-less tables
|
85
|
+
#key = 'id'
|
86
|
+
#case ActiveRecord::Base.primary_key_prefix_type
|
87
|
+
# when :table_name
|
88
|
+
# key = Inflector.foreign_key(table_name, false)
|
89
|
+
# when :table_name_with_underscore
|
90
|
+
# key = Inflector.foreign_key(table_name)
|
91
|
+
#end
|
92
|
+
#next if ReservedTables.include?(table_name.downcase.to_sym) ||
|
93
|
+
# is_link_table?(table_name) ||
|
94
|
+
# ! @conn.columns(table_name).map{ |x| x.name}.include?(key)
|
95
|
+
|
96
|
+
table_name_clean = table_name.gsub(/^#{@table_name_prefix}/,'')
|
97
|
+
|
98
|
+
# a model table then...
|
99
|
+
model_class_name = inflector.class_name(table_name_clean)
|
100
|
+
|
101
|
+
logger.debug "Got a model table: #{table_name} => class #{model_class_name}"
|
102
|
+
|
103
|
+
@models[model_class_name] = table_name
|
104
|
+
@tables[table_name] = model_class_name
|
105
|
+
|
106
|
+
if preload
|
107
|
+
# create by MAGIC!
|
108
|
+
klass = model_class_name.constantize
|
109
|
+
|
110
|
+
# Process FKs?
|
111
|
+
if @conn.supports_fetch_foreign_keys?
|
112
|
+
|
113
|
+
tables.each do |table_name|
|
114
|
+
logger.debug "Getting FKs for #{table_name}"
|
115
|
+
@fks_by_table[table_name] = Array.new
|
116
|
+
@conn.foreign_key_constraints(table_name).each do |fk|
|
117
|
+
logger.debug "Got one: #{fk}"
|
118
|
+
@fks_by_table[table_name].push(fk)
|
119
|
+
end # do each fk
|
120
|
+
|
121
|
+
end # each table
|
122
|
+
end
|
123
|
+
|
124
|
+
# Try to work out our link tables now...
|
125
|
+
@models.keys.sort.each{|klass| process_table(@models[klass.to_s])}
|
126
|
+
@link_tables.keys.sort.each{|table_name| process_link_table(table_name) if @link_tables[table_name]}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
def process_table(table_name)
|
133
|
+
|
134
|
+
logger.debug "Processing model table #{table_name}"
|
135
|
+
|
136
|
+
# ok, so let's look at the foreign keys on the table...
|
137
|
+
belongs_to_klass = @tables[table_name].constantize rescue return
|
138
|
+
|
139
|
+
processed_columns = Hash.new
|
140
|
+
|
141
|
+
fks_on_table(table_name).each do |fk|
|
142
|
+
logger.debug "Found FK column by suffix _id [#{fk.foreign_key}]"
|
143
|
+
has_some_klass = Inflector.classify(fk.reference_table).constantize rescue next
|
144
|
+
processed_columns[fk.foreign_key] = { :has_some_klass => has_some_klass }
|
145
|
+
processed_columns[fk.foreign_key].merge! add_has_some_belongs_to(belongs_to_klass, fk.foreign_key, has_some_klass) rescue next
|
146
|
+
end
|
147
|
+
|
148
|
+
column_names = @conn.columns(table_name).map{ |x| x.name}
|
149
|
+
column_names.each do |column_name|
|
150
|
+
next if not column_name =~ /_id$/
|
151
|
+
logger.debug "Found FK column by suffix _id [#{column_name}]"
|
152
|
+
if processed_columns.key?(column_name)
|
153
|
+
logger.debug "Skipping, already processed"
|
154
|
+
next
|
155
|
+
end
|
156
|
+
has_some_klass = Inflector.classify(column_name.sub(/_id$/,"")).constantize rescue next
|
157
|
+
processed_columns[column_name] = { :has_some_klass => has_some_klass }
|
158
|
+
processed_columns[column_name].merge! add_has_some_belongs_to(belongs_to_klass, column_name, has_some_klass) rescue next
|
159
|
+
end
|
160
|
+
|
161
|
+
#TODO: what if same classes in table?
|
162
|
+
|
163
|
+
# is this a link table with attributes? (has_many through?)
|
164
|
+
return if processed_columns.keys.length < 2
|
165
|
+
|
166
|
+
processed_columns.keys.each do |key1|
|
167
|
+
processed_columns.keys.each do |key2|
|
168
|
+
next if key1 == key2
|
169
|
+
logger.debug "\n*** #{processed_columns[key1][:has_some_class]}.send 'has_many', #{processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym}, :through => #{processed_columns[key2][:has_some_name]}\n\n"
|
170
|
+
processed_columns[key1][:has_some_class].send 'has_many', processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym, :through => processed_columns[key2][:has_some_name].to_sym
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_has_some_belongs_to(belongs_to_klass, belongs_to_fk, has_some_klass)
|
177
|
+
|
178
|
+
logger.debug "Trying to add a #{belongs_to_klass} belongs_to #{has_some_klass}..."
|
179
|
+
|
180
|
+
# so this is a belongs_to & has_some style relationship...
|
181
|
+
# is it a has_many, or a has_one? Well, let's assume a has_one has a unique index on the column please... good db design, haha!
|
182
|
+
unique = belongs_to_klass.get_unique_index_columns.include?(belongs_to_fk)
|
183
|
+
belongs_to_name = belongs_to_fk.sub(/_id$/, '').to_sym
|
184
|
+
|
185
|
+
logger.debug "\n*** #{belongs_to_klass}.send 'belongs_to', #{belongs_to_name}, :class_name => #{has_some_klass}, :foreign_key => #{belongs_to_fk}\n"
|
186
|
+
belongs_to_klass.send(:belongs_to, belongs_to_name, :class_name => has_some_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
|
187
|
+
|
188
|
+
# work out if we need a prefix
|
189
|
+
has_some_name = (
|
190
|
+
(unique ? belongs_to_klass.table_name.singularize : belongs_to_klass.table_name) +
|
191
|
+
(belongs_to_name.to_s == has_some_klass.table_name.singularize ? "" : "_as_"+belongs_to_name.to_s)
|
192
|
+
).downcase.to_sym
|
193
|
+
method = unique ? :has_one : :has_many
|
194
|
+
logger.debug "\n*** #{has_some_klass}.send(#{method}, #{has_some_name}, :class_name => #{belongs_to_klass.to_s}, :foreign_key => #{belongs_to_fk.to_sym})\n\n"
|
195
|
+
has_some_klass.send(method, has_some_name, :class_name => belongs_to_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
|
196
|
+
|
197
|
+
return { :method => method, :belongs_to_name => belongs_to_name, :has_some_name => has_some_name, :has_some_class => has_some_klass }
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
def process_link_table(table_name)
|
202
|
+
|
203
|
+
logger.debug "Processing link table #{table_name}"
|
204
|
+
|
205
|
+
classes_map = Hash.new
|
206
|
+
column_names = @conn.columns(table_name).map{ |x| x.name}
|
207
|
+
|
208
|
+
# use foreign keys first
|
209
|
+
fks_on_table(table_name).each do |fk|
|
210
|
+
logger.debug "Processing fk: #{fk}"
|
211
|
+
klass = Inflector.classify(fk.reference_table).constantize rescue logger.debug("Cannot find model #{class_name} for table #{fk.reference_table}") && return
|
212
|
+
classes_map[fk.foreign_key] = klass
|
213
|
+
end
|
214
|
+
|
215
|
+
logger.debug "Got #{classes_map.keys.length} references from FKs"
|
216
|
+
|
217
|
+
if classes_map.keys.length < 2
|
218
|
+
|
219
|
+
#Fall back on good ol _id recognition
|
220
|
+
|
221
|
+
column_names.each do |column_name|
|
222
|
+
|
223
|
+
# check we haven't processed by fks already
|
224
|
+
next if ! classes_map[column_name].nil?
|
225
|
+
referenced_table = column_name.sub(/_id$/, '')
|
226
|
+
|
227
|
+
begin
|
228
|
+
klass = Inflector.classify(referenced_table).constantize
|
229
|
+
# fall back on FKs here
|
230
|
+
if ! klass.nil?
|
231
|
+
classes_map[column_name] = klass
|
232
|
+
end
|
233
|
+
rescue
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# not detected the link table?
|
239
|
+
logger.debug "Got #{classes_map.keys.length} references"
|
240
|
+
logger.debug "Cannot detect both tables referenced in link table" && return if classes_map.keys.length != 2
|
241
|
+
|
242
|
+
logger.debug "Adding habtm relationship"
|
243
|
+
|
244
|
+
logger.debug "\n*** #{classes_map[column_names[0]]}.send 'has_and_belongs_to_many', #{column_names[1].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[1]].to_s}, :join_table => #{table_name.to_sym}\n"
|
245
|
+
logger.debug "\n*** #{classes_map[column_names[1]]}.send 'has_and_belongs_to_many', #{column_names[0].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[0]].to_s}, :join_table => #{table_name.to_sym}\n\n"
|
246
|
+
|
247
|
+
classes_map[column_names[0]].send 'has_and_belongs_to_many', column_names[1].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[1]].to_s, :join_table => table_name.to_sym
|
248
|
+
classes_map[column_names[1]].send 'has_and_belongs_to_many', column_names[0].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[0]].to_s, :join_table => table_name.to_sym
|
249
|
+
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
class ModelHash < Hash
|
254
|
+
def unenquire(class_id)
|
255
|
+
@enquired ||= {}
|
256
|
+
@enquired[class_id = class_id.to_s] = false
|
257
|
+
end
|
258
|
+
|
259
|
+
def enquired?(class_id)
|
260
|
+
@enquired ||= {}
|
261
|
+
@enquired[class_id.to_s]
|
262
|
+
end
|
263
|
+
|
264
|
+
def [](class_id)
|
265
|
+
enquired?(class_id = class_id.to_s)
|
266
|
+
@enquired[class_id] = true
|
267
|
+
super(class_id)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module DrNicMagicModels
|
2
|
+
module Validations
|
3
|
+
|
4
|
+
def generate_validations
|
5
|
+
|
6
|
+
logger = DrNicMagicModels::Logger
|
7
|
+
|
8
|
+
# Ensure that the connection to db is established, else validations don't get created.
|
9
|
+
ActiveRecord::Base.connection
|
10
|
+
|
11
|
+
# Code reworked from http://www.redhillconsulting.com.au/rails_plugins.html
|
12
|
+
# Thanks Red Hill Consulting for using an MIT licence :o)
|
13
|
+
|
14
|
+
# NOT NULL constraints
|
15
|
+
self.columns.reject { |column| column.name =~ /(?i)^(((created|updated)_(at|on))|position|type|id)$/ }.each do |column|
|
16
|
+
|
17
|
+
if column.type == :integer
|
18
|
+
logger.debug "validates_numericality_of #{column.name}, :allow_nil => #{column.null.inspect}, :only_integer => true"
|
19
|
+
self.validates_numericality_of column.name, :allow_nil => column.null, :only_integer => true
|
20
|
+
elsif column.number?
|
21
|
+
logger.debug "validates_numericality_of #{column.name}, :allow_nil => #{column.null.inspect}"
|
22
|
+
self.validates_numericality_of column.name, :allow_nil => column.null
|
23
|
+
elsif column.text? && column.limit
|
24
|
+
logger.debug "validates_length_of #{column.name}, :allow_nil => #{column.null.inspect}, :maximum => #{column.limit}"
|
25
|
+
self.validates_length_of column.name, :allow_nil => column.null, :maximum => column.limit
|
26
|
+
end
|
27
|
+
|
28
|
+
# Active record seems to interpolate booleans anyway to either true, false or nil...
|
29
|
+
if column.type == :boolean
|
30
|
+
logger.debug "validates_inclusion_of #{column.name}, :in => [true, false], :allow_nil => #{column.null}, :message => ActiveRecord::Errors.default_error_messages[:blank]"
|
31
|
+
self.validates_inclusion_of column.name, :in => [true, false], :allow_nil => column.null, :message => ActiveRecord::Errors.default_error_messages[:blank]
|
32
|
+
elsif !column.null
|
33
|
+
logger.debug "validates_presence_of #{column.name}"
|
34
|
+
self.validates_presence_of column.name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Single-column UNIQUE indexes
|
39
|
+
get_unique_index_columns.each do |col|
|
40
|
+
logger.debug "validates_uniqueness_of #{col}"
|
41
|
+
self.validates_uniqueness_of col, :allow_nil=>true, :allow_blank=>true
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
unless defined?(ActiveRecord)
|
5
|
+
begin
|
6
|
+
require 'active_record'
|
7
|
+
rescue LoadError
|
8
|
+
require 'rubygems'
|
9
|
+
require_gem 'activerecord'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module DrNicMagicModels
|
14
|
+
Logger = RAILS_DEFAULT_LOGGER rescue Logger.new(STDERR)
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'dr_nic_magic_models/magic_model'
|
18
|
+
require 'dr_nic_magic_models/schema'
|
19
|
+
require 'dr_nic_magic_models/validations'
|
20
|
+
require 'dr_nic_magic_models/inflector'
|
21
|
+
require 'base'
|
22
|
+
require 'module'
|
23
|
+
require 'rails' rescue nil
|
24
|
+
require 'connection_adapters/abstract_adapter'
|
25
|
+
require 'connection_adapters/mysql_adapter'
|
26
|
+
require 'connection_adapters/postgresql_adapter'
|
27
|
+
|
28
|
+
# load the schema
|
29
|
+
# TODO - add this to README - DrNicMagicModels::Schema.load_schema(true)
|
30
|
+
|
31
|
+
class ActiveRecord::Base
|
32
|
+
include DrNicMagicModels::MagicModel
|
33
|
+
extend DrNicMagicModels::Validations
|
34
|
+
end
|
data/lib/module.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
class Module
|
2
|
+
alias :normal_const_missing :const_missing
|
3
|
+
|
4
|
+
def const_missing(class_id)
|
5
|
+
begin
|
6
|
+
return normal_const_missing(class_id)
|
7
|
+
rescue
|
8
|
+
end
|
9
|
+
@magic_schema ||= DrNicMagicModels::Schema.new self
|
10
|
+
unless table_name = @magic_schema.models[class_id]
|
11
|
+
raise NameError.new("uninitialized constant #{class_id}") if @magic_schema.models.enquired? class_id
|
12
|
+
end
|
13
|
+
superklass = @magic_schema.superklass || ActiveRecord::Base
|
14
|
+
klass = create_class(class_id, superklass) do
|
15
|
+
set_table_name table_name
|
16
|
+
# include DrNicMagicModels::MagicModel
|
17
|
+
# extend DrNicMagicModels::Validations
|
18
|
+
end
|
19
|
+
klass.generate_validations # need to call this AFTER the class name has been assigned
|
20
|
+
@magic_schema.inflector.post_class_creation klass
|
21
|
+
klass
|
22
|
+
end
|
23
|
+
|
24
|
+
def magic_module(options)
|
25
|
+
self.instance_variable_set "@table_name_prefix", options[:table_name_prefix] if options[:table_name_prefix]
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def create_class(class_name, superclass, &block)
|
30
|
+
klass = Class.new superclass, &block
|
31
|
+
self.const_set class_name, klass
|
32
|
+
end
|
33
|
+
end
|
data/lib/rails.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Dependencies #:nodoc:#
|
2
|
+
|
3
|
+
@@models_dir = File.expand_path(File.join(RAILS_ROOT,'app','models'))
|
4
|
+
|
5
|
+
# don't reload models... it doesn't work anyway, not sure why they haven't done this?
|
6
|
+
# submit as patch?
|
7
|
+
alias require_or_load_old require_or_load
|
8
|
+
def require_or_load(file_name, *args)
|
9
|
+
file_name = $1 if file_name =~ /^(.*)\.rb$/
|
10
|
+
expanded = File.expand_path(file_name)
|
11
|
+
old_mechanism = Dependencies.mechanism
|
12
|
+
if expanded =~ /^#{@@models_dir}/
|
13
|
+
RAILS_DEFAULT_LOGGER.debug "*** Not reloading #{file_name}"
|
14
|
+
Dependencies.mechanism = :require
|
15
|
+
end
|
16
|
+
require_or_load_old(file_name, *args)
|
17
|
+
Dependencies.mechanism = old_mechanism
|
18
|
+
end
|
19
|
+
end
|
data/scripts/txt2html
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redcloth'
|
5
|
+
require 'syntax/convertors/html'
|
6
|
+
require 'erb'
|
7
|
+
require File.dirname(__FILE__) + '/../lib/dr_nic_magic_models/version.rb'
|
8
|
+
|
9
|
+
version = DrNicMagicModels::VERSION::STRING
|
10
|
+
download = 'http://rubyforge.org/projects/magicmodels'
|
11
|
+
|
12
|
+
class Fixnum
|
13
|
+
def ordinal
|
14
|
+
# teens
|
15
|
+
return 'th' if (10..19).include?(self % 100)
|
16
|
+
# others
|
17
|
+
case self % 10
|
18
|
+
when 1: return 'st'
|
19
|
+
when 2: return 'nd'
|
20
|
+
when 3: return 'rd'
|
21
|
+
else return 'th'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Time
|
27
|
+
def pretty
|
28
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def convert_syntax(syntax, source)
|
33
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
34
|
+
end
|
35
|
+
|
36
|
+
if ARGV.length >= 1
|
37
|
+
src, template = ARGV
|
38
|
+
template ||= File.dirname(__FILE__) + '/../website/template.rhtml'
|
39
|
+
else
|
40
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
41
|
+
exit!
|
42
|
+
end
|
43
|
+
|
44
|
+
template = ERB.new(File.open(template).read)
|
45
|
+
|
46
|
+
title = nil
|
47
|
+
body = nil
|
48
|
+
File.open(src) do |fsrc|
|
49
|
+
title_text = fsrc.readline
|
50
|
+
body_text = fsrc.read
|
51
|
+
syntax_items = []
|
52
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
53
|
+
ident = syntax_items.length
|
54
|
+
element, syntax, source = $1, $2, $3
|
55
|
+
syntax_items << "<#{element} class=\"syntax\">#{convert_syntax(syntax, source)}</#{element}>"
|
56
|
+
"syntax-temp-#{ident}"
|
57
|
+
}
|
58
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
59
|
+
body = RedCloth.new(body_text).to_html
|
60
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
61
|
+
end
|
62
|
+
stat = File.stat(src)
|
63
|
+
created = stat.ctime
|
64
|
+
modified = stat.mtime
|
65
|
+
|
66
|
+
$stdout << template.result(binding)
|
data/scripts/txt2js
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redcloth'
|
5
|
+
require 'syntax/convertors/html'
|
6
|
+
require 'erb'
|
7
|
+
require 'active_support'
|
8
|
+
require File.dirname(__FILE__) + '/../lib/dr_nic_magic_models/version.rb'
|
9
|
+
|
10
|
+
version = DrNicMagicModels::VERSION::STRING
|
11
|
+
download = 'http://rubyforge.org/projects/magicmodels'
|
12
|
+
|
13
|
+
class Fixnum
|
14
|
+
def ordinal
|
15
|
+
# teens
|
16
|
+
return 'th' if (10..19).include?(self % 100)
|
17
|
+
# others
|
18
|
+
case self % 10
|
19
|
+
when 1: return 'st'
|
20
|
+
when 2: return 'nd'
|
21
|
+
when 3: return 'rd'
|
22
|
+
else return 'th'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Time
|
28
|
+
def pretty
|
29
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def convert_syntax(syntax, source)
|
34
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
35
|
+
end
|
36
|
+
|
37
|
+
if ARGV.length >= 1
|
38
|
+
src, template = ARGV
|
39
|
+
template ||= File.dirname(__FILE__) + '/../website/template.js'
|
40
|
+
else
|
41
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
42
|
+
exit!
|
43
|
+
end
|
44
|
+
|
45
|
+
template = ERB.new(File.open(template).read)
|
46
|
+
|
47
|
+
title = nil
|
48
|
+
body = nil
|
49
|
+
File.open(src) do |fsrc|
|
50
|
+
title_text = fsrc.readline
|
51
|
+
body = fsrc.read
|
52
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
53
|
+
end
|
54
|
+
stat = File.stat(src)
|
55
|
+
created = stat.ctime
|
56
|
+
modified = stat.mtime
|
57
|
+
|
58
|
+
$stdout << template.result(binding)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'active_record'
|
6
|
+
require 'active_record/fixtures'
|
7
|
+
require 'connection'
|
8
|
+
require 'dr_nic_magic_models'
|
9
|
+
|
10
|
+
ActiveSupport::Deprecation.debug = true
|
11
|
+
|
12
|
+
|
13
|
+
QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Object.const_defined?(:QUOTED_TYPE)
|
14
|
+
|
15
|
+
class Test::Unit::TestCase #:nodoc:
|
16
|
+
self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
17
|
+
self.use_instantiated_fixtures = false
|
18
|
+
self.use_transactional_fixtures = true #(ENV['AR_NO_TX_FIXTURES'] != "yes")
|
19
|
+
|
20
|
+
def create_fixtures(*table_names, &block)
|
21
|
+
Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names, {}, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def assert_date_from_db(expected, actual, message = nil)
|
25
|
+
# SQL Server doesn't have a separate column type just for dates,
|
26
|
+
# so the time is in the string and incorrectly formatted
|
27
|
+
if current_adapter?(:SQLServerAdapter)
|
28
|
+
assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
|
29
|
+
elsif current_adapter?(:SybaseAdapter)
|
30
|
+
assert_equal expected.to_s, actual.to_date.to_s, message
|
31
|
+
else
|
32
|
+
assert_equal expected.to_s, actual.to_s, message
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def assert_queries(num = 1)
|
37
|
+
ActiveRecord::Base.connection.class.class_eval do
|
38
|
+
self.query_count = 0
|
39
|
+
alias_method :execute, :execute_with_query_counting
|
40
|
+
end
|
41
|
+
yield
|
42
|
+
ensure
|
43
|
+
ActiveRecord::Base.connection.class.class_eval do
|
44
|
+
alias_method :execute, :execute_without_query_counting
|
45
|
+
end
|
46
|
+
assert_equal num, ActiveRecord::Base.connection.query_count, "#{ActiveRecord::Base.connection.query_count} instead of #{num} queries were executed."
|
47
|
+
end
|
48
|
+
|
49
|
+
def assert_no_queries(&block)
|
50
|
+
assert_queries(0, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def current_adapter?(type)
|
56
|
+
ActiveRecord::ConnectionAdapters.const_defined?(type) &&
|
57
|
+
ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters.const_get(type))
|
58
|
+
end
|
59
|
+
|
60
|
+
ActiveRecord::Base.connection.class.class_eval do
|
61
|
+
cattr_accessor :query_count
|
62
|
+
alias_method :execute_without_query_counting, :execute
|
63
|
+
def execute_with_query_counting(sql, name = nil)
|
64
|
+
self.query_count += 1
|
65
|
+
execute_without_query_counting(sql, name)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
70
|
+
#ActiveRecord::Base.colorize_logging = false
|
@@ -0,0 +1,14 @@
|
|
1
|
+
print "Using native MySQL\n"
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
6
|
+
db1 = "dr_nic_magic_models_unittest"
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection(
|
9
|
+
:adapter => "mysql",
|
10
|
+
:username => "root",
|
11
|
+
:password => "",
|
12
|
+
:encoding => "utf8",
|
13
|
+
:database => db1
|
14
|
+
)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
print "Using Postgres\n"
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
6
|
+
db1 = "dr_nic_magic_models_unittest"
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection(
|
9
|
+
:adapter => "postgresql",
|
10
|
+
:encoding => "utf8",
|
11
|
+
:database => db1
|
12
|
+
)
|
data/test/dummy_test.rb
ADDED
data/test/env_test.rb
ADDED
File without changes
|