MikeSofaer-saxual-replication 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+