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.
Files changed (57) hide show
  1. data/CHANGELOG +9 -0
  2. data/History.txt +33 -0
  3. data/Manifest.txt +56 -0
  4. data/README +0 -0
  5. data/Rakefile +149 -0
  6. data/install.rb +30 -0
  7. data/lib/base.rb +12 -0
  8. data/lib/connection_adapters/abstract/schema_statements.rb +0 -0
  9. data/lib/connection_adapters/abstract_adapter.rb +32 -0
  10. data/lib/connection_adapters/mysql_adapter.rb +42 -0
  11. data/lib/connection_adapters/postgresql_adapter.rb +45 -0
  12. data/lib/dr_nic_magic_models/inflector.rb +14 -0
  13. data/lib/dr_nic_magic_models/magic_model.rb +135 -0
  14. data/lib/dr_nic_magic_models/schema.rb +270 -0
  15. data/lib/dr_nic_magic_models/validations.rb +46 -0
  16. data/lib/dr_nic_magic_models/version.rb +9 -0
  17. data/lib/dr_nic_magic_models.rb +34 -0
  18. data/lib/module.rb +33 -0
  19. data/lib/rails.rb +19 -0
  20. data/scripts/txt2html +66 -0
  21. data/scripts/txt2js +58 -0
  22. data/test/abstract_unit.rb +70 -0
  23. data/test/connections/native_mysql/connection.rb +14 -0
  24. data/test/connections/native_postgresql/connection.rb +12 -0
  25. data/test/connections/native_sqlite/connection.rb +10 -0
  26. data/test/dummy_test.rb +13 -0
  27. data/test/env_test.rb +10 -0
  28. data/test/fixtures/.DS_Store +0 -0
  29. data/test/fixtures/adjectives.yml +3 -0
  30. data/test/fixtures/adjectives_fun_users.yml +3 -0
  31. data/test/fixtures/db_definitions/mysql.drop.sql +4 -0
  32. data/test/fixtures/db_definitions/mysql.sql +58 -0
  33. data/test/fixtures/db_definitions/postgresql.sql +56 -0
  34. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  35. data/test/fixtures/fun_users.yml +14 -0
  36. data/test/fixtures/group_memberships.yml +4 -0
  37. data/test/fixtures/group_tag.yml +11 -0
  38. data/test/fixtures/groups.yml +12 -0
  39. data/test/foreign_keys_test.rb +0 -0
  40. data/test/fun_user_plus.rb +2 -0
  41. data/test/invisible_model_access_test.rb +71 -0
  42. data/test/invisible_model_assoc_test.rb +61 -0
  43. data/test/invisible_model_classes_test.rb +23 -0
  44. data/test/magic_module_test.rb +20 -0
  45. data/test/test_existing_model.rb +20 -0
  46. data/test.db +0 -0
  47. data/website/index.html +409 -0
  48. data/website/index.txt +291 -0
  49. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  50. data/website/stylesheets/screen.css +106 -0
  51. data/website/template.js +3 -0
  52. data/website/template.rhtml +55 -0
  53. data/website/version-raw.js +3 -0
  54. data/website/version-raw.txt +2 -0
  55. data/website/version.js +4 -0
  56. data/website/version.txt +3 -0
  57. 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,9 @@
1
+ module DrNicMagicModels #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 9
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ 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
+ )
@@ -0,0 +1,10 @@
1
+ print "Using native Sqlite3\n"
2
+ require 'logger'
3
+
4
+ ActiveRecord::Base.logger = Logger.new("debug.log")
5
+
6
+ ActiveRecord::Base.establish_connection(
7
+ :adapter => "sqlite3",
8
+ :dbfile => "test.db"
9
+ )
10
+
@@ -0,0 +1,13 @@
1
+ require 'abstract_unit'
2
+ #require 'fixtures/user'
3
+ #require 'fixtures/group'
4
+ #require 'fixtures/membership'
5
+
6
+ class DummyTest < Test::Unit::TestCase
7
+ def setup
8
+ end
9
+
10
+ def test_truth
11
+ assert true
12
+ end
13
+ end
data/test/env_test.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'abstract_unit'
2
+
3
+ class EnvTest < Test::Unit::TestCase
4
+
5
+ def test_modules
6
+ assert_not_nil DrNicMagicModels
7
+ assert_not_nil DrNicMagicModels::Validations
8
+ assert_not_nil DrNicMagicModels::Schema
9
+ end
10
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ first:
2
+ id: 1
3
+ name: kind