MikeSofaer-saxual-replication 0.0.1

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.
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "spec"
2
+ require "spec/rake/spectask"
3
+ require 'lib/saxual-replication.rb'
4
+
5
+ Spec::Rake::SpecTask.new do |t|
6
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
7
+ t.spec_files = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task :install do
11
+ rm_rf "*.gem"
12
+ puts `gem build saxual-replication.gemspec`
13
+ puts `sudo gem install saxual-replication-#{SAXualReplication::VERSION}.gem`
14
+ end
@@ -0,0 +1,92 @@
1
+ require 'sax-machine'
2
+ require 'dm-core'
3
+
4
+ module SAXualReplication
5
+ class MissingElementError < Exception; end
6
+
7
+ def self.included(base)
8
+ base.send(:include, SAXMachine)
9
+ base.extend SaverMethods
10
+ end
11
+
12
+ module SaverMethods
13
+ def parse(xml)
14
+ ret = super(xml)
15
+ ret.validate
16
+ return ret
17
+ end
18
+
19
+ def parse_multiple(xml)
20
+ klass = collection_class
21
+ ret = klass.parse(xml)
22
+ ret.rows.each{|o| o.validate}
23
+ ret.rows
24
+ end
25
+
26
+ def columns_with_types
27
+ column_names.each{|c| yield c, data_class(c) || String}
28
+ end
29
+
30
+ def connection
31
+ DataMapper.repository(:default).adapter
32
+ end
33
+
34
+ def table(value)
35
+ @table_name = value
36
+ end
37
+
38
+ def tag(value)
39
+ @tag = value
40
+ end
41
+
42
+ def datamapper_class
43
+ klass = self.dup
44
+ klass.send(:include, DataMapper::Resource)
45
+ klass.storage_names[:default] = @table_name
46
+ klass.property(:id, DataMapper::Types::Serial)
47
+ klass.property(:created_at, DateTime, :nullable => false)
48
+ klass.property(:updated_at, DateTime, :nullable => false)
49
+ columns_with_types { |n, t| klass.property(n, t) }
50
+ klass
51
+ end
52
+
53
+ def collection_class
54
+ klass = self
55
+ tag = @tag
56
+ Class.new do
57
+ include SAXualReplication
58
+ elements tag, :as => :rows, :class => klass
59
+ end
60
+ end
61
+
62
+ def sql(rows)
63
+ "INSERT INTO "+ @table_name + "(" + column_names.join(', ') + ", created_at, updated_at) VALUES " +
64
+ ([("(" + (["?"] * (column_names.size + 2)).join(',') + ")")] * rows.size).join(',')
65
+ end
66
+ def bind_values(rows)
67
+ names = column_names
68
+ datetime = DateTime.now
69
+ array = []
70
+ rows.each{|row| row.add_bind_values!(names, array, datetime)}
71
+ array
72
+ end
73
+
74
+ def save(rows)
75
+ connection.execute sql(rows), *bind_values(rows)
76
+ end
77
+ end
78
+
79
+
80
+ #+ " ON DUPLICATE KEY UPDATE " + update_keys.join(', ')
81
+
82
+ def add_bind_values!(column_names, bind_array, datetime)
83
+ column_names.each{|c| bind_array << self.send(c)}
84
+ bind_array << datetime << datetime
85
+ end
86
+
87
+ def validate
88
+ self.class.instance_variable_get('@sax_config').instance_variable_get('@top_level_elements').select{ |e| e.required? }.each do |element|
89
+ raise MissingElementError.new("Missing the required attribute " + element.name) unless send(element.instance_variable_get('@as'))
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "SAXualReplication" do
4
+ before :each do
5
+ @klass = Class.new do
6
+ include SAXualReplication
7
+ element :title
8
+ element :written_on, :class => DateTime
9
+ table "documents"
10
+ tag :document
11
+ end
12
+ end
13
+ it "should function as a SAXMachine class" do
14
+ document = @klass.parse("<title>Hello, Everyone!</title>")
15
+ document.title.should == "Hello, Everyone!"
16
+ end
17
+ describe "DataMapper" do
18
+ before(:each) do
19
+ DataMapper.setup(:default, 'mysql://localhost/saxual_replication_test')
20
+ @adapter = DataMapper.repository.adapter
21
+ end
22
+ it "should have the database connection" do
23
+ @adapter.query "show tables"
24
+ end
25
+ it "should have a DataMapper class" do
26
+ @klass.datamapper_class.all.should be_a(Array)
27
+ end
28
+ it "should be able to auto-migrate the document table" do
29
+ DataMapper.auto_migrate!
30
+ end
31
+ describe "with multiple columns" do
32
+ before(:each) do
33
+ @document = @klass.parse("<xml><title>Someone's Cat</title><written_on>March 5 2007</written_on></xml>")
34
+ end
35
+ after(:each) do
36
+ @adapter.execute "delete from documents"
37
+ end
38
+ it "should generate the correct bind values for the specified columns" do
39
+ @klass.column_names.should =~ [:title, :written_on]
40
+ array = []
41
+ @document.add_bind_values!(@klass.column_names, array, DateTime.now)
42
+ array[0].should == "Someone's Cat"
43
+ array[1].should be_a(DateTime)
44
+ array[2].should be_a(DateTime)
45
+ array[3].should be_a(DateTime)
46
+ end
47
+ it "should generate the correct bind values from a class call" do
48
+ array = @klass.bind_values([@document,@document])
49
+ array[0].should == "Someone's Cat"
50
+ array[4].should == "Someone's Cat"
51
+ array[1].should be_a(DateTime)
52
+ array[5].should be_a(DateTime)
53
+ end
54
+ it "should generate the correct SQL from a class call" do
55
+ @klass.sql([@document,@document]).should == "INSERT INTO documents(title, written_on, created_at, updated_at) VALUES (?,?,?,?),(?,?,?,?)"
56
+ end
57
+ describe "multiple records" do
58
+ before(:each) do
59
+ @xml = "<xml><document><title>Hello, Everyone!</title></document><document><title>Someone's Cat</title></document></xml>"
60
+ end
61
+
62
+ it "should be possible to parse two records" do
63
+ rows = @klass.parse_multiple(@xml)
64
+ rows.size.should == 2
65
+ end
66
+
67
+ it "should be able to save two records" do
68
+ documents = @klass.parse_multiple(@xml)
69
+ @klass.save documents
70
+ @klass.datamapper_class.all[0].title.should == "Hello, Everyone!"
71
+ @klass.datamapper_class.all[1].title.should == "Someone's Cat"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --diff
2
+ --color
@@ -0,0 +1,13 @@
1
+ require "rubygems"
2
+ require "spec"
3
+
4
+ # gem install redgreen for colored test output
5
+ begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
6
+
7
+ path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
8
+ $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
9
+
10
+ require "lib/saxual-replication"
11
+
12
+ # Spec::Runner.configure do |config|
13
+ # end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: MikeSofaer-saxual-replication
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Sofaer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-21 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sax-machine
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.15
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: dm-core
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.0
34
+ version:
35
+ description:
36
+ email: mike@sofaer.net
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - lib/saxual-replication.rb
45
+ - README
46
+ - Rakefile
47
+ - spec/spec.opts
48
+ - spec/spec_helper.rb
49
+ - spec/saxual-replication/saxual_replication_spec.rb
50
+ has_rdoc: false
51
+ homepage: http://github.com/MikeSofaer/saxual-replication
52
+ post_install_message:
53
+ rdoc_options: []
54
+
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.2.0
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: Database replication from XML with SAXMachine
76
+ test_files: []
77
+