dm-core 0.10.2 → 1.0.0.rc1

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 (183) hide show
  1. data/.gitignore +10 -1
  2. data/Gemfile +143 -0
  3. data/Rakefile +9 -5
  4. data/VERSION +1 -1
  5. data/dm-core.gemspec +160 -57
  6. data/lib/dm-core.rb +131 -56
  7. data/lib/dm-core/adapters.rb +98 -14
  8. data/lib/dm-core/adapters/abstract_adapter.rb +24 -4
  9. data/lib/dm-core/adapters/in_memory_adapter.rb +7 -2
  10. data/lib/dm-core/associations/many_to_many.rb +19 -30
  11. data/lib/dm-core/associations/many_to_one.rb +58 -42
  12. data/lib/dm-core/associations/one_to_many.rb +33 -23
  13. data/lib/dm-core/associations/one_to_one.rb +27 -11
  14. data/lib/dm-core/associations/relationship.rb +4 -4
  15. data/lib/dm-core/collection.rb +23 -16
  16. data/lib/dm-core/core_ext/array.rb +36 -0
  17. data/lib/dm-core/core_ext/hash.rb +30 -0
  18. data/lib/dm-core/core_ext/module.rb +46 -0
  19. data/lib/dm-core/core_ext/object.rb +31 -0
  20. data/lib/dm-core/core_ext/pathname.rb +20 -0
  21. data/lib/dm-core/core_ext/string.rb +22 -0
  22. data/lib/dm-core/core_ext/try_dup.rb +44 -0
  23. data/lib/dm-core/model.rb +88 -27
  24. data/lib/dm-core/model/hook.rb +75 -18
  25. data/lib/dm-core/model/property.rb +50 -9
  26. data/lib/dm-core/model/relationship.rb +31 -31
  27. data/lib/dm-core/model/scope.rb +3 -3
  28. data/lib/dm-core/property.rb +196 -516
  29. data/lib/dm-core/property/binary.rb +7 -0
  30. data/lib/dm-core/property/boolean.rb +35 -0
  31. data/lib/dm-core/property/class.rb +24 -0
  32. data/lib/dm-core/property/date.rb +47 -0
  33. data/lib/dm-core/property/date_time.rb +48 -0
  34. data/lib/dm-core/property/decimal.rb +43 -0
  35. data/lib/dm-core/property/discriminator.rb +48 -0
  36. data/lib/dm-core/property/float.rb +24 -0
  37. data/lib/dm-core/property/integer.rb +32 -0
  38. data/lib/dm-core/property/numeric.rb +43 -0
  39. data/lib/dm-core/property/object.rb +32 -0
  40. data/lib/dm-core/property/serial.rb +8 -0
  41. data/lib/dm-core/property/string.rb +49 -0
  42. data/lib/dm-core/property/text.rb +12 -0
  43. data/lib/dm-core/property/time.rb +48 -0
  44. data/lib/dm-core/property/typecast/numeric.rb +32 -0
  45. data/lib/dm-core/property/typecast/time.rb +28 -0
  46. data/lib/dm-core/property_set.rb +10 -4
  47. data/lib/dm-core/query.rb +14 -37
  48. data/lib/dm-core/query/conditions/comparison.rb +8 -6
  49. data/lib/dm-core/query/conditions/operation.rb +33 -2
  50. data/lib/dm-core/query/operator.rb +2 -5
  51. data/lib/dm-core/query/path.rb +4 -6
  52. data/lib/dm-core/repository.rb +21 -6
  53. data/lib/dm-core/resource.rb +316 -133
  54. data/lib/dm-core/resource/state.rb +79 -0
  55. data/lib/dm-core/resource/state/clean.rb +40 -0
  56. data/lib/dm-core/resource/state/deleted.rb +30 -0
  57. data/lib/dm-core/resource/state/dirty.rb +86 -0
  58. data/lib/dm-core/resource/state/immutable.rb +34 -0
  59. data/lib/dm-core/resource/state/persisted.rb +29 -0
  60. data/lib/dm-core/resource/state/transient.rb +70 -0
  61. data/lib/dm-core/spec/lib/adapter_helpers.rb +52 -0
  62. data/lib/dm-core/spec/lib/collection_helpers.rb +20 -0
  63. data/{spec → lib/dm-core/spec}/lib/counter_adapter.rb +5 -1
  64. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  65. data/lib/dm-core/spec/lib/spec_helper.rb +68 -0
  66. data/lib/dm-core/spec/setup.rb +165 -0
  67. data/lib/dm-core/spec/{adapter_shared_spec.rb → shared/adapter_spec.rb} +21 -7
  68. data/{spec/public/shared/resource_shared_spec.rb → lib/dm-core/spec/shared/resource_spec.rb} +120 -83
  69. data/{spec/public/shared/sel_shared_spec.rb → lib/dm-core/spec/shared/sel_spec.rb} +5 -6
  70. data/lib/dm-core/support/assertions.rb +8 -0
  71. data/lib/dm-core/support/equalizer.rb +1 -0
  72. data/lib/dm-core/support/hook.rb +420 -0
  73. data/lib/dm-core/support/lazy_array.rb +453 -0
  74. data/lib/dm-core/support/local_object_space.rb +12 -0
  75. data/lib/dm-core/support/logger.rb +193 -6
  76. data/lib/dm-core/support/naming_conventions.rb +8 -8
  77. data/lib/dm-core/support/subject.rb +33 -0
  78. data/lib/dm-core/type.rb +4 -0
  79. data/lib/dm-core/types/boolean.rb +2 -0
  80. data/lib/dm-core/types/decimal.rb +9 -0
  81. data/lib/dm-core/types/discriminator.rb +2 -0
  82. data/lib/dm-core/types/object.rb +3 -0
  83. data/lib/dm-core/types/serial.rb +2 -0
  84. data/lib/dm-core/types/text.rb +2 -0
  85. data/lib/dm-core/version.rb +1 -1
  86. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +67 -0
  87. data/spec/public/model/hook_spec.rb +209 -0
  88. data/spec/public/model/property_spec.rb +35 -0
  89. data/spec/public/model/relationship_spec.rb +33 -20
  90. data/spec/public/model_spec.rb +142 -10
  91. data/spec/public/property/binary_spec.rb +14 -0
  92. data/spec/public/property/boolean_spec.rb +14 -0
  93. data/spec/public/property/class_spec.rb +20 -0
  94. data/spec/public/property/date_spec.rb +14 -0
  95. data/spec/public/property/date_time_spec.rb +14 -0
  96. data/spec/public/property/decimal_spec.rb +14 -0
  97. data/spec/public/{types → property}/discriminator_spec.rb +2 -12
  98. data/spec/public/property/float_spec.rb +14 -0
  99. data/spec/public/property/integer_spec.rb +14 -0
  100. data/spec/public/property/object_spec.rb +9 -17
  101. data/spec/public/property/serial_spec.rb +14 -0
  102. data/spec/public/property/string_spec.rb +14 -0
  103. data/spec/public/property/text_spec.rb +52 -0
  104. data/spec/public/property/time_spec.rb +14 -0
  105. data/spec/public/property_spec.rb +28 -87
  106. data/spec/public/resource_spec.rb +101 -0
  107. data/spec/public/sel_spec.rb +5 -15
  108. data/spec/public/shared/collection_shared_spec.rb +16 -30
  109. data/spec/public/shared/finder_shared_spec.rb +2 -4
  110. data/spec/public/shared/property_shared_spec.rb +176 -0
  111. data/spec/semipublic/adapters/abstract_adapter_spec.rb +1 -1
  112. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +2 -2
  113. data/spec/semipublic/associations/many_to_many_spec.rb +89 -0
  114. data/spec/semipublic/associations/many_to_one_spec.rb +24 -1
  115. data/spec/semipublic/associations/one_to_many_spec.rb +51 -0
  116. data/spec/semipublic/associations/one_to_one_spec.rb +49 -0
  117. data/spec/semipublic/associations/relationship_spec.rb +3 -3
  118. data/spec/semipublic/associations_spec.rb +1 -1
  119. data/spec/semipublic/property/binary_spec.rb +13 -0
  120. data/spec/semipublic/property/boolean_spec.rb +65 -0
  121. data/spec/semipublic/property/class_spec.rb +33 -0
  122. data/spec/semipublic/property/date_spec.rb +43 -0
  123. data/spec/semipublic/property/date_time_spec.rb +46 -0
  124. data/spec/semipublic/property/decimal_spec.rb +82 -0
  125. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  126. data/spec/semipublic/property/float_spec.rb +82 -0
  127. data/spec/semipublic/property/integer_spec.rb +82 -0
  128. data/spec/semipublic/property/serial_spec.rb +13 -0
  129. data/spec/semipublic/property/string_spec.rb +13 -0
  130. data/spec/semipublic/property/text_spec.rb +31 -0
  131. data/spec/semipublic/property/time_spec.rb +50 -0
  132. data/spec/semipublic/property_spec.rb +2 -532
  133. data/spec/semipublic/query/conditions/comparison_spec.rb +171 -169
  134. data/spec/semipublic/query/conditions/operation_spec.rb +53 -51
  135. data/spec/semipublic/query/path_spec.rb +17 -17
  136. data/spec/semipublic/query_spec.rb +47 -78
  137. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  138. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  139. data/spec/semipublic/resource/state/dirty_spec.rb +133 -0
  140. data/spec/semipublic/resource/state/immutable_spec.rb +99 -0
  141. data/spec/semipublic/resource/state/transient_spec.rb +128 -0
  142. data/spec/semipublic/resource/state_spec.rb +226 -0
  143. data/spec/semipublic/shared/property_shared_spec.rb +143 -0
  144. data/spec/semipublic/shared/resource_shared_spec.rb +16 -15
  145. data/spec/semipublic/shared/resource_state_shared_spec.rb +78 -0
  146. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  147. data/spec/spec_helper.rb +21 -97
  148. data/spec/support/types/huge_integer.rb +17 -0
  149. data/spec/unit/array_spec.rb +48 -0
  150. data/spec/unit/hash_spec.rb +35 -0
  151. data/spec/unit/hook_spec.rb +1234 -0
  152. data/spec/unit/lazy_array_spec.rb +1959 -0
  153. data/spec/unit/module_spec.rb +70 -0
  154. data/spec/unit/object_spec.rb +37 -0
  155. data/spec/unit/try_dup_spec.rb +45 -0
  156. data/tasks/local_gemfile.rake +18 -0
  157. data/tasks/spec.rake +0 -3
  158. metadata +197 -71
  159. data/deps.rip +0 -2
  160. data/lib/dm-core/adapters/data_objects_adapter.rb +0 -712
  161. data/lib/dm-core/adapters/mysql_adapter.rb +0 -42
  162. data/lib/dm-core/adapters/oracle_adapter.rb +0 -229
  163. data/lib/dm-core/adapters/postgres_adapter.rb +0 -22
  164. data/lib/dm-core/adapters/sqlite3_adapter.rb +0 -17
  165. data/lib/dm-core/adapters/sqlserver_adapter.rb +0 -114
  166. data/lib/dm-core/adapters/yaml_adapter.rb +0 -111
  167. data/lib/dm-core/core_ext/enumerable.rb +0 -28
  168. data/lib/dm-core/migrations.rb +0 -1427
  169. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +0 -366
  170. data/lib/dm-core/transaction.rb +0 -508
  171. data/lib/dm-core/types/paranoid_boolean.rb +0 -42
  172. data/lib/dm-core/types/paranoid_datetime.rb +0 -41
  173. data/spec/lib/adapter_helpers.rb +0 -105
  174. data/spec/lib/collection_helpers.rb +0 -18
  175. data/spec/lib/pending_helpers.rb +0 -46
  176. data/spec/public/migrations_spec.rb +0 -503
  177. data/spec/public/transaction_spec.rb +0 -153
  178. data/spec/semipublic/adapters/mysql_adapter_spec.rb +0 -17
  179. data/spec/semipublic/adapters/oracle_adapter_spec.rb +0 -194
  180. data/spec/semipublic/adapters/postgres_adapter_spec.rb +0 -17
  181. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +0 -17
  182. data/spec/semipublic/adapters/sqlserver_adapter_spec.rb +0 -17
  183. data/spec/semipublic/adapters/yaml_adapter_spec.rb +0 -12
@@ -0,0 +1,7 @@
1
+ module DataMapper
2
+ class Property
3
+ class Binary < String
4
+ include PassThroughLoadDump
5
+ end # class Binary
6
+ end # class Property
7
+ end # module DataMapper
@@ -0,0 +1,35 @@
1
+ module DataMapper
2
+ class Property
3
+ class Boolean < Object
4
+ include PassThroughLoadDump
5
+
6
+ primitive ::TrueClass
7
+
8
+ def primitive?(value)
9
+ value == true || value == false
10
+ end
11
+
12
+ # Typecast a value to a true or false
13
+ #
14
+ # @param [Integer, #to_str] value
15
+ # value to typecast
16
+ #
17
+ # @return [Boolean]
18
+ # true or false constructed from value
19
+ #
20
+ # @api private
21
+ def typecast_to_primitive(value)
22
+ if value.kind_of?(::Integer)
23
+ return true if value == 1
24
+ return false if value == 0
25
+ elsif value.respond_to?(:to_str)
26
+ string_value = value.to_str.downcase
27
+ return true if %w[ true 1 t ].include?(string_value)
28
+ return false if %w[ false 0 f ].include?(string_value)
29
+ end
30
+
31
+ value
32
+ end
33
+ end # class Boolean
34
+ end # class Property
35
+ end # module DataMapper
@@ -0,0 +1,24 @@
1
+ module DataMapper
2
+ class Property
3
+ class Class < Object
4
+ include PassThroughLoadDump
5
+
6
+ primitive ::Class
7
+
8
+ # Typecast a value to a Class
9
+ #
10
+ # @param [#to_s] value
11
+ # value to typecast
12
+ #
13
+ # @return [Class]
14
+ # Class constructed from value
15
+ #
16
+ # @api private
17
+ def typecast_to_primitive(value)
18
+ model.find_const(value.to_s)
19
+ rescue NameError
20
+ value
21
+ end
22
+ end # class Class
23
+ end # class Property
24
+ end # module DataMapper
@@ -0,0 +1,47 @@
1
+ require 'dm-core/property/typecast/time'
2
+
3
+ module DataMapper
4
+ class Property
5
+ class Date < Object
6
+ include PassThroughLoadDump
7
+ include Typecast::Time
8
+
9
+ primitive ::Date
10
+
11
+ # Typecasts an arbitrary value to a Date
12
+ # Handles both Hashes and Date instances.
13
+ #
14
+ # @param [#to_mash, #to_s] value
15
+ # value to be typecast
16
+ #
17
+ # @return [Date]
18
+ # Date constructed from value
19
+ #
20
+ # @api private
21
+ def typecast_to_primitive(value)
22
+ if value.respond_to?(:to_date)
23
+ value.to_date
24
+ elsif value.respond_to?(:to_mash)
25
+ typecast_hash_to_date(value)
26
+ else
27
+ ::Date.parse(value.to_s)
28
+ end
29
+ rescue ArgumentError
30
+ value
31
+ end
32
+
33
+ # Creates a Date instance from a Hash with keys :year, :month, :day
34
+ #
35
+ # @param [#to_mash] value
36
+ # value to be typecast
37
+ #
38
+ # @return [Date]
39
+ # Date constructed from hash
40
+ #
41
+ # @api private
42
+ def typecast_hash_to_date(value)
43
+ ::Date.new(*extract_time(value)[0, 3])
44
+ end
45
+ end # class Date
46
+ end # class Property
47
+ end # module DataMapper
@@ -0,0 +1,48 @@
1
+ require 'dm-core/property/typecast/time'
2
+
3
+ module DataMapper
4
+ class Property
5
+ class DateTime < Object
6
+ include PassThroughLoadDump
7
+ include Typecast::Time
8
+
9
+ primitive ::DateTime
10
+
11
+ # Typecasts an arbitrary value to a DateTime.
12
+ # Handles both Hashes and DateTime instances.
13
+ #
14
+ # @param [#to_mash, #to_s] value
15
+ # value to be typecast
16
+ #
17
+ # @return [DateTime]
18
+ # DateTime constructed from value
19
+ #
20
+ # @api private
21
+ def typecast_to_primitive(value)
22
+ if value.respond_to?(:to_datetime)
23
+ value.to_datetime
24
+ elsif value.respond_to?(:to_mash)
25
+ typecast_hash_to_datetime(value)
26
+ else
27
+ ::DateTime.parse(value.to_s)
28
+ end
29
+ rescue ArgumentError
30
+ value
31
+ end
32
+
33
+ # Creates a DateTime instance from a Hash with keys :year, :month, :day,
34
+ # :hour, :min, :sec
35
+ #
36
+ # @param [#to_mash] value
37
+ # value to be typecast
38
+ #
39
+ # @return [DateTime]
40
+ # DateTime constructed from hash
41
+ #
42
+ # @api private
43
+ def typecast_hash_to_datetime(value)
44
+ ::DateTime.new(*extract_time(value))
45
+ end
46
+ end # class DateTime
47
+ end # class Property
48
+ end # module DataMapper
@@ -0,0 +1,43 @@
1
+ module DataMapper
2
+ class Property
3
+ class Decimal < Numeric
4
+ primitive BigDecimal
5
+
6
+ DEFAULT_SCALE = 0
7
+
8
+ protected
9
+
10
+ def initialize(model, name, options = {}, type = nil)
11
+ super
12
+
13
+ unless @scale.nil?
14
+ unless @scale >= 0
15
+ raise ArgumentError, "scale must be equal to or greater than 0, but was #{@scale.inspect}"
16
+ end
17
+
18
+ unless @precision >= @scale
19
+ raise ArgumentError, "precision must be equal to or greater than scale, but was #{@precision.inspect} and scale was #{scale_inspect}"
20
+ end
21
+ end
22
+ end
23
+
24
+ # Typecast a value to a BigDecimal
25
+ #
26
+ # @param [#to_str, #to_d, Integer] value
27
+ # value to typecast
28
+ #
29
+ # @return [BigDecimal]
30
+ # BigDecimal constructed from value
31
+ #
32
+ # @api private
33
+ def typecast_to_primitive(value)
34
+ if value.kind_of?(::Integer)
35
+ # TODO: remove this case when Integer#to_d added by extlib
36
+ value.to_s.to_d
37
+ else
38
+ typecast_to_numeric(value, :to_d)
39
+ end
40
+ end
41
+ end # class Decimal
42
+ end # class Property
43
+ end # module DataMapper
@@ -0,0 +1,48 @@
1
+ module DataMapper
2
+ class Property
3
+ class Discriminator < Class
4
+ include PassThroughLoadDump
5
+
6
+ default lambda { |resource, property| resource.model }
7
+ required true
8
+
9
+ # @api private
10
+ def bind
11
+ model.default_scope(repository_name).update(name => model.descendants)
12
+
13
+ model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
+ extend Chainable
15
+
16
+ extendable do
17
+ def inherited(model)
18
+ super # setup self.descendants
19
+ set_discriminator_scope_for(model)
20
+ end
21
+
22
+ def new(*args, &block)
23
+ if args.size == 1 && args.first.kind_of?(Hash)
24
+ discriminator = properties(repository_name).discriminator
25
+
26
+ if discriminator_value = args.first[discriminator.name]
27
+ model = discriminator.typecast_to_primitive(discriminator_value)
28
+
29
+ if model.kind_of?(Model) && !model.equal?(self)
30
+ return model.new(*args, &block)
31
+ end
32
+ end
33
+ end
34
+
35
+ super
36
+ end
37
+
38
+ private
39
+
40
+ def set_discriminator_scope_for(model)
41
+ model.default_scope(#{repository_name.inspect}).update(#{name.inspect} => model.descendants)
42
+ end
43
+ end
44
+ RUBY
45
+ end
46
+ end # class Discriminator
47
+ end # module Types
48
+ end # module DataMapper
@@ -0,0 +1,24 @@
1
+ module DataMapper
2
+ class Property
3
+ class Float < Numeric
4
+ primitive ::Float
5
+
6
+ DEFAULT_SCALE = nil
7
+
8
+ protected
9
+
10
+ # Typecast a value to a Float
11
+ #
12
+ # @param [#to_str, #to_f] value
13
+ # value to typecast
14
+ #
15
+ # @return [Float]
16
+ # Float constructed from value
17
+ #
18
+ # @api private
19
+ def typecast_to_primitive(value)
20
+ typecast_to_numeric(value, :to_f)
21
+ end
22
+ end # class Float
23
+ end # class Property
24
+ end # module DataMapper
@@ -0,0 +1,32 @@
1
+ module DataMapper
2
+ class Property
3
+ class Integer < Numeric
4
+ primitive ::Integer
5
+
6
+ accept_options :serial
7
+
8
+ protected
9
+
10
+ # @api semipublic
11
+ def initialize(model, name, options = {}, type = nil)
12
+ if options.key?(:serial) && !kind_of?(Serial)
13
+ warn "Integer #{name} with explicit :serial option is deprecated, use Serial instead (#{caller[2]})"
14
+ end
15
+ super
16
+ end
17
+
18
+ # Typecast a value to an Integer
19
+ #
20
+ # @param [#to_str, #to_i] value
21
+ # value to typecast
22
+ #
23
+ # @return [Integer]
24
+ # Integer constructed from value
25
+ #
26
+ # @api private
27
+ def typecast_to_primitive(value)
28
+ typecast_to_numeric(value, :to_i)
29
+ end
30
+ end # class Integer
31
+ end # class Property
32
+ end # module DataMapper
@@ -0,0 +1,43 @@
1
+ require 'dm-core/property/typecast/numeric'
2
+
3
+ module DataMapper
4
+ class Property
5
+ class Numeric < Object
6
+ include PassThroughLoadDump
7
+ include Typecast::Numeric
8
+
9
+ accept_options :precision, :scale, :min, :max
10
+ attr_reader :precision, :scale, :min, :max
11
+
12
+ DEFAULT_PRECISION = 10
13
+ DEFAULT_NUMERIC_MIN = 0
14
+ DEFAULT_NUMERIC_MAX = 2**31-1
15
+
16
+ protected
17
+
18
+ def initialize(model, name, options = {}, type = nil)
19
+ super
20
+
21
+ if [ BigDecimal, ::Float ].include?(@primitive)
22
+ @precision = @options.fetch(:precision, DEFAULT_PRECISION)
23
+ @scale = @options.fetch(:scale, self.class::DEFAULT_SCALE)
24
+
25
+ unless @precision > 0
26
+ raise ArgumentError, "precision must be greater than 0, but was #{@precision.inspect}"
27
+ end
28
+ end
29
+
30
+ if (@options.keys & [ :min, :max ]).any?
31
+ @min = @options.fetch(:min, DEFAULT_NUMERIC_MIN)
32
+ @max = @options.fetch(:max, DEFAULT_NUMERIC_MAX)
33
+
34
+ if @max < DEFAULT_NUMERIC_MIN && !@options.key?(:min)
35
+ raise ArgumentError, "min should be specified when the max is less than #{DEFAULT_NUMERIC_MIN}"
36
+ elsif @max < @min
37
+ raise ArgumentError, "max must be less than the min, but was #{@max} while the min was #{@min}"
38
+ end
39
+ end
40
+ end
41
+ end # class Numeric
42
+ end # class Property
43
+ end # module DataMapper
@@ -0,0 +1,32 @@
1
+ module DataMapper
2
+ class Property
3
+ class Object < Property
4
+ primitive ::Object
5
+
6
+ # @api semipublic
7
+ def dump(value)
8
+ return value if value.nil?
9
+
10
+ if @type
11
+ @type.dump(value, self)
12
+ else
13
+ [ Marshal.dump(value) ].pack('m')
14
+ end
15
+ end
16
+
17
+ # @api semipublic
18
+ def load(value)
19
+ if @type
20
+ return @type.load(value, self)
21
+ end
22
+
23
+ case value
24
+ when ::String
25
+ Marshal.load(value.unpack('m').first)
26
+ when ::Object
27
+ value
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ module DataMapper
2
+ class Property
3
+ class Serial < Integer
4
+ serial true
5
+ min 1
6
+ end # class Text
7
+ end # module Types
8
+ end # module DataMapper
@@ -0,0 +1,49 @@
1
+ module DataMapper
2
+ class Property
3
+ class String < Object
4
+ include PassThroughLoadDump
5
+
6
+ primitive ::String
7
+
8
+ accept_options :length
9
+
10
+ DEFAULT_LENGTH = 50
11
+
12
+ # Returns maximum property length (if applicable).
13
+ # This usually only makes sense when property is of
14
+ # type Range or custom
15
+ #
16
+ # @return [Integer, nil]
17
+ # the maximum length of this property
18
+ #
19
+ # @api semipublic
20
+ def length
21
+ if @length.kind_of?(Range)
22
+ @length.max
23
+ else
24
+ @length
25
+ end
26
+ end
27
+
28
+ protected
29
+
30
+ def initialize(model, name, options = {}, type = nil)
31
+ super
32
+ @length = @options.fetch(:length, DEFAULT_LENGTH)
33
+ end
34
+
35
+ # Typecast a value to a String
36
+ #
37
+ # @param [#to_s] value
38
+ # value to typecast
39
+ #
40
+ # @return [String]
41
+ # String constructed from value
42
+ #
43
+ # @api private
44
+ def typecast_to_primitive(value)
45
+ value.to_s
46
+ end
47
+ end # class String
48
+ end # class Property
49
+ end # module DataMapper