dm-serializer 0.9.8 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/Manifest.txt +11 -1
- data/README.textile +61 -0
- data/Rakefile +1 -1
- data/benchmarks/to_xml.rb +89 -0
- data/lib/dm-serializer/common.rb +24 -0
- data/lib/dm-serializer/to_csv.rb +35 -0
- data/lib/dm-serializer/to_json.rb +73 -0
- data/lib/dm-serializer/to_xml.rb +61 -0
- data/lib/dm-serializer/to_yaml.rb +48 -0
- data/lib/dm-serializer/version.rb +1 -1
- data/lib/dm-serializer/xml_serializers/libxml.rb +29 -0
- data/lib/dm-serializer/xml_serializers/nokogiri.rb +28 -0
- data/lib/dm-serializer/xml_serializers/rexml.rb +23 -0
- data/lib/dm-serializer/xml_serializers.rb +17 -0
- data/lib/dm-serializer.rb +4 -230
- data/spec/fixtures/cow.rb +0 -4
- data/spec/lib/serialization_method_shared_spec.rb +41 -0
- data/spec/public/to_json_spec.rb +1 -39
- data/spec/public/to_xml_spec.rb +76 -63
- data/spec/public/to_yaml_spec.rb +11 -6
- data/spec/spec_helper.rb +3 -2
- metadata +15 -5
- data/README.txt +0 -3
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 0.9.9 / 2009-01-04
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Uses LibXML or Nokogiri if available for a ~6x improvement in
|
6
|
+
serialization performance.
|
7
|
+
|
8
|
+
* 4 minor enhancements:
|
9
|
+
|
10
|
+
* Added :element_name and :collection_element_name options to #to_xml
|
11
|
+
* Removed #xml_element_name override in #to_xml
|
12
|
+
* Removed :read_only_attributes option from #to_json
|
13
|
+
* Removed #serialized_properties override in #to_json
|
14
|
+
|
1
15
|
=== 0.9.8 / 2008-12-07
|
2
16
|
|
3
17
|
* 2 minor enhancements:
|
data/Manifest.txt
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
History.txt
|
2
2
|
LICENSE
|
3
3
|
Manifest.txt
|
4
|
-
README.
|
4
|
+
README.textile
|
5
5
|
Rakefile
|
6
6
|
TODO
|
7
7
|
autotest/discover.rb
|
8
8
|
autotest/dmserializer_rspec.rb
|
9
|
+
benchmarks/to_xml.rb
|
9
10
|
lib/dm-serializer.rb
|
11
|
+
lib/dm-serializer/common.rb
|
12
|
+
lib/dm-serializer/to_csv.rb
|
13
|
+
lib/dm-serializer/to_json.rb
|
14
|
+
lib/dm-serializer/to_xml.rb
|
15
|
+
lib/dm-serializer/to_yaml.rb
|
10
16
|
lib/dm-serializer/version.rb
|
17
|
+
lib/dm-serializer/xml_serializers.rb
|
18
|
+
lib/dm-serializer/xml_serializers/libxml.rb
|
19
|
+
lib/dm-serializer/xml_serializers/nokogiri.rb
|
20
|
+
lib/dm-serializer/xml_serializers/rexml.rb
|
11
21
|
spec/fixtures/cow.rb
|
12
22
|
spec/fixtures/planet.rb
|
13
23
|
spec/fixtures/quan_tum_cat.rb
|
data/README.textile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
h1. dm-serializer
|
2
|
+
|
3
|
+
h2. Overview
|
4
|
+
|
5
|
+
dm-serializer allows DataMapper models and collections to be serialized to a variety of formats (currently JSON, XML, YAML and CSV).
|
6
|
+
|
7
|
+
h2. How it works
|
8
|
+
|
9
|
+
One method is added to each model/collection for each serialization type - @to_json@, @to_xml@, @to_yaml@, and @to_csv@. With the exception of @to_csv@, all of these methods share the same interface. @to_json@ will be used for examples. Any method specific behaviour is documented in its own section below.
|
10
|
+
|
11
|
+
<pre><code>require 'dm-serializer'
|
12
|
+
|
13
|
+
class Cow
|
14
|
+
include DataMapper::Resource
|
15
|
+
|
16
|
+
property :id, Integer, :key => true
|
17
|
+
property :name, String
|
18
|
+
|
19
|
+
def description
|
20
|
+
"A Cow"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
cow = Cow.create(
|
25
|
+
:id => 1,
|
26
|
+
:name => "Berta"
|
27
|
+
)
|
28
|
+
|
29
|
+
cow.to_json # => { "id": 1, "name": "Berta" }
|
30
|
+
cow.to_json(:only => [:name]) # => { "name": "Berta" }
|
31
|
+
cow.to_json(:exclude => [:id]) # => { "name": "Berta" }
|
32
|
+
cow.to_json(:methods => [:desc]) # => { "id": 1, "name": "Berta", "desc": "A Cow" }</code></pre>
|
33
|
+
|
34
|
+
You can include associations by passing the association accessor the @:methods@ option.
|
35
|
+
|
36
|
+
If you want to only load a particular serialization method, that's cool, you can do that:
|
37
|
+
|
38
|
+
<pre><code>require 'dm-serializer/to_json'</code></pre>
|
39
|
+
|
40
|
+
h2. to_xml
|
41
|
+
|
42
|
+
@to_xml@ supports some extra options to allow you to override the element names
|
43
|
+
|
44
|
+
<pre><code>cow.to_xml( :element_name => 'bovine') # => <bovine><id>1</id><name>Berta</name></bovine>
|
45
|
+
cows.to_xml(:collection_element_name => 'kine') # => <kine><bovine><id>1</id><name>Berta</name></bovine></kine></code></pre>
|
46
|
+
|
47
|
+
If you would like a nice speed boost (~5x), require @libxml@ or @nokogiri@ before @dm-serializer@, and that library will be used rather than REXML.
|
48
|
+
|
49
|
+
h2. to_csv
|
50
|
+
|
51
|
+
@to_csv@ currently doesn't support any options yet. It will in the future. It will not support serializing child associations.
|
52
|
+
|
53
|
+
h2. Arrays, Hashes, and other core classes
|
54
|
+
|
55
|
+
@dm-serializer@ only adds serialization methods to DataMapper objects and collections, however some libraries used (json, yaml) add methods to core classes, such as @Array@. Note that passing @dm-serializer@ options (such as @:only@) to these methods is *not supported*.
|
56
|
+
|
57
|
+
<pre><code>Cow.all.to_a.to_yaml(:only => 'name') # WILL NOT WORK</code></pre>
|
58
|
+
|
59
|
+
h2. Beware
|
60
|
+
|
61
|
+
If you go spelunking through the code you will find other undocumented options. Use at your own risk, I plan on removing or changing these in the near future.
|
data/Rakefile
CHANGED
@@ -14,7 +14,7 @@ GEM_NAME = 'dm-serializer'
|
|
14
14
|
GEM_VERSION = DataMapper::Serializer::VERSION
|
15
15
|
GEM_DEPENDENCIES = [['dm-core', "~>#{GEM_VERSION}"]]
|
16
16
|
GEM_CLEAN = %w[ log pkg coverage ]
|
17
|
-
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.
|
17
|
+
GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.textile LICENSE TODO History.txt ] }
|
18
18
|
|
19
19
|
PROJECT_NAME = 'datamapper'
|
20
20
|
PROJECT_URL = "http://github.com/sam/dm-more/tree/master/#{GEM_NAME}"
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
gem 'dm-core', '~>0.9.9'
|
5
|
+
require 'dm-core'
|
6
|
+
|
7
|
+
spec_dir_path = Pathname(__FILE__).dirname.expand_path
|
8
|
+
$LOAD_PATH.unshift(spec_dir_path.parent + 'lib/')
|
9
|
+
require 'dm-serializer'
|
10
|
+
|
11
|
+
def load_driver(name, default_uri)
|
12
|
+
begin
|
13
|
+
DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
|
14
|
+
DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
|
15
|
+
DataMapper::Repository.adapters[:alternate] = DataMapper::Repository.adapters[name]
|
16
|
+
true
|
17
|
+
rescue LoadError => e
|
18
|
+
warn "Could not load do_#{name}: #{e}"
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
|
24
|
+
|
25
|
+
class Cow
|
26
|
+
include DataMapper::Resource
|
27
|
+
|
28
|
+
property :id, Integer, :key => true
|
29
|
+
property :composite, Integer, :key => true
|
30
|
+
property :name, String
|
31
|
+
property :breed, String
|
32
|
+
|
33
|
+
has n, :baby_cows, :class_name => 'Cow'
|
34
|
+
belongs_to :mother_cow, :class_name => 'Cow'
|
35
|
+
end
|
36
|
+
|
37
|
+
require "benchwarmer"
|
38
|
+
|
39
|
+
TIMES = 2000
|
40
|
+
DataMapper.auto_migrate!
|
41
|
+
cow = Cow.create(
|
42
|
+
:id => 89,
|
43
|
+
:composite => 34,
|
44
|
+
:name => 'Berta',
|
45
|
+
:breed => 'Guernsey'
|
46
|
+
)
|
47
|
+
all_cows = Cow.all
|
48
|
+
|
49
|
+
puts "REXML"
|
50
|
+
Benchmark.warmer(TIMES) do
|
51
|
+
group("Serialization:") do
|
52
|
+
report "Single Resource" do
|
53
|
+
cow.to_xml
|
54
|
+
end
|
55
|
+
report "Collection" do
|
56
|
+
all_cows.to_xml
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
require 'nokogiri'
|
62
|
+
load 'dm-serializer/xml_serializers.rb'
|
63
|
+
|
64
|
+
puts "Nokogiri"
|
65
|
+
Benchmark.warmer(TIMES) do
|
66
|
+
group("Serialization:") do
|
67
|
+
report "Single Resource" do
|
68
|
+
cow.to_xml
|
69
|
+
end
|
70
|
+
report "Collection" do
|
71
|
+
all_cows.to_xml
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
require 'libxml'
|
77
|
+
load 'dm-serializer/xml_serializers.rb'
|
78
|
+
|
79
|
+
puts "LibXML"
|
80
|
+
Benchmark.warmer(TIMES) do
|
81
|
+
group("Serialization:") do
|
82
|
+
report "Single Resource" do
|
83
|
+
cow.to_xml
|
84
|
+
end
|
85
|
+
report "Collection" do
|
86
|
+
all_cows.to_xml
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
# Returns propreties to serialize based on :only or :exclude arrays, if provided
|
4
|
+
# :only takes precendence over :exclude
|
5
|
+
#
|
6
|
+
# @return <Array> properties that need to be serialized
|
7
|
+
def properties_to_serialize(options)
|
8
|
+
only_properties = Array(options[:only])
|
9
|
+
excluded_properties = Array(options[:exclude])
|
10
|
+
|
11
|
+
self.class.properties(repository.name).reject do |p|
|
12
|
+
if only_properties.include? p.name
|
13
|
+
false
|
14
|
+
else
|
15
|
+
excluded_properties.include?(p.name) || !(only_properties.empty? || only_properties.include?(p.name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Resource
|
22
|
+
include Serialize
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
|
3
|
+
begin
|
4
|
+
gem('fastercsv')
|
5
|
+
require 'faster_csv'
|
6
|
+
rescue LoadError
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
|
10
|
+
module DataMapper
|
11
|
+
module Serialize
|
12
|
+
# Serialize a Resource to comma-separated values (CSV).
|
13
|
+
#
|
14
|
+
# @return <String> a CSV representation of the Resource
|
15
|
+
def to_csv(writer = '')
|
16
|
+
FasterCSV.generate(writer) do |csv|
|
17
|
+
row = []
|
18
|
+
self.class.properties(repository.name).each do |property|
|
19
|
+
row << send(property.name).to_s
|
20
|
+
end
|
21
|
+
csv << row
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Collection
|
27
|
+
def to_csv
|
28
|
+
result = ""
|
29
|
+
each do |item|
|
30
|
+
result << item.to_csv + "\n"
|
31
|
+
end
|
32
|
+
result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
|
3
|
+
begin
|
4
|
+
gem('json')
|
5
|
+
require 'json/ext'
|
6
|
+
rescue LoadError
|
7
|
+
gem('json_pure')
|
8
|
+
require 'json/pure'
|
9
|
+
end
|
10
|
+
|
11
|
+
module DataMapper
|
12
|
+
module Serialize
|
13
|
+
# Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)
|
14
|
+
#
|
15
|
+
# @return <String> a JSON representation of the Resource
|
16
|
+
def to_json(*args)
|
17
|
+
options = args.first || {}
|
18
|
+
result = '{ '
|
19
|
+
fields = []
|
20
|
+
|
21
|
+
propset = properties_to_serialize(options)
|
22
|
+
|
23
|
+
fields += propset.map do |property|
|
24
|
+
"#{property.name.to_json}: #{send(property.getter).to_json}"
|
25
|
+
end
|
26
|
+
|
27
|
+
# add methods
|
28
|
+
(options[:methods] || []).each do |meth|
|
29
|
+
if self.respond_to?(meth)
|
30
|
+
fields << "#{meth.to_json}: #{send(meth).to_json}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Note: if you want to include a whole other model via relation, use :methods
|
35
|
+
# comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
|
36
|
+
# add relationships
|
37
|
+
# TODO: This needs tests and also needs to be ported to #to_xml and #to_yaml
|
38
|
+
(options[:relationships] || {}).each do |rel,opts|
|
39
|
+
if self.respond_to?(rel)
|
40
|
+
fields << "#{rel.to_json}: #{send(rel).to_json(opts)}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
result << fields.join(', ')
|
45
|
+
result << ' }'
|
46
|
+
result
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module Associations
|
51
|
+
# the json gem adds Object#to_json, which breaks the DM proxies, since it
|
52
|
+
# happens *after* the proxy has been blank slated. This code removes the added
|
53
|
+
# method, so it is delegated correctly to the Collection
|
54
|
+
proxies = []
|
55
|
+
|
56
|
+
proxies << ManyToMany::Proxy if defined?(ManyToMany::Proxy)
|
57
|
+
proxies << OneToMany::Proxy if defined?(OneToMany::Proxy)
|
58
|
+
proxies << ManyToOne::Proxy if defined?(ManyToOne::Proxy)
|
59
|
+
|
60
|
+
proxies.each do |proxy|
|
61
|
+
if proxy.public_instance_methods.any? { |m| m.to_sym == :to_json }
|
62
|
+
proxy.send(:undef_method, :to_json)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Collection
|
68
|
+
def to_json(*args)
|
69
|
+
opts = args.first || {}
|
70
|
+
"[" << map {|e| e.to_json(opts)}.join(",") << "]"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
require 'dm-serializer/xml_serializers'
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
module Serialize
|
7
|
+
# Serialize a Resource to XML
|
8
|
+
#
|
9
|
+
# @return <REXML::Document> an XML representation of this Resource
|
10
|
+
def to_xml(opts = {})
|
11
|
+
to_xml_document(opts).to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
# This method requires certain methods to be implemented in the individual
|
16
|
+
# serializer library subclasses:
|
17
|
+
# new_document
|
18
|
+
# root_node
|
19
|
+
# add_property_node
|
20
|
+
# add_node
|
21
|
+
def to_xml_document(opts={}, doc = nil)
|
22
|
+
xml = XMLSerializers::SERIALIZER
|
23
|
+
doc ||= xml.new_document
|
24
|
+
default_xml_element_name = lambda { Extlib::Inflection.underscore(self.class.name).tr("/", "-") }
|
25
|
+
root = xml.root_node(doc, opts[:element_name] || default_xml_element_name[])
|
26
|
+
properties_to_serialize(opts).each do |property|
|
27
|
+
value = send(property.name)
|
28
|
+
attrs = (property.type == String) ? {} : {'type' => property.type.to_s.downcase}
|
29
|
+
xml.add_node(root, property.name.to_s, value, attrs)
|
30
|
+
end
|
31
|
+
|
32
|
+
(opts[:methods] || []).each do |meth|
|
33
|
+
if self.respond_to?(meth)
|
34
|
+
xml_name = meth.to_s.gsub(/[^a-z0-9_]/, '')
|
35
|
+
value = send(meth)
|
36
|
+
xml.add_node(root, xml_name, value.to_s) unless value.nil?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
doc
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Collection
|
44
|
+
def to_xml(opts = {})
|
45
|
+
to_xml_document(opts).to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def to_xml_document(opts = {})
|
51
|
+
xml = DataMapper::Serialize::XMLSerializers::SERIALIZER
|
52
|
+
doc = xml.new_document
|
53
|
+
default_collection_element_name = lambda {Extlib::Inflection.pluralize(Extlib::Inflection.underscore(self.model.to_s)).tr("/", "-")}
|
54
|
+
root = xml.root_node(doc, opts[:collection_element_name] || default_collection_element_name[], {'type' => 'array'})
|
55
|
+
self.each do |item|
|
56
|
+
item.send(:to_xml_document, opts, doc)
|
57
|
+
end
|
58
|
+
doc
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'dm-serializer/common'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Serialize
|
5
|
+
# Serialize a Resource to YAML
|
6
|
+
#
|
7
|
+
# @return <YAML> a YAML representation of this Resource
|
8
|
+
def to_yaml(opts_or_emitter = {})
|
9
|
+
if opts_or_emitter.is_a?(YAML::Syck::Emitter)
|
10
|
+
emitter = opts_or_emitter
|
11
|
+
opts = {}
|
12
|
+
else
|
13
|
+
emitter = {}
|
14
|
+
opts = opts_or_emitter
|
15
|
+
end
|
16
|
+
|
17
|
+
YAML::quick_emit(object_id,emitter) do |out|
|
18
|
+
out.map(nil,to_yaml_style) do |map|
|
19
|
+
propset = properties_to_serialize(opts)
|
20
|
+
propset.each do |property|
|
21
|
+
value = send(property.name.to_sym)
|
22
|
+
map.add(property.name, value.is_a?(Class) ? value.to_s : value)
|
23
|
+
end
|
24
|
+
# add methods
|
25
|
+
(opts[:methods] || []).each do |meth|
|
26
|
+
if self.respond_to?(meth)
|
27
|
+
map.add(meth.to_sym, send(meth))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
(instance_variable_get("@yaml_addes") || []).each do |k,v|
|
31
|
+
map.add(k.to_s,v)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Collection
|
39
|
+
def to_yaml(opts_or_emitter = {})
|
40
|
+
if opts_or_emitter.is_a?(YAML::Syck::Emitter)
|
41
|
+
to_a.to_yaml(opts_or_emitter)
|
42
|
+
else
|
43
|
+
# FIXME: Don't double handle the YAML (remove the YAML.load)
|
44
|
+
to_a.collect {|x| YAML.load(x.to_yaml(opts_or_emitter)) }.to_yaml
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
module XMLSerializers
|
4
|
+
module LibXML
|
5
|
+
def self.new_document
|
6
|
+
::LibXML::XML::Document.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.root_node(doc, name, attrs = {})
|
10
|
+
root = ::LibXML::XML::Node.new(name)
|
11
|
+
attrs.each do |attr_name, attr_val|
|
12
|
+
root[attr_name] = attr_val
|
13
|
+
end
|
14
|
+
doc.root.nil? ? doc.root = root : doc.root << root
|
15
|
+
root
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_node(parent, name, value, attrs = {})
|
19
|
+
value_str = value.to_s unless value.nil?
|
20
|
+
node = ::LibXML::XML::Node.new(name, value_str)
|
21
|
+
attrs.each do |attr_name, attr_val|
|
22
|
+
node[attr_name] = attr_val
|
23
|
+
end
|
24
|
+
parent << node
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
module XMLSerializers
|
4
|
+
module Nokogiri
|
5
|
+
def self.new_document
|
6
|
+
::Nokogiri::XML::Document.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.root_node(doc, name, attrs = {})
|
10
|
+
root = ::Nokogiri::XML::Node.new(name, doc)
|
11
|
+
attrs.each do |attr_name, attr_val|
|
12
|
+
root[attr_name] = attr_val
|
13
|
+
end
|
14
|
+
doc.root.nil? ? doc.root = root : doc.root << root
|
15
|
+
root
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_node(parent, name, value, attrs = {})
|
19
|
+
node = ::Nokogiri::XML::Node.new(name, parent.document)
|
20
|
+
node << ::Nokogiri::XML::Text.new(value.to_s, parent.document) unless value.nil?
|
21
|
+
attrs.each {|attr_name, attr_val| node[attr_name] = attr_val }
|
22
|
+
parent << node
|
23
|
+
node
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Serialize
|
3
|
+
module XMLSerializers
|
4
|
+
module REXML
|
5
|
+
def self.new_document
|
6
|
+
::REXML::Document.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.root_node(document, name, attrs = {})
|
10
|
+
add_node(document.root || document, name, nil, attrs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.add_node(parent, name, value, attrs = {})
|
14
|
+
node = parent.add_element(name)
|
15
|
+
attrs.each {|attr_name, attr_val| node.attributes[attr_name] = attr_val}
|
16
|
+
node << ::REXML::Text.new(value.to_s) unless value.nil?
|
17
|
+
node
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'dm-serializer/xml_serializers/rexml'
|
2
|
+
require 'dm-serializer/xml_serializers/nokogiri'
|
3
|
+
require 'dm-serializer/xml_serializers/libxml'
|
4
|
+
|
5
|
+
module DataMapper
|
6
|
+
module Serialize
|
7
|
+
module XMLSerializers
|
8
|
+
SERIALIZER = if defined?(::LibXML)
|
9
|
+
LibXML
|
10
|
+
elsif defined?(::Nokogiri)
|
11
|
+
Nokogiri
|
12
|
+
else
|
13
|
+
REXML
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/dm-serializer.rb
CHANGED
@@ -1,230 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require 'faster_csv'
|
6
|
-
rescue LoadError
|
7
|
-
nil
|
8
|
-
end
|
9
|
-
|
10
|
-
begin
|
11
|
-
gem('json')
|
12
|
-
require 'json/ext'
|
13
|
-
rescue LoadError
|
14
|
-
gem('json_pure')
|
15
|
-
require 'json/pure'
|
16
|
-
end
|
17
|
-
|
18
|
-
module DataMapper
|
19
|
-
module Serialize
|
20
|
-
# Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)
|
21
|
-
#
|
22
|
-
# @return <String> a JSON representation of the Resource
|
23
|
-
def to_json(*args)
|
24
|
-
options = args.first || {}
|
25
|
-
result = '{ '
|
26
|
-
fields = []
|
27
|
-
|
28
|
-
propset = properties_to_serialize(options)
|
29
|
-
|
30
|
-
fields += propset.map do |property|
|
31
|
-
"#{property.name.to_json}: #{send(property.getter).to_json}"
|
32
|
-
end
|
33
|
-
|
34
|
-
if self.respond_to?(:serialize_properties)
|
35
|
-
self.serialize_properties.each do |k,v|
|
36
|
-
fields << "#{k.to_json}: #{v.to_json}"
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
if self.class.respond_to?(:read_only_attributes) && exclude_read_only
|
41
|
-
self.class.read_only_attributes.each do |property|
|
42
|
-
fields << "#{property.to_json}: #{send(property).to_json}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# add methods
|
47
|
-
(options[:methods] || []).each do |meth|
|
48
|
-
if self.respond_to?(meth)
|
49
|
-
fields << "#{meth.to_json}: #{send(meth).to_json}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Note: if you want to include a whole other model via relation, use :methods
|
54
|
-
# comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
|
55
|
-
# add relationships
|
56
|
-
(options[:relationships] || {}).each do |rel,opts|
|
57
|
-
if self.respond_to?(rel)
|
58
|
-
fields << "#{rel.to_json}: #{send(rel).to_json(opts)}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
result << fields.join(', ')
|
63
|
-
result << ' }'
|
64
|
-
result
|
65
|
-
end
|
66
|
-
|
67
|
-
# Serialize a Resource to comma-separated values (CSV).
|
68
|
-
#
|
69
|
-
# @return <String> a CSV representation of the Resource
|
70
|
-
def to_csv(writer = '')
|
71
|
-
FasterCSV.generate(writer) do |csv|
|
72
|
-
row = []
|
73
|
-
self.class.properties(repository.name).each do |property|
|
74
|
-
row << send(property.name).to_s
|
75
|
-
end
|
76
|
-
csv << row
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Serialize a Resource to XML
|
81
|
-
#
|
82
|
-
# @return <REXML::Document> an XML representation of this Resource
|
83
|
-
def to_xml(opts = {})
|
84
|
-
|
85
|
-
to_xml_document(opts).to_s
|
86
|
-
end
|
87
|
-
|
88
|
-
# Serialize a Resource to YAML
|
89
|
-
#
|
90
|
-
# @return <YAML> a YAML representation of this Resource
|
91
|
-
def to_yaml(opts = {})
|
92
|
-
YAML::quick_emit(object_id,opts) do |out|
|
93
|
-
out.map(nil,to_yaml_style) do |map|
|
94
|
-
propset = properties_to_serialize(opts)
|
95
|
-
propset.each do |property|
|
96
|
-
value = send(property.name.to_sym)
|
97
|
-
map.add(property.name, value.is_a?(Class) ? value.to_s : value)
|
98
|
-
end
|
99
|
-
# add methods
|
100
|
-
(opts[:methods] || []).each do |meth|
|
101
|
-
if self.respond_to?(meth)
|
102
|
-
map.add(meth.to_sym, send(meth))
|
103
|
-
end
|
104
|
-
end
|
105
|
-
(instance_variable_get("@yaml_addes") || []).each do |k,v|
|
106
|
-
map.add(k.to_s,v)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
protected
|
113
|
-
|
114
|
-
# Returns propreties to serialize based on :only or :exclude arrays, if provided
|
115
|
-
# :only takes precendence over :exclude
|
116
|
-
#
|
117
|
-
# @return <Array> properties that need to be serialized
|
118
|
-
def properties_to_serialize(options)
|
119
|
-
only_properties = Array(options[:only])
|
120
|
-
excluded_properties = Array(options[:exclude])
|
121
|
-
exclude_read_only = options[:without_read_only_attributes] || false
|
122
|
-
|
123
|
-
self.class.properties(repository.name).reject do |p|
|
124
|
-
if only_properties.include? p.name
|
125
|
-
false
|
126
|
-
else
|
127
|
-
excluded_properties.include?(p.name) || !(only_properties.empty? || only_properties.include?(p.name))
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
|
133
|
-
# Return the name of this Resource - to be used as the root element name.
|
134
|
-
# This can be overloaded.
|
135
|
-
#
|
136
|
-
# @return <String> name of this Resource
|
137
|
-
def xml_element_name
|
138
|
-
Extlib::Inflection.underscore(self.class.name).tr("/", "-")
|
139
|
-
end
|
140
|
-
|
141
|
-
# Return a REXML::Document representing this Resource
|
142
|
-
#
|
143
|
-
# @return <REXML::Document> an XML representation of this Resource
|
144
|
-
def to_xml_document(opts={}, doc=nil)
|
145
|
-
doc ||= REXML::Document.new
|
146
|
-
root = doc.add_element(xml_element_name)
|
147
|
-
|
148
|
-
#TODO old code base was converting single quote to double quote on attribs
|
149
|
-
|
150
|
-
propset = properties_to_serialize(opts)
|
151
|
-
propset.each do |property|
|
152
|
-
value = send(property.name)
|
153
|
-
node = root.add_element(property.name.to_s)
|
154
|
-
unless property.type == String
|
155
|
-
node.attributes["type"] = property.type.to_s.downcase
|
156
|
-
end
|
157
|
-
node << REXML::Text.new(value.to_s) unless value.nil?
|
158
|
-
end
|
159
|
-
|
160
|
-
# add methods
|
161
|
-
(opts[:methods] || []).each do |meth|
|
162
|
-
if self.respond_to?(meth)
|
163
|
-
xml_name = meth.to_s.gsub(/[^a-z0-9_]/, '')
|
164
|
-
node = root.add_element(xml_name)
|
165
|
-
value = send(meth)
|
166
|
-
node << REXML::Text.new(value.to_s, :raw => true) unless value.nil?
|
167
|
-
end
|
168
|
-
end
|
169
|
-
doc
|
170
|
-
end
|
171
|
-
|
172
|
-
end # module Serialize
|
173
|
-
|
174
|
-
module Resource
|
175
|
-
include Serialize
|
176
|
-
end # module Resource
|
177
|
-
|
178
|
-
# the json gem adds Object#to_json, which breaks the DM proxies, since it
|
179
|
-
# happens *after* the proxy has been blank slated. This code removes the added
|
180
|
-
# method, so it is delegated correctly to the Collection
|
181
|
-
[
|
182
|
-
Associations::OneToMany::Proxy,
|
183
|
-
(Associations::ManyToOne::Proxy if defined?(Associations::ManyToOne::Proxy)),
|
184
|
-
Associations::ManyToMany::Proxy
|
185
|
-
].each do |proxy|
|
186
|
-
[:to_json].each do |method|
|
187
|
-
proxy.send(:undef_method, :to_json) rescue nil
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
class Collection
|
192
|
-
def to_yaml(opts = {})
|
193
|
-
# FIXME: Don't double handle the YAML (remove the YAML.load)
|
194
|
-
to_a.collect {|x| YAML.load(x.to_yaml(opts)) }.to_yaml
|
195
|
-
end
|
196
|
-
|
197
|
-
def to_json(*args)
|
198
|
-
opts = args.first || {}
|
199
|
-
"[" << map {|e| e.to_json(opts)}.join(",") << "]"
|
200
|
-
end
|
201
|
-
|
202
|
-
def to_xml(opts = {})
|
203
|
-
to_xml_document(opts).to_s
|
204
|
-
end
|
205
|
-
|
206
|
-
def to_csv
|
207
|
-
result = ""
|
208
|
-
each do |item|
|
209
|
-
result << item.to_csv + "\n"
|
210
|
-
end
|
211
|
-
result
|
212
|
-
end
|
213
|
-
|
214
|
-
protected
|
215
|
-
def xml_element_name
|
216
|
-
Extlib::Inflection.pluralize(Extlib::Inflection.underscore(self.model.to_s)).tr("/", "-")
|
217
|
-
end
|
218
|
-
|
219
|
-
def to_xml_document(opts={})
|
220
|
-
doc = REXML::Document.new
|
221
|
-
root = doc.add_element(xml_element_name)
|
222
|
-
root.attributes["type"] = 'array'
|
223
|
-
each do |item|
|
224
|
-
item.send(:to_xml_document, opts, root)
|
225
|
-
end
|
226
|
-
doc
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
end # module DataMapper
|
1
|
+
require 'dm-serializer/to_json'
|
2
|
+
require 'dm-serializer/to_xml'
|
3
|
+
require 'dm-serializer/to_yaml'
|
4
|
+
require 'dm-serializer/to_csv'
|
data/spec/fixtures/cow.rb
CHANGED
@@ -1,6 +1,47 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
3
|
|
4
|
+
share_examples_for 'A serialization method that also serializes core classes' do
|
5
|
+
# This spec ensures that we don't break any serialization methods attached
|
6
|
+
# to core classes, such as Array
|
7
|
+
before(:all) do
|
8
|
+
%w[ @harness ].each do |ivar|
|
9
|
+
raise "+#{ivar}+ should be defined in before block" unless instance_variable_get(ivar)
|
10
|
+
end
|
11
|
+
|
12
|
+
DataMapper.auto_migrate!
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
Cow.all.destroy!
|
17
|
+
Planet.all.destroy!
|
18
|
+
FriendedPlanet.all.destroy!
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'serializes an array of extended objects' do
|
22
|
+
Cow.create(
|
23
|
+
:id => 89,
|
24
|
+
:composite => 34,
|
25
|
+
:name => 'Berta',
|
26
|
+
:breed => 'Guernsey'
|
27
|
+
)
|
28
|
+
result = @harness.test(Cow.all.to_a)
|
29
|
+
result[0].values_at("id", "composite", "name", "breed").should ==
|
30
|
+
[89, 34, "Berta", "Guernsey"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'serializes an array of collections' do
|
34
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), Cow)
|
35
|
+
collection = DataMapper::Collection.new(query) do |c|
|
36
|
+
c.load([1, 2, 'Betsy', 'Jersey'])
|
37
|
+
c.load([89, 34, 'Berta', 'Guernsey'])
|
38
|
+
end
|
39
|
+
result = @harness.test([collection])
|
40
|
+
result[0][1].values_at("id", "composite", "name", "breed").should ==
|
41
|
+
[89, 34, "Berta", "Guernsey"]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
4
45
|
share_examples_for 'A serialization method' do
|
5
46
|
before(:all) do
|
6
47
|
%w[ @harness ].each do |ivar|
|
data/spec/public/to_json_spec.rb
CHANGED
@@ -29,45 +29,7 @@ describe DataMapper::Serialize, '#to_json' do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it_should_behave_like "A serialization method"
|
32
|
-
|
33
|
-
it "should serialize an array of collections" do
|
34
|
-
deserialized_collection = JSON.parse([@collection].to_json).first
|
35
|
-
betsy = deserialized_collection.first
|
36
|
-
berta = deserialized_collection.last
|
37
|
-
|
38
|
-
betsy["id"].should == 1
|
39
|
-
betsy["composite"].should == 2
|
40
|
-
betsy["name"].should == "Betsy"
|
41
|
-
betsy["breed"].should == "Jersey"
|
42
|
-
|
43
|
-
berta["id"].should == 10
|
44
|
-
berta["composite"].should == 20
|
45
|
-
berta["name"].should == "Berta"
|
46
|
-
berta["breed"].should == "Guernsey"
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should serialize an array of extended objects" do
|
50
|
-
deserialized_collection = JSON.parse(@collection.to_a.to_json)
|
51
|
-
betsy = deserialized_collection.first
|
52
|
-
berta = deserialized_collection.last
|
53
|
-
|
54
|
-
betsy["id"].should == 1
|
55
|
-
betsy["composite"].should == 2
|
56
|
-
betsy["name"].should == "Betsy"
|
57
|
-
betsy["breed"].should == "Jersey"
|
58
|
-
|
59
|
-
berta["id"].should == 10
|
60
|
-
berta["composite"].should == 20
|
61
|
-
berta["name"].should == "Berta"
|
62
|
-
berta["breed"].should == "Guernsey"
|
63
|
-
end
|
64
|
-
|
65
|
-
it "handles extra properties" do
|
66
|
-
deserialized_hash = JSON.parse(Cow.new(:id => 1, :name => "Harry", :breed => "Angus").to_json)
|
67
|
-
|
68
|
-
deserialized_hash["extra"].should == "Extra"
|
69
|
-
deserialized_hash["another"].should == 42
|
70
|
-
end
|
32
|
+
it_should_behave_like 'A serialization method that also serializes core classes'
|
71
33
|
|
72
34
|
it "handles options given to a collection properly" do
|
73
35
|
deserialized_collection = JSON.parse(@collection.to_json(:only => [:composite]))
|
data/spec/public/to_xml_spec.rb
CHANGED
@@ -1,89 +1,102 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
{
|
5
|
+
'REXML' => nil,
|
6
|
+
'LibXML' => 'libxml',
|
7
|
+
'Nokogiri' => 'nokogiri'
|
8
|
+
}.each do |lib, file_to_require|
|
9
|
+
begin
|
10
|
+
require file_to_require if file_to_require
|
11
|
+
rescue LoadError
|
12
|
+
warn "[WARNING] Cannot require '#{file_to_require}', not running #to_xml specs for #{lib}"
|
13
|
+
next
|
14
|
+
end
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
16
|
+
describe DataMapper::Serialize, "#to_xml using #{lib}" do
|
17
|
+
#
|
18
|
+
# ==== enterprisey XML
|
19
|
+
#
|
20
|
+
|
21
|
+
before(:all) do
|
22
|
+
@harness = Class.new(SerializerTestHarness) do
|
23
|
+
def method_name
|
24
|
+
:to_xml
|
25
|
+
end
|
14
26
|
|
15
|
-
|
27
|
+
protected
|
16
28
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
29
|
+
def deserialize(result)
|
30
|
+
doc = REXML::Document.new(result)
|
31
|
+
root = doc.elements[1]
|
32
|
+
if root.attributes["type"] == "array"
|
33
|
+
root.elements.collect do |element|
|
34
|
+
a = {}
|
35
|
+
element.elements.each do |v|
|
36
|
+
a.update(v.name => cast(v.text, v.attributes["type"]))
|
37
|
+
end
|
38
|
+
a
|
39
|
+
end
|
40
|
+
else
|
22
41
|
a = {}
|
23
|
-
|
42
|
+
root.elements.each do |v|
|
24
43
|
a.update(v.name => cast(v.text, v.attributes["type"]))
|
25
44
|
end
|
26
45
|
a
|
27
46
|
end
|
28
|
-
else
|
29
|
-
a = {}
|
30
|
-
root.elements.each do |v|
|
31
|
-
a.update(v.name => cast(v.text, v.attributes["type"]))
|
32
|
-
end
|
33
|
-
a
|
34
47
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def cast(value, type)
|
38
|
-
boolean_conversions = {"true" => true, "false" => false}
|
39
|
-
value = boolean_conversions[value] if boolean_conversions.has_key?(value)
|
40
|
-
value = value.to_i if value && type == "integer"
|
41
|
-
value
|
42
|
-
end
|
43
|
-
end.new
|
44
|
-
end
|
45
|
-
|
46
|
-
it_should_behave_like "A serialization method"
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
def cast(value, type)
|
50
|
+
boolean_conversions = {"true" => true, "false" => false}
|
51
|
+
value = boolean_conversions[value] if boolean_conversions.has_key?(value)
|
52
|
+
value = value.to_i if value && type == "integer"
|
53
|
+
value
|
54
|
+
end
|
55
|
+
end.new
|
56
|
+
DataMapper::Serialize::XMLSerializers.instance_eval { remove_const('SERIALIZER') }
|
57
|
+
DataMapper::Serialize::XMLSerializers::SERIALIZER = DataMapper::Serialize::XMLSerializers::const_get(lib)
|
51
58
|
end
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
60
|
+
it_should_behave_like "A serialization method"
|
61
|
+
|
62
|
+
describe ':element_name option for Resource' do
|
63
|
+
it 'should be used as the root node name by #to_xml' do
|
64
|
+
planet = Planet.new
|
65
|
+
xml = planet.to_xml(:element_name => "aplanet")
|
66
|
+
REXML::Document.new(xml).elements[1].name.should == "aplanet"
|
59
67
|
end
|
60
68
|
|
61
|
-
|
62
|
-
|
69
|
+
it 'when not specified the class name underscored and with slashes replaced with dashes should be used as the root node name' do
|
70
|
+
cat = QuanTum::Cat.new
|
71
|
+
xml = cat.to_xml
|
72
|
+
REXML::Document.new(xml).elements[1].name.should == "quan_tum-cat"
|
73
|
+
end
|
63
74
|
end
|
64
|
-
end
|
65
75
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
76
|
+
describe ':collection_element_name for Collection' do
|
77
|
+
before(:each) do
|
78
|
+
query = DataMapper::Query.new(DataMapper::repository(:default), QuanTum::Cat)
|
79
|
+
@collection = DataMapper::Collection.new(query) {}
|
80
|
+
end
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
it 'when not specified the class name tableized and with slashes replaced with dashes should be used as the root node name' do
|
83
|
+
xml = @collection.to_xml
|
84
|
+
REXML::Document.new(xml).elements[1].name.should == "quan_tum-cats"
|
85
|
+
end
|
75
86
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
"somanycats"
|
82
|
-
end
|
87
|
+
it 'should be used as the root node name by #to_xml' do
|
88
|
+
@collection.load([1])
|
89
|
+
|
90
|
+
xml = @collection.to_xml(:collection_element_name => "somanycats")
|
91
|
+
REXML::Document.new(xml).elements[1].name.should == "somanycats"
|
83
92
|
end
|
84
93
|
|
85
|
-
|
86
|
-
|
94
|
+
it 'should respect :element_name for collection elements' do
|
95
|
+
@collection.load([1])
|
96
|
+
|
97
|
+
xml = @collection.to_xml(:collection_element_name => "somanycats", :element_name => 'cat')
|
98
|
+
REXML::Document.new(xml).elements[1].elements[1].name.should == "cat"
|
99
|
+
end
|
87
100
|
end
|
88
101
|
end
|
89
102
|
end
|
data/spec/public/to_yaml_spec.rb
CHANGED
@@ -18,15 +18,20 @@ describe DataMapper::Serialize, '#to_yaml' do
|
|
18
18
|
def deserialize(result)
|
19
19
|
stringify_keys = lambda {|hash| hash.inject({}) {|a, (key, value)| a.update(key.to_s => value) }}
|
20
20
|
result = YAML.load(result)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
(process = lambda {|object|
|
22
|
+
if object.is_a?(Array)
|
23
|
+
object.collect(&process)
|
24
|
+
elsif object.is_a?(Hash)
|
25
|
+
stringify_keys[object]
|
26
|
+
else
|
27
|
+
object
|
28
|
+
end
|
29
|
+
})[result]
|
26
30
|
end
|
27
31
|
end.new
|
28
32
|
end
|
29
33
|
|
30
|
-
it_should_behave_like
|
34
|
+
it_should_behave_like 'A serialization method'
|
35
|
+
it_should_behave_like 'A serialization method that also serializes core classes'
|
31
36
|
|
32
37
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
|
-
gem 'dm-core', '~>0.9.
|
4
|
+
gem 'dm-core', '~>0.9.9'
|
5
5
|
require 'dm-core'
|
6
6
|
|
7
7
|
spec_dir_path = Pathname(__FILE__).dirname.expand_path
|
8
|
-
|
8
|
+
$LOAD_PATH.unshift(spec_dir_path.parent + 'lib/')
|
9
|
+
require 'dm-serializer'
|
9
10
|
|
10
11
|
def load_driver(name, default_uri)
|
11
12
|
return false if ENV['ADAPTER'] != name.to_s
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dm-serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guy van den Berg
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-01-04 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.
|
23
|
+
version: 0.9.9
|
24
24
|
version:
|
25
25
|
description: DataMapper plugin for serializing DataMapper objects
|
26
26
|
email:
|
@@ -30,7 +30,7 @@ executables: []
|
|
30
30
|
extensions: []
|
31
31
|
|
32
32
|
extra_rdoc_files:
|
33
|
-
- README.
|
33
|
+
- README.textile
|
34
34
|
- LICENSE
|
35
35
|
- TODO
|
36
36
|
- History.txt
|
@@ -38,13 +38,23 @@ files:
|
|
38
38
|
- History.txt
|
39
39
|
- LICENSE
|
40
40
|
- Manifest.txt
|
41
|
-
- README.
|
41
|
+
- README.textile
|
42
42
|
- Rakefile
|
43
43
|
- TODO
|
44
44
|
- autotest/discover.rb
|
45
45
|
- autotest/dmserializer_rspec.rb
|
46
|
+
- benchmarks/to_xml.rb
|
46
47
|
- lib/dm-serializer.rb
|
48
|
+
- lib/dm-serializer/common.rb
|
49
|
+
- lib/dm-serializer/to_csv.rb
|
50
|
+
- lib/dm-serializer/to_json.rb
|
51
|
+
- lib/dm-serializer/to_xml.rb
|
52
|
+
- lib/dm-serializer/to_yaml.rb
|
47
53
|
- lib/dm-serializer/version.rb
|
54
|
+
- lib/dm-serializer/xml_serializers.rb
|
55
|
+
- lib/dm-serializer/xml_serializers/libxml.rb
|
56
|
+
- lib/dm-serializer/xml_serializers/nokogiri.rb
|
57
|
+
- lib/dm-serializer/xml_serializers/rexml.rb
|
48
58
|
- spec/fixtures/cow.rb
|
49
59
|
- spec/fixtures/planet.rb
|
50
60
|
- spec/fixtures/quan_tum_cat.rb
|
data/README.txt
DELETED