ardm-types 1.2.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.
- checksums.yaml +7 -0
- data/.gitignore +36 -0
- data/.travis.yml +11 -0
- data/Gemfile +51 -0
- data/LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +4 -0
- data/ardm-types.gemspec +29 -0
- data/lib/ardm-types.rb +1 -0
- data/lib/dm-types/api_key.rb +30 -0
- data/lib/dm-types/bcrypt_hash.rb +34 -0
- data/lib/dm-types/comma_separated_list.rb +29 -0
- data/lib/dm-types/csv.rb +38 -0
- data/lib/dm-types/enum.rb +51 -0
- data/lib/dm-types/epoch_time.rb +41 -0
- data/lib/dm-types/file_path.rb +32 -0
- data/lib/dm-types/flag.rb +63 -0
- data/lib/dm-types/ip_address.rb +42 -0
- data/lib/dm-types/json.rb +50 -0
- data/lib/dm-types/paranoid/base.rb +55 -0
- data/lib/dm-types/paranoid_boolean.rb +23 -0
- data/lib/dm-types/paranoid_datetime.rb +22 -0
- data/lib/dm-types/regexp.rb +21 -0
- data/lib/dm-types/slug.rb +29 -0
- data/lib/dm-types/support/dirty_minder.rb +166 -0
- data/lib/dm-types/support/flags.rb +41 -0
- data/lib/dm-types/uri.rb +38 -0
- data/lib/dm-types/uuid.rb +74 -0
- data/lib/dm-types/version.rb +5 -0
- data/lib/dm-types/yaml.rb +41 -0
- data/lib/dm-types.rb +23 -0
- data/spec/fixtures/api_user.rb +14 -0
- data/spec/fixtures/article.rb +35 -0
- data/spec/fixtures/bookmark.rb +23 -0
- data/spec/fixtures/invention.rb +7 -0
- data/spec/fixtures/network_node.rb +36 -0
- data/spec/fixtures/person.rb +25 -0
- data/spec/fixtures/software_package.rb +33 -0
- data/spec/fixtures/ticket.rb +21 -0
- data/spec/fixtures/tshirt.rb +24 -0
- data/spec/integration/api_key_spec.rb +27 -0
- data/spec/integration/bcrypt_hash_spec.rb +47 -0
- data/spec/integration/comma_separated_list_spec.rb +87 -0
- data/spec/integration/dirty_minder_spec.rb +197 -0
- data/spec/integration/enum_spec.rb +80 -0
- data/spec/integration/epoch_time_spec.rb +61 -0
- data/spec/integration/file_path_spec.rb +160 -0
- data/spec/integration/flag_spec.rb +72 -0
- data/spec/integration/ip_address_spec.rb +153 -0
- data/spec/integration/json_spec.rb +72 -0
- data/spec/integration/slug_spec.rb +67 -0
- data/spec/integration/uri_spec.rb +139 -0
- data/spec/integration/uuid_spec.rb +102 -0
- data/spec/integration/yaml_spec.rb +69 -0
- data/spec/rcov.opts +6 -0
- data/spec/shared/flags_shared_spec.rb +37 -0
- data/spec/shared/identity_function_group.rb +5 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/unit/bcrypt_hash_spec.rb +155 -0
- data/spec/unit/csv_spec.rb +142 -0
- data/spec/unit/enum_spec.rb +126 -0
- data/spec/unit/epoch_time_spec.rb +74 -0
- data/spec/unit/file_path_spec.rb +87 -0
- data/spec/unit/flag_spec.rb +114 -0
- data/spec/unit/ip_address_spec.rb +121 -0
- data/spec/unit/json_spec.rb +144 -0
- data/spec/unit/paranoid_boolean_spec.rb +150 -0
- data/spec/unit/paranoid_datetime_spec.rb +154 -0
- data/spec/unit/regexp_spec.rb +63 -0
- data/spec/unit/uri_spec.rb +64 -0
- data/spec/unit/uuid_spec.rb +25 -0
- data/spec/unit/yaml_spec.rb +111 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +236 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 64d3d24b7d203fef1dd08c5c63fb97af6e7ffbdd
|
4
|
+
data.tar.gz: 2ce41762914595258f160111247c308b1f32fe99
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e95ea2e08793070c9def64cb04d5cbaa88cfc84ca42c3cff11a25ee05dd1453e74210b1c30fc39a6f747a5a410e721bb84c610e9a74d0ee54be8f758726e0ab0
|
7
|
+
data.tar.gz: 58809ba9545ede43fce6982293d049bc1270cb015d796a4a75683870843b34b0ad3880576033b8c1f1165c0749bfe647ba6aebadd4c3df365728b9607026b4aa
|
data/.gitignore
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
._*
|
4
|
+
|
5
|
+
## TEXTMATE
|
6
|
+
*.tmproj
|
7
|
+
tmtags
|
8
|
+
|
9
|
+
## EMACS
|
10
|
+
*~
|
11
|
+
\#*
|
12
|
+
.\#*
|
13
|
+
|
14
|
+
## VIM
|
15
|
+
*.swp
|
16
|
+
|
17
|
+
## Rubinius
|
18
|
+
*.rbc
|
19
|
+
|
20
|
+
## PROJECT::GENERAL
|
21
|
+
*.gem
|
22
|
+
coverage
|
23
|
+
rdoc
|
24
|
+
pkg
|
25
|
+
tmp
|
26
|
+
doc
|
27
|
+
log
|
28
|
+
.yardoc
|
29
|
+
measurements
|
30
|
+
|
31
|
+
## BUNDLER
|
32
|
+
.bundle
|
33
|
+
Gemfile.*
|
34
|
+
|
35
|
+
## PROJECT::SPECIFIC
|
36
|
+
spec/db/
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
gemspec
|
6
|
+
|
7
|
+
SOURCE = ENV.fetch('SOURCE', :git).to_sym
|
8
|
+
REPO_POSTFIX = SOURCE == :path ? '' : '.git'
|
9
|
+
DATAMAPPER = SOURCE == :path ? Pathname(__FILE__).dirname.parent : 'http://github.com/ar-dm'
|
10
|
+
DM_VERSION = '~> 1.2.0'
|
11
|
+
DO_VERSION = '~> 0.10.6'
|
12
|
+
DM_DO_ADAPTERS = %w[ sqlite postgres mysql oracle sqlserver ]
|
13
|
+
CURRENT_BRANCH = ENV.fetch('GIT_BRANCH', 'master')
|
14
|
+
|
15
|
+
gem 'ardm-core', DM_VERSION, SOURCE => "#{DATAMAPPER}/ardm-core#{REPO_POSTFIX}", :branch => CURRENT_BRANCH
|
16
|
+
|
17
|
+
group :development do
|
18
|
+
gem 'ardm-validations', DM_VERSION, SOURCE => "#{DATAMAPPER}/ardm-validations#{REPO_POSTFIX}", :branch => CURRENT_BRANCH
|
19
|
+
end
|
20
|
+
|
21
|
+
group :datamapper do
|
22
|
+
|
23
|
+
adapters = ENV['ADAPTER'] || ENV['ADAPTERS']
|
24
|
+
adapters = adapters.to_s.tr(',', ' ').split.uniq - %w[ in_memory ]
|
25
|
+
|
26
|
+
if (do_adapters = DM_DO_ADAPTERS & adapters).any?
|
27
|
+
do_options = {}
|
28
|
+
do_options[:git] = "#{DATAMAPPER}/do#{REPO_POSTFIX}" if ENV['DO_GIT'] == 'true'
|
29
|
+
|
30
|
+
gem 'data_objects', DO_VERSION, do_options.dup
|
31
|
+
|
32
|
+
do_adapters.each do |adapter|
|
33
|
+
adapter = 'sqlite3' if adapter == 'sqlite'
|
34
|
+
gem "do_#{adapter}", DO_VERSION, do_options.dup
|
35
|
+
end
|
36
|
+
|
37
|
+
gem 'ardm-do-adapter', DM_VERSION, SOURCE => "#{DATAMAPPER}/ardm-do-adapter#{REPO_POSTFIX}", :branch => CURRENT_BRANCH
|
38
|
+
end
|
39
|
+
|
40
|
+
adapters.each do |adapter|
|
41
|
+
gem "ardm-#{adapter}-adapter", DM_VERSION, SOURCE => "#{DATAMAPPER}/ardm-#{adapter}-adapter#{REPO_POSTFIX}", :branch => CURRENT_BRANCH
|
42
|
+
end
|
43
|
+
|
44
|
+
plugins = ENV['PLUGINS'] || ENV['PLUGIN']
|
45
|
+
plugins = plugins.to_s.tr(',', ' ').split.push('ardm-migrations').uniq
|
46
|
+
|
47
|
+
plugins.each do |plugin|
|
48
|
+
gem plugin, DM_VERSION, SOURCE => "#{DATAMAPPER}/#{plugin}#{REPO_POSTFIX}", :branch => CURRENT_BRANCH
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Sam Smoot, Dan Kubb
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/ardm-types.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/dm-types/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "ardm-types"
|
6
|
+
gem.version = DataMapper::Types::VERSION
|
7
|
+
|
8
|
+
gem.authors = [ 'Martin Emde', 'Dan Kubb' ]
|
9
|
+
gem.email = [ 'me@martinemde.com', "dan.kubb@gmail.com" ]
|
10
|
+
gem.summary = "Ardm fork of dm-types"
|
11
|
+
gem.description = gem.summary
|
12
|
+
gem.homepage = "http://github.com/martinemde/ardm-types"
|
13
|
+
gem.license = "MIT"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split("\n")
|
16
|
+
gem.test_files = `git ls-files -- {spec}/*`.split("\n")
|
17
|
+
gem.extra_rdoc_files = %w[LICENSE README.rdoc]
|
18
|
+
gem.require_paths = [ "lib" ]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency 'ardm-core', '~> 1.2'
|
21
|
+
gem.add_runtime_dependency 'bcrypt', '~> 3.0'
|
22
|
+
gem.add_runtime_dependency 'fastercsv', '~> 1.5'
|
23
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.0'
|
24
|
+
gem.add_runtime_dependency 'stringex', '~> 1.3'
|
25
|
+
gem.add_runtime_dependency 'uuidtools', '~> 2.1'
|
26
|
+
|
27
|
+
gem.add_development_dependency 'rake', '~> 0.9'
|
28
|
+
gem.add_development_dependency 'rspec', '~> 1.3'
|
29
|
+
end
|
data/lib/ardm-types.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'dm-types'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
|
3
|
+
require 'digest/sha1'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
class Property
|
7
|
+
class APIKey < String
|
8
|
+
|
9
|
+
# The amount of random seed data to use to generate tha API Key
|
10
|
+
PADDING = 256
|
11
|
+
|
12
|
+
length 40
|
13
|
+
unique true
|
14
|
+
default proc { APIKey.generate }
|
15
|
+
|
16
|
+
#
|
17
|
+
# Generates a new API Key.
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
# The new API Key.
|
21
|
+
#
|
22
|
+
def self.generate
|
23
|
+
sha1 = Digest::SHA1.new
|
24
|
+
|
25
|
+
PADDING.times { sha1 << rand(256).chr }
|
26
|
+
return sha1.hexdigest
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'bcrypt'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
class Property
|
6
|
+
class BCryptHash < String
|
7
|
+
|
8
|
+
length 60
|
9
|
+
|
10
|
+
def primitive?(value)
|
11
|
+
value.kind_of?(BCrypt::Password)
|
12
|
+
end
|
13
|
+
|
14
|
+
def load(value)
|
15
|
+
unless value.nil?
|
16
|
+
begin
|
17
|
+
primitive?(value) ? value : BCrypt::Password.new(value)
|
18
|
+
rescue BCrypt::Errors::InvalidHash
|
19
|
+
BCrypt::Password.create(value, :cost => BCrypt::Engine::DEFAULT_COST)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def dump(value)
|
25
|
+
load(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def typecast_to_primitive(value)
|
29
|
+
load(value)
|
30
|
+
end
|
31
|
+
|
32
|
+
end # class BCryptHash
|
33
|
+
end # class Property
|
34
|
+
end # module DataMapper
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types/yaml'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
class Property
|
6
|
+
class CommaSeparatedList < Yaml
|
7
|
+
|
8
|
+
def dump(value)
|
9
|
+
if value.nil?
|
10
|
+
nil
|
11
|
+
elsif value.kind_of?(::Array)
|
12
|
+
super(value)
|
13
|
+
elsif value.kind_of?(::String)
|
14
|
+
v = []
|
15
|
+
|
16
|
+
value.split(',').each do |element|
|
17
|
+
element.strip!
|
18
|
+
v << element unless element.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
super(v)
|
22
|
+
else
|
23
|
+
raise ArgumentError, "+value+ of CommaSeparatedList must be a string, an array or nil, but given #{value.inspect}"
|
24
|
+
end
|
25
|
+
end # dump
|
26
|
+
|
27
|
+
end # CommaSeparatedList
|
28
|
+
end # Property
|
29
|
+
end # DataMapper
|
data/lib/dm-types/csv.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types/support/dirty_minder'
|
3
|
+
|
4
|
+
if RUBY_VERSION >= '1.9.0'
|
5
|
+
require 'csv'
|
6
|
+
else
|
7
|
+
require 'fastercsv' # must be ~>1.5
|
8
|
+
CSV = FasterCSV unless defined?(CSV)
|
9
|
+
end
|
10
|
+
|
11
|
+
module DataMapper
|
12
|
+
class Property
|
13
|
+
class Csv < Text
|
14
|
+
|
15
|
+
def primitive?(value)
|
16
|
+
super || value.kind_of?(::Array)
|
17
|
+
end
|
18
|
+
|
19
|
+
def load(value)
|
20
|
+
case value
|
21
|
+
when ::String then CSV.parse(value)
|
22
|
+
when ::Array then value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def dump(value)
|
27
|
+
case value
|
28
|
+
when ::Array
|
29
|
+
CSV.generate { |csv| value.each { |row| csv << row } }
|
30
|
+
when ::String then value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
include ::DataMapper::Property::DirtyMinder
|
35
|
+
|
36
|
+
end # class Csv
|
37
|
+
end # class Property
|
38
|
+
end # module DataMapper
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types/support/flags'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
class Property
|
6
|
+
class Enum < Integer
|
7
|
+
min 1
|
8
|
+
|
9
|
+
include Flags
|
10
|
+
|
11
|
+
def initialize(model, name, options = {})
|
12
|
+
@flag_map = {}
|
13
|
+
|
14
|
+
flags = options.fetch(:flags, self.class.flags)
|
15
|
+
flags.each_with_index do |flag, i|
|
16
|
+
@flag_map[i.succ] = flag
|
17
|
+
end
|
18
|
+
|
19
|
+
if self.class.accepted_options.include?(:set) && !options.include?(:set)
|
20
|
+
options[:set] = @flag_map.values_at(*@flag_map.keys.sort)
|
21
|
+
end
|
22
|
+
|
23
|
+
options[:max] = @flag_map.size
|
24
|
+
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def load(value)
|
29
|
+
flag_map[value]
|
30
|
+
end
|
31
|
+
|
32
|
+
def dump(value)
|
33
|
+
case value
|
34
|
+
when ::Array then value.collect { |v| dump(v) }
|
35
|
+
else flag_map.invert[value]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def typecast_to_primitive(value)
|
40
|
+
# Attempt to typecast using the class of the first item in the map.
|
41
|
+
case flag_map[1]
|
42
|
+
when ::Symbol then value.to_sym
|
43
|
+
when ::String then value.to_s
|
44
|
+
when ::Fixnum then value.to_i
|
45
|
+
else value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end # class Enum
|
50
|
+
end # class Property
|
51
|
+
end # module DataMapper
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
class Property
|
5
|
+
class EpochTime < Integer
|
6
|
+
|
7
|
+
def load(value)
|
8
|
+
if value.kind_of?(::Numeric)
|
9
|
+
::Time.at(value.to_i)
|
10
|
+
else
|
11
|
+
value
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def dump(value)
|
16
|
+
value.to_i if value
|
17
|
+
end
|
18
|
+
|
19
|
+
def custom?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def typecast(value)
|
24
|
+
case value
|
25
|
+
when ::Time then value
|
26
|
+
when ::Numeric, /\A\d+\z/ then ::Time.at(value.to_i)
|
27
|
+
when ::DateTime then datetime_to_time(value)
|
28
|
+
when ::String then ::Time.parse(value)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def datetime_to_time(datetime)
|
35
|
+
utc = datetime.new_offset(0)
|
36
|
+
::Time.utc(utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec)
|
37
|
+
end
|
38
|
+
|
39
|
+
end # class EpochTime
|
40
|
+
end # class Property
|
41
|
+
end # module DataMapper
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'dm-core'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
class Property
|
6
|
+
class FilePath < String
|
7
|
+
|
8
|
+
length 255
|
9
|
+
|
10
|
+
def primitive?(value)
|
11
|
+
value.kind_of?(Pathname)
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?(value, negated = false)
|
15
|
+
super || dump(value).kind_of?(::String)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load(value)
|
19
|
+
Pathname.new(value) unless DataMapper::Ext.blank?(value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def dump(value)
|
23
|
+
value.to_s unless DataMapper::Ext.blank?(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def typecast_to_primitive(value)
|
27
|
+
load(value)
|
28
|
+
end
|
29
|
+
|
30
|
+
end # class FilePath
|
31
|
+
end # class Property
|
32
|
+
end # module DataMapper
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types/support/flags'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
class Property
|
6
|
+
class Flag < Integer
|
7
|
+
|
8
|
+
include Flags
|
9
|
+
|
10
|
+
def initialize(model, name, options = {})
|
11
|
+
super
|
12
|
+
|
13
|
+
@flag_map = {}
|
14
|
+
|
15
|
+
flags = options.fetch(:flags, self.class.flags)
|
16
|
+
flags.each_with_index do |flag, i|
|
17
|
+
flag_map[i] = flag
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def load(value)
|
22
|
+
return [] if value.nil? || value <= 0
|
23
|
+
|
24
|
+
begin
|
25
|
+
matches = []
|
26
|
+
|
27
|
+
0.upto(flag_map.size - 1) do |i|
|
28
|
+
matches << flag_map[i] if value[i] == 1
|
29
|
+
end
|
30
|
+
|
31
|
+
matches.compact
|
32
|
+
rescue TypeError, Errno::EDOM
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def dump(value)
|
38
|
+
unless value.nil?
|
39
|
+
flags = Array(value).map { |flag| flag.to_sym }
|
40
|
+
flags.uniq!
|
41
|
+
|
42
|
+
flag = 0
|
43
|
+
|
44
|
+
flag_map.invert.values_at(*flags).each do |i|
|
45
|
+
next if i.nil?
|
46
|
+
flag += (1 << i)
|
47
|
+
end
|
48
|
+
|
49
|
+
flag
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def typecast(value)
|
54
|
+
case value
|
55
|
+
when nil then nil
|
56
|
+
when ::Array then value.map { |v| v.to_sym }
|
57
|
+
else [value.to_sym]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end # class Flag
|
62
|
+
end # class Property
|
63
|
+
end # module DataMapper
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
require 'dm-core'
|
3
|
+
|
4
|
+
module DataMapper
|
5
|
+
class Property
|
6
|
+
class IPAddress < String
|
7
|
+
|
8
|
+
length 39
|
9
|
+
|
10
|
+
def primitive?(value)
|
11
|
+
value.kind_of?(IPAddr)
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?(value, negated = false)
|
15
|
+
super || dump(value).kind_of?(::String)
|
16
|
+
end
|
17
|
+
|
18
|
+
def load(value)
|
19
|
+
if value.nil?
|
20
|
+
nil
|
21
|
+
elsif value.is_a?(::String)
|
22
|
+
unless value.empty?
|
23
|
+
IPAddr.new(value)
|
24
|
+
else
|
25
|
+
IPAddr.new("0.0.0.0")
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise ArgumentError.new("+value+ must be nil or a String")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def dump(value)
|
33
|
+
value.to_s unless value.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def typecast_to_primitive(value)
|
37
|
+
load(value)
|
38
|
+
end
|
39
|
+
|
40
|
+
end # class IPAddress
|
41
|
+
end # module Property
|
42
|
+
end # module DataMapper
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-types/support/dirty_minder'
|
3
|
+
require 'multi_json'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
class Property
|
7
|
+
class Json < Text
|
8
|
+
|
9
|
+
def custom?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def primitive?(value)
|
14
|
+
value.kind_of?(::Array) || value.kind_of?(::Hash)
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?(value, negated = false)
|
18
|
+
super || dump(value).kind_of?(::String)
|
19
|
+
end
|
20
|
+
|
21
|
+
def load(value)
|
22
|
+
if value.nil?
|
23
|
+
nil
|
24
|
+
elsif value.is_a?(::String)
|
25
|
+
typecast_to_primitive(value)
|
26
|
+
else
|
27
|
+
raise ArgumentError.new("+value+ of a property of JSON type must be nil or a String")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def dump(value)
|
32
|
+
if value.nil? || value.is_a?(::String)
|
33
|
+
value
|
34
|
+
else
|
35
|
+
MultiJson.encode(value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def typecast_to_primitive(value)
|
40
|
+
MultiJson.decode(value.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
include ::DataMapper::Property::DirtyMinder
|
44
|
+
|
45
|
+
end # class Json
|
46
|
+
|
47
|
+
JSON = Json
|
48
|
+
|
49
|
+
end # class Property
|
50
|
+
end # module DataMapper
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Types
|
3
|
+
module Paranoid
|
4
|
+
module Base
|
5
|
+
def self.included(model)
|
6
|
+
model.extend ClassMethods
|
7
|
+
model.instance_variable_set(:@paranoid_properties, {})
|
8
|
+
end
|
9
|
+
|
10
|
+
def paranoid_destroy
|
11
|
+
model.paranoid_properties.each do |name, block|
|
12
|
+
attribute_set(name, block.call(self))
|
13
|
+
end
|
14
|
+
save_self
|
15
|
+
self.persistence_state = Resource::PersistenceState::Immutable.new(self)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def _destroy(execute_hooks = true)
|
23
|
+
return false unless saved?
|
24
|
+
if execute_hooks
|
25
|
+
paranoid_destroy
|
26
|
+
else
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end # module Base
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
def inherited(model)
|
34
|
+
model.instance_variable_set(:@paranoid_properties, @paranoid_properties.dup)
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api public
|
39
|
+
def with_deleted
|
40
|
+
with_exclusive_scope({}) { block_given? ? yield : all }
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
def paranoid_properties
|
45
|
+
@paranoid_properties
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
def set_paranoid_property(name, &block)
|
50
|
+
paranoid_properties[name] = block
|
51
|
+
end
|
52
|
+
end # module ClassMethods
|
53
|
+
end # module Paranoid
|
54
|
+
end # module Types
|
55
|
+
end # module DataMapper
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'dm-types/paranoid/base'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
class Property
|
5
|
+
class ParanoidBoolean < Boolean
|
6
|
+
default false
|
7
|
+
lazy true
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
def bind
|
11
|
+
property_name = name.inspect
|
12
|
+
|
13
|
+
model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
14
|
+
include DataMapper::Types::Paranoid::Base
|
15
|
+
|
16
|
+
set_paranoid_property(#{property_name}) { true }
|
17
|
+
|
18
|
+
default_scope(#{repository_name.inspect}).update(#{property_name} => false)
|
19
|
+
RUBY
|
20
|
+
end
|
21
|
+
end # class ParanoidBoolean
|
22
|
+
end # module Property
|
23
|
+
end # module DataMapper
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'dm-types/paranoid/base'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
class Property
|
5
|
+
class ParanoidDateTime < DateTime
|
6
|
+
lazy true
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
def bind
|
10
|
+
property_name = name.inspect
|
11
|
+
|
12
|
+
model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
13
|
+
include DataMapper::Types::Paranoid::Base
|
14
|
+
|
15
|
+
set_paranoid_property(#{property_name}) { ::DateTime.now }
|
16
|
+
|
17
|
+
default_scope(#{repository_name.inspect}).update(#{property_name} => nil)
|
18
|
+
RUBY
|
19
|
+
end
|
20
|
+
end # class ParanoidDateTime
|
21
|
+
end # module Property
|
22
|
+
end # module DataMapper
|