mack-data_mapper 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/lib/gems/addressable-2.0.0/lib/addressable/idna.rb +4867 -0
  2. data/lib/gems/addressable-2.0.0/lib/addressable/uri.rb +2469 -0
  3. data/lib/gems/addressable-2.0.0/lib/addressable/version.rb +35 -0
  4. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/adapters/data_objects_adapter.rb +85 -0
  5. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/aggregate_functions.rb +201 -0
  6. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/collection.rb +11 -0
  7. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/model.rb +11 -0
  8. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/repository.rb +7 -0
  9. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/support/symbol.rb +21 -0
  10. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates/version.rb +7 -0
  11. data/lib/gems/dm-aggregates-0.9.7/lib/dm-aggregates.rb +15 -0
  12. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/abstract_adapter.rb +209 -0
  13. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/data_objects_adapter.rb +709 -0
  14. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  15. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/mysql_adapter.rb +136 -0
  16. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/postgres_adapter.rb +188 -0
  17. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
  18. data/lib/gems/dm-core-0.9.7/lib/dm-core/adapters.rb +22 -0
  19. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_many.rb +147 -0
  20. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/many_to_one.rb +107 -0
  21. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_many.rb +318 -0
  22. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/one_to_one.rb +61 -0
  23. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship.rb +223 -0
  24. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations/relationship_chain.rb +81 -0
  25. data/lib/gems/dm-core-0.9.7/lib/dm-core/associations.rb +200 -0
  26. data/lib/gems/dm-core-0.9.7/lib/dm-core/auto_migrations.rb +105 -0
  27. data/lib/gems/dm-core-0.9.7/lib/dm-core/collection.rb +642 -0
  28. data/lib/gems/dm-core-0.9.7/lib/dm-core/dependency_queue.rb +32 -0
  29. data/lib/gems/dm-core-0.9.7/lib/dm-core/hook.rb +11 -0
  30. data/lib/gems/dm-core-0.9.7/lib/dm-core/identity_map.rb +42 -0
  31. data/lib/gems/dm-core-0.9.7/lib/dm-core/is.rb +16 -0
  32. data/lib/gems/dm-core-0.9.7/lib/dm-core/logger.rb +232 -0
  33. data/lib/gems/dm-core-0.9.7/lib/dm-core/migrations/destructive_migrations.rb +17 -0
  34. data/lib/gems/dm-core-0.9.7/lib/dm-core/migrator.rb +29 -0
  35. data/lib/gems/dm-core-0.9.7/lib/dm-core/model.rb +488 -0
  36. data/lib/gems/dm-core-0.9.7/lib/dm-core/naming_conventions.rb +84 -0
  37. data/lib/gems/dm-core-0.9.7/lib/dm-core/property.rb +663 -0
  38. data/lib/gems/dm-core-0.9.7/lib/dm-core/property_set.rb +169 -0
  39. data/lib/gems/dm-core-0.9.7/lib/dm-core/query.rb +628 -0
  40. data/lib/gems/dm-core-0.9.7/lib/dm-core/repository.rb +159 -0
  41. data/lib/gems/dm-core-0.9.7/lib/dm-core/resource.rb +637 -0
  42. data/lib/gems/dm-core-0.9.7/lib/dm-core/scope.rb +58 -0
  43. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/array.rb +13 -0
  44. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/assertions.rb +8 -0
  45. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/errors.rb +23 -0
  46. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/kernel.rb +11 -0
  47. data/lib/gems/dm-core-0.9.7/lib/dm-core/support/symbol.rb +41 -0
  48. data/lib/gems/dm-core-0.9.7/lib/dm-core/support.rb +7 -0
  49. data/lib/gems/dm-core-0.9.7/lib/dm-core/transaction.rb +267 -0
  50. data/lib/gems/dm-core-0.9.7/lib/dm-core/type.rb +160 -0
  51. data/lib/gems/dm-core-0.9.7/lib/dm-core/type_map.rb +80 -0
  52. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/boolean.rb +7 -0
  53. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/discriminator.rb +34 -0
  54. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/object.rb +24 -0
  55. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_boolean.rb +34 -0
  56. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/paranoid_datetime.rb +33 -0
  57. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/serial.rb +9 -0
  58. data/lib/gems/dm-core-0.9.7/lib/dm-core/types/text.rb +10 -0
  59. data/lib/gems/dm-core-0.9.7/lib/dm-core/types.rb +19 -0
  60. data/lib/gems/dm-core-0.9.7/lib/dm-core/version.rb +3 -0
  61. data/lib/gems/dm-core-0.9.7/lib/dm-core.rb +217 -0
  62. data/lib/gems/dm-core-0.9.7/script/all +5 -0
  63. data/lib/gems/dm-core-0.9.7/script/performance.rb +284 -0
  64. data/lib/gems/dm-core-0.9.7/script/profile.rb +87 -0
  65. data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations/version.rb +5 -0
  66. data/lib/gems/dm-migrations-0.9.7/lib/dm-migrations.rb +1 -0
  67. data/lib/gems/dm-migrations-0.9.7/lib/migration.rb +215 -0
  68. data/lib/gems/dm-migrations-0.9.7/lib/migration_runner.rb +88 -0
  69. data/lib/gems/dm-migrations-0.9.7/lib/spec/example/migration_example_group.rb +73 -0
  70. data/lib/gems/dm-migrations-0.9.7/lib/spec/matchers/migration_matchers.rb +107 -0
  71. data/lib/gems/dm-migrations-0.9.7/lib/sql/column.rb +9 -0
  72. data/lib/gems/dm-migrations-0.9.7/lib/sql/mysql.rb +52 -0
  73. data/lib/gems/dm-migrations-0.9.7/lib/sql/postgresql.rb +78 -0
  74. data/lib/gems/dm-migrations-0.9.7/lib/sql/sqlite3.rb +43 -0
  75. data/lib/gems/dm-migrations-0.9.7/lib/sql/table.rb +19 -0
  76. data/lib/gems/dm-migrations-0.9.7/lib/sql/table_creator.rb +81 -0
  77. data/lib/gems/dm-migrations-0.9.7/lib/sql/table_modifier.rb +53 -0
  78. data/lib/gems/dm-migrations-0.9.7/lib/sql.rb +10 -0
  79. data/lib/gems/dm-observer-0.9.7/lib/dm-observer/version.rb +5 -0
  80. data/lib/gems/dm-observer-0.9.7/lib/dm-observer.rb +91 -0
  81. data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer/version.rb +5 -0
  82. data/lib/gems/dm-serializer-0.9.7/lib/dm-serializer.rb +183 -0
  83. data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps/version.rb +5 -0
  84. data/lib/gems/dm-timestamps-0.9.7/lib/dm-timestamps.rb +57 -0
  85. data/lib/gems/dm-types-0.9.7/lib/dm-types/bcrypt_hash.rb +31 -0
  86. data/lib/gems/dm-types-0.9.7/lib/dm-types/csv.rb +28 -0
  87. data/lib/gems/dm-types-0.9.7/lib/dm-types/enum.rb +70 -0
  88. data/lib/gems/dm-types-0.9.7/lib/dm-types/epoch_time.rb +27 -0
  89. data/lib/gems/dm-types-0.9.7/lib/dm-types/file_path.rb +27 -0
  90. data/lib/gems/dm-types-0.9.7/lib/dm-types/flag.rb +61 -0
  91. data/lib/gems/dm-types-0.9.7/lib/dm-types/ip_address.rb +30 -0
  92. data/lib/gems/dm-types-0.9.7/lib/dm-types/json.rb +40 -0
  93. data/lib/gems/dm-types-0.9.7/lib/dm-types/regexp.rb +20 -0
  94. data/lib/gems/dm-types-0.9.7/lib/dm-types/serial.rb +8 -0
  95. data/lib/gems/dm-types-0.9.7/lib/dm-types/slug.rb +37 -0
  96. data/lib/gems/dm-types-0.9.7/lib/dm-types/uri.rb +29 -0
  97. data/lib/gems/dm-types-0.9.7/lib/dm-types/uuid.rb +64 -0
  98. data/lib/gems/dm-types-0.9.7/lib/dm-types/version.rb +5 -0
  99. data/lib/gems/dm-types-0.9.7/lib/dm-types/yaml.rb +36 -0
  100. data/lib/gems/dm-types-0.9.7/lib/dm-types.rb +28 -0
  101. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/absent_field_validator.rb +60 -0
  102. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/acceptance_validator.rb +76 -0
  103. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/auto_validate.rb +153 -0
  104. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/block_validator.rb +60 -0
  105. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/confirmation_validator.rb +80 -0
  106. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/contextual_validators.rb +56 -0
  107. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/custom_validator.rb +72 -0
  108. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/format_validator.rb +97 -0
  109. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/email.rb +40 -0
  110. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/formats/url.rb +20 -0
  111. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/generic_validator.rb +100 -0
  112. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/length_validator.rb +113 -0
  113. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/method_validator.rb +68 -0
  114. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/numeric_validator.rb +83 -0
  115. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/primitive_validator.rb +60 -0
  116. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/required_field_validator.rb +88 -0
  117. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/support/object.rb +5 -0
  118. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/uniqueness_validator.rb +64 -0
  119. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/validation_errors.rb +63 -0
  120. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/version.rb +5 -0
  121. data/lib/gems/dm-validations-0.9.7/lib/dm-validations/within_validator.rb +53 -0
  122. data/lib/gems/dm-validations-0.9.7/lib/dm-validations.rb +234 -0
  123. data/lib/gems/json_pure-1.1.3/GPL +340 -0
  124. data/lib/gems/json_pure-1.1.3/VERSION +1 -0
  125. data/lib/gems/json_pure-1.1.3/bin/edit_json.rb +10 -0
  126. data/lib/gems/json_pure-1.1.3/bin/prettify_json.rb +76 -0
  127. data/lib/gems/json_pure-1.1.3/lib/json/Array.xpm +21 -0
  128. data/lib/gems/json_pure-1.1.3/lib/json/FalseClass.xpm +21 -0
  129. data/lib/gems/json_pure-1.1.3/lib/json/Hash.xpm +21 -0
  130. data/lib/gems/json_pure-1.1.3/lib/json/Key.xpm +73 -0
  131. data/lib/gems/json_pure-1.1.3/lib/json/NilClass.xpm +21 -0
  132. data/lib/gems/json_pure-1.1.3/lib/json/Numeric.xpm +28 -0
  133. data/lib/gems/json_pure-1.1.3/lib/json/String.xpm +96 -0
  134. data/lib/gems/json_pure-1.1.3/lib/json/TrueClass.xpm +21 -0
  135. data/lib/gems/json_pure-1.1.3/lib/json/add/core.rb +135 -0
  136. data/lib/gems/json_pure-1.1.3/lib/json/add/rails.rb +58 -0
  137. data/lib/gems/json_pure-1.1.3/lib/json/common.rb +354 -0
  138. data/lib/gems/json_pure-1.1.3/lib/json/editor.rb +1362 -0
  139. data/lib/gems/json_pure-1.1.3/lib/json/ext.rb +13 -0
  140. data/lib/gems/json_pure-1.1.3/lib/json/json.xpm +1499 -0
  141. data/lib/gems/json_pure-1.1.3/lib/json/pure/generator.rb +394 -0
  142. data/lib/gems/json_pure-1.1.3/lib/json/pure/parser.rb +259 -0
  143. data/lib/gems/json_pure-1.1.3/lib/json/pure.rb +75 -0
  144. data/lib/gems/json_pure-1.1.3/lib/json/version.rb +9 -0
  145. data/lib/gems/json_pure-1.1.3/lib/json.rb +235 -0
  146. data/lib/gems/launchy-0.3.2/bin/launchy +12 -0
  147. data/lib/gems/launchy-0.3.2/lib/launchy/application.rb +163 -0
  148. data/lib/gems/launchy-0.3.2/lib/launchy/browser.rb +85 -0
  149. data/lib/gems/launchy-0.3.2/lib/launchy/command_line.rb +48 -0
  150. data/lib/gems/launchy-0.3.2/lib/launchy/gemspec.rb +53 -0
  151. data/lib/gems/launchy-0.3.2/lib/launchy/specification.rb +133 -0
  152. data/lib/gems/launchy-0.3.2/lib/launchy/version.rb +18 -0
  153. data/lib/gems/launchy-0.3.2/lib/launchy.rb +58 -0
  154. data/lib/gems/uuidtools-1.0.3/lib/uuidtools/version.rb +32 -0
  155. data/lib/gems/uuidtools-1.0.3/lib/uuidtools.rb +648 -0
  156. data/lib/gems.rb +13 -0
  157. data/lib/mack-data_mapper/migration_generator/migration_generator.rb +5 -0
  158. data/lib/mack-data_mapper/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +1 -1
  159. data/lib/mack-data_mapper/model_generator/manifest.yml +3 -3
  160. data/lib/mack-data_mapper/model_generator/model_generator.rb +8 -1
  161. data/lib/mack-data_mapper/model_generator/templates/model.rb.template +1 -1
  162. data/lib/mack-data_mapper/model_generator/templates/rspec.rb.template +1 -1
  163. data/lib/mack-data_mapper/model_generator/templates/test_case.rb.template +1 -1
  164. data/lib/mack-data_mapper.rb +3 -2
  165. data/lib/mack-data_mapper_tasks.rb +7 -0
  166. metadata +235 -86
@@ -0,0 +1,81 @@
1
+ module SQL
2
+ class TableCreator
3
+ attr_accessor :table_name, :opts
4
+
5
+ def initialize(adapter, table_name, opts = {}, &block)
6
+ @adapter = adapter
7
+ @table_name = table_name.to_s
8
+ @opts = opts
9
+
10
+ @columns = []
11
+
12
+ self.instance_eval &block
13
+ end
14
+
15
+ def quoted_table_name
16
+ @adapter.send(:quote_table_name, table_name)
17
+ end
18
+
19
+ def column(name, type, opts = {})
20
+ @columns << Column.new(@adapter, name, type, opts)
21
+ end
22
+
23
+ def to_sql
24
+ "CREATE TABLE #{quoted_table_name} (#{@columns.map{ |c| c.to_sql }.join(', ')})"
25
+ end
26
+
27
+ # A helper for using the native NOW() SQL function in a default
28
+ def now
29
+ SqlExpr.new('NOW()')
30
+ end
31
+
32
+ # A helper for using the native UUID() SQL function in a default
33
+ def uuid
34
+ SqlExpr.new('UUID()')
35
+ end
36
+
37
+ class SqlExpr
38
+ attr_accessor :sql
39
+ def initialize(sql)
40
+ @sql = sql
41
+ end
42
+
43
+ def to_s
44
+ @sql.to_s
45
+ end
46
+ end
47
+
48
+ class Column
49
+ attr_accessor :name, :type
50
+
51
+ def initialize(adapter, name, type, opts = {})
52
+ @adapter = adapter
53
+ @name = name.to_s
54
+ @opts = opts
55
+ @type = build_type(type)
56
+ end
57
+
58
+ def build_type(type_class)
59
+ schema = {:name => @name, :quote_column_name => quoted_name}.merge(@opts)
60
+ schema[:serial?] ||= schema[:serial]
61
+ schema[:nullable?] ||= schema[:nullable] || !schema[:not_null]
62
+ if type_class.is_a?(String)
63
+ schema[:primitive] = type_class
64
+ else
65
+ schema = @adapter.class.type_map[type_class].merge(schema)
66
+ end
67
+ @adapter.property_schema_statement(schema)
68
+ end
69
+
70
+ def to_sql
71
+ type
72
+ end
73
+
74
+ def quoted_name
75
+ @adapter.send(:quote_column_name, name)
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,53 @@
1
+ module SQL
2
+ class TableModifier
3
+ attr_accessor :table_name, :opts, :statements, :adapter
4
+
5
+ def initialize(adapter, table_name, opts = {}, &block)
6
+ @adapter = adapter
7
+ @table_name = table_name.to_s
8
+ @opts = (opts)
9
+
10
+ @statements = []
11
+
12
+ self.instance_eval &block
13
+ end
14
+
15
+ def add_column(name, type, opts = {})
16
+ column = SQL::TableCreator::Column.new(@adapter, name, type, opts)
17
+ @statements << "ALTER TABLE #{quoted_table_name} ADD COLUMN #{column.to_sql}"
18
+ end
19
+
20
+ def drop_column(name)
21
+ # raise NotImplemented for SQLite3. Can't ALTER TABLE, need to copy table.
22
+ # We'd have to inspect it, and we can't, since we aren't executing any queries yet.
23
+ # TODO instead of building the SQL queries when executing the block, create AddColumn,
24
+ # AlterColumn and DropColumn objects that get #to_sql'd
25
+ if name.is_a?(Array)
26
+ name.each{ |n| drop_column(n) }
27
+ else
28
+ @statements << "ALTER TABLE #{quoted_table_name} DROP COLUMN #{quote_column_name(name)}"
29
+ end
30
+ end
31
+ alias drop_columns drop_column
32
+
33
+ def rename_column(name, new_name, opts = {})
34
+ # raise NotImplemented for SQLite3
35
+ @statements << "ALTER TABLE #{quoted_table_name} RENAME COLUMN #{quote_column_name(name)} TO #{quote_column_name(new_name)}"
36
+ end
37
+
38
+ def change_column(name, type, opts = {})
39
+ # raise NotImplemented for SQLite3
40
+ @statements << "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(name)} TYPE #{type}"
41
+ end
42
+
43
+ def quote_column_name(name)
44
+ @adapter.send(:quote_column_name, name.to_s)
45
+ end
46
+
47
+ def quoted_table_name
48
+ @adapter.send(:quote_table_name, table_name)
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/sql/table_creator'
2
+ require File.dirname(__FILE__) + '/sql/table_modifier'
3
+
4
+ require File.dirname(__FILE__) + '/sql/sqlite3'
5
+ require File.dirname(__FILE__) + '/sql/mysql'
6
+ require File.dirname(__FILE__) + '/sql/postgresql'
7
+
8
+ module SQL
9
+
10
+ end
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Observer
3
+ VERSION = "0.9.7"
4
+ end
5
+ end
@@ -0,0 +1,91 @@
1
+ module DataMapper
2
+ # Observers allow you to add callback hooks to DataMapper::Resource objects
3
+ # in a separate class. This is great for separating out logic that is not
4
+ # really part of the model, but needs to be triggered by a model, or models.
5
+ module Observer
6
+
7
+ def self.included(klass)
8
+ klass.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ attr_accessor :observing
14
+
15
+ def initialize
16
+ self.observing = []
17
+ end
18
+
19
+ # Assign an Array of Class names to watch.
20
+ # observe User, Article, Topic
21
+ def observe(*args)
22
+ # puts "#{self.to_s} observing... #{args.collect{|c| Extlib::Inflection.classify(c.to_s)}.join(', ')}"
23
+ self.observing = args
24
+ end
25
+
26
+ def before(sym, &block)
27
+ self.observing.each do |klass|
28
+ klass.before(sym.to_sym, &block)
29
+ end
30
+ end
31
+
32
+ def after(sym, &block)
33
+ self.observing.each do |klass|
34
+ klass.after(sym.to_sym, &block)
35
+ end
36
+ end
37
+
38
+ def before_class_method(sym, &block)
39
+ self.observing.each do |klass|
40
+ klass.before_class_method(sym.to_sym, &block)
41
+ end
42
+ end
43
+
44
+ def after_class_method(sym, &block)
45
+ self.observing.each do |klass|
46
+ klass.after_class_method(sym.to_sym, &block)
47
+ end
48
+ end
49
+
50
+ end # ClassMethods
51
+
52
+ end # Observer
53
+ end # DataMapper
54
+
55
+ if $0 == __FILE__
56
+ require 'rubygems'
57
+
58
+ gem 'dm-core', '~>0.9.7'
59
+ require 'dm-core'
60
+
61
+ FileUtils.touch(File.join(Dir.pwd, "migration_test.db"))
62
+ DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/migration_test.db")
63
+
64
+ class Foo
65
+ include DataMapper::Resource
66
+
67
+ property :id, Integer, :serial => true
68
+ property :bar, Text
69
+ end
70
+
71
+ Foo.auto_migrate!
72
+
73
+ class FooObserver
74
+ include DataMapper::Observer
75
+
76
+ observe :foo
77
+
78
+ before :save do
79
+ raise "Hell!" if self.bar.nil?
80
+ puts "hi"
81
+ end
82
+
83
+ after :save do
84
+ puts "bye"
85
+ end
86
+
87
+ end
88
+
89
+ Foo.new(:bar => "hello").save
90
+
91
+ end
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Serializer
3
+ VERSION = "0.9.7"
4
+ end
5
+ end
@@ -0,0 +1,183 @@
1
+ require Pathname('rexml/document')
2
+
3
+ begin
4
+ require 'faster_csv'
5
+ rescue LoadError
6
+ nil
7
+ end
8
+
9
+ begin
10
+ require Pathname('json/ext')
11
+ rescue LoadError
12
+ require Pathname('json/pure')
13
+ end
14
+
15
+ module DataMapper
16
+ module Serialize
17
+
18
+ # Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)
19
+ #
20
+ # @return <String> a JSON representation of the Resource
21
+ def to_json(options = {})
22
+ result = '{ '
23
+ fields = []
24
+
25
+ # FIXME: this should go into bunch of protected methods shared with other serialization methods
26
+ only_properties = Array(options[:only])
27
+ excluded_properties = Array(options[:exclude])
28
+ exclude_read_only = options[:without_read_only_attributes] || false
29
+
30
+ propset = self.class.properties(repository.name).reject do |p|
31
+ next if only_properties.include? p.name
32
+ excluded_properties.include?(p.name) || !(only_properties.empty? || only_properties.include?(p.name))
33
+ end
34
+
35
+ fields += propset.map do |property|
36
+ "#{property.name.to_json}: #{send(property.getter).to_json}"
37
+ end
38
+
39
+ if self.respond_to?(:serialize_properties)
40
+ self.serialize_properties.each do |k,v|
41
+ fields << "#{k.to_json}: #{v.to_json}"
42
+ end
43
+ end
44
+
45
+ if self.class.respond_to?(:read_only_attributes) && exclude_read_only
46
+ self.class.read_only_attributes.each do |property|
47
+ fields << "#{property.to_json}: #{send(property).to_json}"
48
+ end
49
+ end
50
+
51
+ # add methods
52
+ (options[:methods] || []).each do |meth|
53
+ if self.respond_to?(meth)
54
+ fields << "#{meth.to_json}: #{send(meth).to_json}"
55
+ end
56
+ end
57
+
58
+ # Note: if you want to include a whole other model via relation, use :methods
59
+ # comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
60
+ # add relationships
61
+ (options[:relationships] || {}).each do |rel,opts|
62
+ if self.respond_to?(rel)
63
+ fields << "#{rel.to_json}: #{send(rel).to_json(opts)}"
64
+ end
65
+ end
66
+
67
+ result << fields.join(', ')
68
+ result << ' }'
69
+ result
70
+ end
71
+
72
+ # Serialize a Resource to comma-separated values (CSV).
73
+ #
74
+ # @return <String> a CSV representation of the Resource
75
+ def to_csv(writer = '')
76
+ FasterCSV.generate(writer) do |csv|
77
+ row = []
78
+ self.class.properties(repository.name).each do |property|
79
+ row << send(property.name).to_s
80
+ end
81
+ csv << row
82
+ end
83
+ end
84
+
85
+ # Serialize a Resource to XML
86
+ #
87
+ # @return <REXML::Document> an XML representation of this Resource
88
+ def to_xml(opts = {})
89
+
90
+ to_xml_document(opts).to_s
91
+ end
92
+
93
+ # Serialize a Resource to YAML
94
+ #
95
+ # @return <YAML> a YAML representation of this Resource
96
+ def to_yaml(opts = {})
97
+ YAML::quick_emit(object_id,opts) do |out|
98
+ out.map(nil,to_yaml_style) do |map|
99
+ self.class.properties(repository.name).each do |property|
100
+ value = send(property.name.to_sym)
101
+ map.add(property.name, value.is_a?(Class) ? value.to_s : value)
102
+ end
103
+ (instance_variable_get("@yaml_addes") || []).each do |k,v|
104
+ map.add(k.to_s,v)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ protected
111
+
112
+ # Return the name of this Resource - to be used as the root element name.
113
+ # This can be overloaded.
114
+ #
115
+ # @return <String> name of this Resource
116
+ def xml_element_name
117
+ Extlib::Inflection.underscore(self.class.name)
118
+ end
119
+
120
+ # Return a REXML::Document representing this Resource
121
+ #
122
+ # @return <REXML::Document> an XML representation of this Resource
123
+ def to_xml_document(opts={}, doc=nil)
124
+ doc ||= REXML::Document.new
125
+ root = doc.add_element(xml_element_name)
126
+
127
+ #TODO old code base was converting single quote to double quote on attribs
128
+
129
+ self.class.properties(repository.name).each do |property|
130
+ value = send(property.name)
131
+ node = root.add_element(property.name.to_s)
132
+ unless property.type == String
133
+ node.attributes["type"] = property.type.to_s.downcase
134
+ end
135
+ node << REXML::Text.new(value.to_s) unless value.nil?
136
+ end
137
+ doc
138
+ end
139
+
140
+ end # module Serialize
141
+
142
+ module Resource
143
+ include Serialize
144
+ end # module Resource
145
+
146
+ class Collection
147
+ def to_yaml(opts = {})
148
+ to_a.to_yaml(opts)
149
+ end
150
+
151
+ def to_json(opts = {})
152
+ "[" << map {|e| e.to_json(opts)}.join(",") << "]"
153
+ end
154
+
155
+ def to_xml(opts = {})
156
+ to_xml_document(opts).to_s
157
+ end
158
+
159
+ def to_csv
160
+ result = ""
161
+ each do |item|
162
+ result << item.to_csv + "\n"
163
+ end
164
+ result
165
+ end
166
+
167
+ protected
168
+ def xml_element_name
169
+ Extlib::Inflection.tableize(self.model.to_s)
170
+ end
171
+
172
+ def to_xml_document(opts={})
173
+ doc = REXML::Document.new
174
+ root = doc.add_element(xml_element_name)
175
+ root.attributes["type"] = 'array'
176
+ each do |item|
177
+ item.send(:to_xml_document, opts, root)
178
+ end
179
+ doc
180
+ end
181
+ end
182
+
183
+ end # module DataMapper
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Timestamps
3
+ VERSION = "0.9.7"
4
+ end
5
+ end
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+
3
+ gem 'dm-core', '~>0.9.7'
4
+ require 'dm-core'
5
+
6
+ module DataMapper
7
+ module Timestamp
8
+ TIMESTAMP_PROPERTIES = {
9
+ :updated_at => lambda { |r| r.updated_at = DateTime.now },
10
+ :updated_on => lambda { |r| r.updated_on = Date.today },
11
+ :created_at => lambda { |r| r.created_at = DateTime.now if r.new_record? && r.created_at.nil? },
12
+ :created_on => lambda { |r| r.created_on = Date.today if r.new_record? && r.created_on.nil?},
13
+ }
14
+
15
+ def self.included(model)
16
+ model.before :save, :set_timestamp_properties
17
+ model.send :extend, ClassMethods
18
+ end
19
+
20
+ private
21
+
22
+ def set_timestamp_properties
23
+ if dirty?
24
+ self.class.properties.slice(*TIMESTAMP_PROPERTIES.keys).compact.each do |property|
25
+ TIMESTAMP_PROPERTIES[property.name][self] unless attribute_dirty?(property.name)
26
+ end
27
+ end
28
+ end
29
+
30
+ module ClassMethods
31
+ def timestamps(*args)
32
+ if args.empty? then raise ArgumentError, "You need to pass at least one argument." end
33
+
34
+ args.each do |ts|
35
+ case ts
36
+ when :at
37
+ property :created_at, DateTime
38
+ property :updated_at, DateTime
39
+ when :on
40
+ property :created_on, Date
41
+ property :updated_on, Date
42
+ else
43
+ unless TIMESTAMP_PROPERTIES.keys.include?(ts)
44
+ raise InvalidTimestampName, "Invalid timestamp property '#{ts}'."
45
+ end
46
+
47
+ property ts, DateTime
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ class InvalidTimestampName < RuntimeError; end
54
+ end # module Timestamp
55
+
56
+ Resource::append_inclusions Timestamp
57
+ end
@@ -0,0 +1,31 @@
1
+
2
+ require 'bcrypt'
3
+
4
+ module DataMapper
5
+ module Types
6
+ class BCryptHash < DataMapper::Type
7
+ primitive String
8
+ size 60
9
+
10
+ def self.load(value, property)
11
+ if value.nil?
12
+ nil
13
+ elsif value.is_a?(String)
14
+ BCrypt::Password.new(value)
15
+ else
16
+ raise ArgumentError.new("+value+ must be nil or a String")
17
+ end
18
+ end
19
+
20
+ def self.dump(value, property)
21
+ if value.nil?
22
+ nil
23
+ elsif value.is_a?(String)
24
+ BCrypt::Password.create(value, :cost => BCrypt::Engine::DEFAULT_COST)
25
+ else
26
+ raise ArgumentError.new("+value+ must be nil or a String")
27
+ end
28
+ end
29
+ end # class BCryptHash
30
+ end # module Types
31
+ end # module DataMapper
@@ -0,0 +1,28 @@
1
+ module DataMapper
2
+ module Types
3
+ class Csv < DataMapper::Type
4
+ primitive String
5
+ size 65535
6
+ lazy true
7
+
8
+ def self.load(value, property)
9
+ case value
10
+ when String then FasterCSV.parse(value)
11
+ when Array then value
12
+ else nil
13
+ end
14
+ end
15
+
16
+ def self.dump(value, property)
17
+ case value
18
+ when Array then
19
+ FasterCSV.generate do |csv|
20
+ value.each { |row| csv << row }
21
+ end
22
+ when String then value
23
+ else nil
24
+ end
25
+ end
26
+ end # class Csv
27
+ end # module Types
28
+ end # module DataMapper
@@ -0,0 +1,70 @@
1
+ module DataMapper
2
+ module Types
3
+ class Enum < DataMapper::Type(Integer)
4
+ def self.inherited(target)
5
+ target.instance_variable_set("@primitive", self.primitive)
6
+ end
7
+
8
+ def self.flag_map
9
+ @flag_map
10
+ end
11
+
12
+ def self.flag_map=(value)
13
+ @flag_map = value
14
+ end
15
+
16
+ def self.new(*flags)
17
+ enum = Class.new(Enum)
18
+ enum.flag_map = {}
19
+
20
+ flags.each_with_index do |flag, i|
21
+ enum.flag_map[i + 1] = flag
22
+ end
23
+
24
+ enum
25
+ end
26
+
27
+ def self.[](*flags)
28
+ new(*flags)
29
+ end
30
+
31
+ def self.load(value, property)
32
+ self.flag_map[value]
33
+ end
34
+
35
+ def self.dump(value, property)
36
+ case value
37
+ when Array then value.collect { |v| self.dump(v, property) }
38
+ else self.flag_map.invert[value]
39
+ end
40
+ end
41
+
42
+ def self.typecast(value, property)
43
+ # Attempt to typecast using the class of the first item in the map.
44
+ return value if value.nil?
45
+ case self.flag_map[1]
46
+ when Symbol then value.to_sym
47
+ when String then value.to_s
48
+ when Fixnum then value.to_i
49
+ else value
50
+ end
51
+ end
52
+ end # class Enum
53
+ end # module Types
54
+
55
+ if defined?(Validate)
56
+ module Validate
57
+ module AutoValidate
58
+ alias :orig_auto_generate_validations :auto_generate_validations
59
+ def auto_generate_validations(property)
60
+ orig_auto_generate_validations(property)
61
+ return unless property.options[:auto_validation]
62
+
63
+ if property.type.ancestors.include?(Types::Enum)
64
+ validates_within property.name, options_with_message({:set => property.type.flag_map.values}, property, :within)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end # module DataMapper
@@ -0,0 +1,27 @@
1
+ module DataMapper
2
+ module Types
3
+ class EpochTime < DataMapper::Type
4
+ primitive Integer
5
+
6
+ def self.load(value, property)
7
+ case value
8
+ when Integer
9
+ Time.at(value)
10
+ else
11
+ value
12
+ end
13
+ end
14
+
15
+ def self.dump(value, property)
16
+ case value
17
+ when Integer
18
+ value
19
+ when Time
20
+ value.to_i
21
+ when DateTime
22
+ Time.parse(value.to_s).to_i
23
+ end
24
+ end
25
+ end # class EpochTime
26
+ end # module Types
27
+ end # module DataMapper
@@ -0,0 +1,27 @@
1
+ require 'pathname'
2
+
3
+ module DataMapper
4
+ module Types
5
+ class FilePath < DataMapper::Type
6
+ primitive String
7
+
8
+ def self.load(value, property)
9
+ if value.nil?
10
+ nil
11
+ else
12
+ Pathname.new(value)
13
+ end
14
+ end
15
+
16
+ def self.dump(value, property)
17
+ return nil if value.nil?
18
+ value.to_s
19
+ end
20
+
21
+ def self.typecast(value, property)
22
+ # Leave alone if a Pathname is given.
23
+ value.kind_of?(Pathname) ? value : load(value, property)
24
+ end
25
+ end # class FilePath
26
+ end # module Types
27
+ end # module DataMapper