squealer 1.0.0

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/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg/
data/.watchr ADDED
@@ -0,0 +1,27 @@
1
+ # ~/.vim/ftdetect/watchr.vim
2
+ #
3
+ # This should have only the following line in it:
4
+ #
5
+ # autocmd BufNewFile,BufRead *.watchr setf ruby
6
+ #
7
+ # This will enable vim to recognize this file as ruby code should you wish to
8
+ # edit it.
9
+ def run(cmd)
10
+ puts cmd
11
+ system cmd
12
+ end
13
+
14
+ def spec(file)
15
+ run "spec -O spec/spec.opts #{file}"
16
+ end
17
+
18
+ watch("spec/.*/*_spec\.rb") do |match|
19
+ p match[0]
20
+ spec(match[0])
21
+ end
22
+
23
+ watch("lib/(.*/.*)\.rb") do |match|
24
+ p match[1]
25
+ spec("spec/#{match[1]}_spec.rb")
26
+ end
27
+
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # Squealer
2
+
3
+ For now, this is specifically for MongoDB exporting to mySQL with the assumption that the data will be heavily denormalized.
4
+
5
+ The target SQL database must have no foreign keys.
6
+
7
+ The target SQL database must use a primary key of char(16) with value of the MongoDB id.
8
+
9
+ It is assumed no indexes are present in the target database table.
10
+
11
+ The target row is inserted, or updated if present. We are using MySQL INSERT ... UPDATE ON DUPLICATE KEY extended syntax to achieve this for now. This allows an event-driven update of exported data as well as a bulk batch process.
12
+
13
+
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+ require 'rake/rdoctask'
7
+
8
+ task :default => [:spec]
9
+ Rake::Task[:default].clear
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gemspec|
14
+ gemspec.name = "squealer"
15
+ gemspec.summary = "Document-oriented to Relational database exporter"
16
+ gemspec.description = "Exports mongodb to mysql. More later."
17
+ gemspec.email = "joshua.graham@grahamis.com"
18
+ gemspec.homepage = "http://github.com/delitescere/squealer/"
19
+ gemspec.authors = ["Josh Graham", "Durran Jordan"]
20
+ gemspec.add_dependency('mysql', '>= 2.8.1')
21
+ gemspec.add_dependency('mongo', '>= 0.18.3')
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler not available. Install it with: gem install jeweler"
26
+ end
27
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,38 @@
1
+ require 'squealer'
2
+
3
+ import('localhost', 27017, 'development')
4
+ export('localhost', 'root', '', 'reporting_export')
5
+
6
+ import.collection("users").find({}).each do |user|
7
+ target(:user, user._id) do # insert or update on user where id is primary key column name
8
+ assign(:name) { user.first_name + " " + user.last_name.upcase }
9
+ assign(:dob) { user.dob }
10
+
11
+ user.activities.each do |activity|
12
+ target(:activity, activity._id) do
13
+ assign(:user_id) { user._id }
14
+ assign(:name) { activity.name }
15
+ end
16
+
17
+ activity.tasks.each do |task|
18
+ target(:task, task._id) do
19
+ assign(:user_id) { user._id }
20
+ assign(:activity_id) { activity._id }
21
+ assign(:date) { task.date }
22
+ end
23
+ end #activity.tasks
24
+ end #user.activities
25
+ end
26
+ end #collection("users")
27
+
28
+ import.collection("organization").find({}).each do |organization|
29
+ if organization.disabled
30
+ import.collection("users").find({ :organization_id => organization.id }) do |user|
31
+ target(:user, user.id) do
32
+ assign(:disabled) { true }
33
+ end
34
+ end
35
+ else
36
+ # something else
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ require 'mysql'
2
+ require 'mongo'
3
+ require 'singleton'
4
+
5
+ module Squealer
6
+ class Database
7
+ include Singleton
8
+
9
+ def import_from(host, port, name)
10
+ @import_dbc = Mongo::Connection.new(host, port, :slave_ok => true).db(name)
11
+ end
12
+
13
+ def export_to(host, username, password, name)
14
+ @export_dbc = Mysql.connect(host, username, password, name)
15
+ end
16
+
17
+ def import
18
+ @import_dbc
19
+ end
20
+
21
+ def export
22
+ @export_dbc
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ class Hash
2
+ def method_missing(name, *args, &block)
3
+ super if args.size > 0 || block_given?
4
+ self[name.to_s]
5
+ end
6
+ end
@@ -0,0 +1,33 @@
1
+ class Object
2
+
3
+ def target(table_name, row_id, &block)
4
+ Squealer::Target.new(Squealer::Database.instance.export, table_name, row_id, &block)
5
+ end
6
+
7
+ def assign(column_name, &block)
8
+ Squealer::Target.current.assign(column_name, &block)
9
+ end
10
+
11
+ def import(*args)
12
+ if args.length > 0
13
+ Squealer::Database.instance.import_from(*args)
14
+ else
15
+ Squealer::Database.instance.import
16
+ end
17
+ end
18
+
19
+ def export(*args)
20
+ if args.length > 0
21
+ Squealer::Database.instance.export_to(*args)
22
+ else
23
+ Squealer::Database.instance.export
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ class NilClass
30
+ def each
31
+ []
32
+ end
33
+ end
@@ -0,0 +1,106 @@
1
+ require 'delegate'
2
+ require 'singleton'
3
+
4
+ module Squealer
5
+ class Target
6
+
7
+ def self.current
8
+ Queue.instance.current
9
+ end
10
+
11
+ def initialize(database_connection, table_name, row_id, &block)
12
+ throw "Block must be given to target (otherwise, there's no work to do)" unless block_given?
13
+
14
+ @table_name = table_name.to_s
15
+ @row_id = row_id
16
+ @column_names = []
17
+ @column_values = []
18
+ @sql = ''
19
+
20
+ target(&block)
21
+ end
22
+
23
+ def sql
24
+ @sql
25
+ end
26
+
27
+ def assign(column_name, &block)
28
+ @column_names << column_name
29
+ @column_values << block.call
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def target(&block)
36
+ Queue.instance.push(self)
37
+
38
+ yield self
39
+
40
+ @sql = "INSERT #{@table_name}"
41
+ @sql << " (#{pk_name}#{column_names}) VALUES (?#{column_value_markers})"
42
+ @sql << " ON DUPLICATE KEY UPDATE #{column_markers}"
43
+
44
+ execute_sql(@sql)
45
+
46
+ Queue.instance.pop
47
+ end
48
+
49
+ def self.targets
50
+ @@targets
51
+ end
52
+
53
+ def targets
54
+ @@targets
55
+ end
56
+
57
+ def execute_sql(sql)
58
+ statement = Database.instance.export.prepare(sql)
59
+ values = [*column_values] + [*column_values] #array expando
60
+ statement.send(:execute, @row_id, *values) #expand values into distinct arguments
61
+ end
62
+
63
+ def pk_name
64
+ 'id'
65
+ end
66
+
67
+ def column_names
68
+ return if @column_names.size == 0
69
+ ",#{@column_names.join(',')}"
70
+ end
71
+
72
+ def column_values
73
+ @column_values
74
+ end
75
+
76
+ def column_value_markers
77
+ return if @column_names.size == 0
78
+ result = ""
79
+ @column_names.size.times { result << ',?'}
80
+ result
81
+ end
82
+
83
+ def column_markers
84
+ return if @column_names.size == 0
85
+ result = ""
86
+ @column_names.each {|k| result << "#{k}=?," }
87
+ result.chop
88
+ end
89
+
90
+ class Queue < DelegateClass(Array)
91
+ include Singleton
92
+
93
+ def current
94
+ last
95
+ end
96
+
97
+ protected
98
+
99
+ def initialize
100
+ super([])
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,5 @@
1
+ class Time
2
+ def to_s
3
+ self.strftime("%Y-%m-%d %H:%M:%S %Z")
4
+ end
5
+ end
data/lib/squealer.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'squealer/object'
2
+ require 'squealer/hash'
3
+ require 'squealer/time'
4
+
5
+ require 'squealer/target'
6
+ require 'squealer/database'
@@ -0,0 +1,15 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "squealer"
5
+ gemspec.summary = "Document-oriented to Relational database exporter"
6
+ gemspec.description = "Exports mongodb to mysql. More later."
7
+ gemspec.email = "joshua.graham@grahamis.com"
8
+ gemspec.homepage = "http://github.com/deltiscere/squealer/"
9
+ gemspec.authors = ["Josh Graham", "Durran Jordan"]
10
+ gem.add_dependency('mysql', '>= 2.8.1')
11
+ gem.add_dependency('mongo', '>= 0.18.3')
12
+ end
13
+ rescue LoadError
14
+ puts "Jeweler not available. Install it with: gem install jeweler"
15
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,3 @@
1
+ --colour
2
+ --format nested
3
+ --drb
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'spork'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+
7
+ require 'squealer'
@@ -0,0 +1,41 @@
1
+ require 'mysql'
2
+ require 'mongo'
3
+ require 'spec_helper'
4
+
5
+ describe Squealer::Database do
6
+
7
+ before(:all) do
8
+ @db_name = "test_export_#{object_id}"
9
+ create_test_db(@db_name)
10
+ end
11
+
12
+ after(:all) do
13
+ drop_test_db(@db_name)
14
+ end
15
+
16
+ it "is a singleton" do
17
+ Squealer::Database.respond_to?(:instance).should be_true
18
+ end
19
+
20
+ it "takes an import database" do
21
+ Squealer::Database.instance.import_from('localhost', 27017, @db_name)
22
+ Squealer::Database.instance.import.should be_a_kind_of(Mongo::DB)
23
+ end
24
+
25
+ it "takes an export database" do
26
+ Squealer::Database.instance.export_to('localhost', 'root', '', @db_name)
27
+ Squealer::Database.instance.export.should be_a_kind_of(Mysql)
28
+ end
29
+
30
+ private
31
+
32
+ def create_test_db(name)
33
+ @my = Mysql.connect('localhost', 'root')
34
+ @my.query("create database #{name}")
35
+ end
36
+
37
+ def drop_test_db(name)
38
+ @my.query("drop database #{name}")
39
+ @my.close
40
+ end
41
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe Hash do
4
+
5
+ describe "#method_missing" do
6
+
7
+ it "treats it as a hash key lookup" do
8
+ { "name" => "Josh" }.name.should == "Josh"
9
+ end
10
+
11
+ context "with args" do
12
+
13
+ it "treats it normally" do
14
+ lambda { { "name" => "Josh" }.name(nil) }.should raise_error(NoMethodError)
15
+ end
16
+
17
+ end
18
+
19
+ context "with block" do
20
+
21
+ it "treats it normally" do
22
+ lambda { { "name" => "Josh" }.name {nil} }.should raise_error(NoMethodError)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe NilClass do
4
+
5
+ describe "#each" do
6
+ it "returns an empty array" do
7
+ nil.each.should == [] # because mongo is schema-less
8
+ end
9
+ end
10
+ end
11
+
12
+ describe Object do
13
+
14
+ describe "#target" do
15
+
16
+ it "has been defined" do
17
+ Object.new.respond_to?(:target).should be_true
18
+ end
19
+
20
+ it "invokes Squealer::Target.new" do
21
+ Squealer::Target.should_receive(:new)
22
+ target(:test_table, 1) { nil }
23
+ end
24
+
25
+ it "uses the export database connection" do
26
+ mock_mysql
27
+ target(:test_table, 1) { nil }
28
+ end
29
+
30
+ end
31
+
32
+ describe "#assign" do
33
+
34
+ it "has been defined" do
35
+ Object.new.respond_to?(:assign).should be_true
36
+ end
37
+
38
+ it "invokes assign on the target it is immediately nested within" do
39
+ mock_mysql
40
+ target(:test_table, 1) do |target1|
41
+ target1.should_receive(:assign)
42
+ assign(:colA) { 42 }
43
+
44
+ target(:test_table_2, 1) do |target2|
45
+ target2.should_receive(:assign)
46
+ assign(:colspeak) { 1984 }
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ describe "#import" do
54
+
55
+ it "has been defined" do
56
+ Object.new.respond_to?(:import).should be_true
57
+ end
58
+
59
+ context "with a single argument" do
60
+
61
+ it "invokes Database.import_from" do
62
+ Squealer::Database.instance.should_receive(:import_from)
63
+ import('test_import')
64
+ end
65
+
66
+ end
67
+
68
+ context "with no argment" do
69
+
70
+ it "invokes Database.import" do
71
+ Squealer::Database.instance.should_receive(:import)
72
+ import
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
79
+ describe "#export" do
80
+
81
+ it "has been defined" do
82
+ Object.new.respond_to?(:export).should be_true
83
+ end
84
+
85
+ context "with a single argument" do
86
+
87
+ it "invokes Database.export_to" do
88
+ Squealer::Database.instance.should_receive(:export_to)
89
+ export('test_export')
90
+ end
91
+
92
+ end
93
+
94
+ context "with no argment" do
95
+
96
+ it "invokes Database.export" do
97
+ Squealer::Database.instance.should_receive(:export)
98
+ export
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+
105
+ def mock_mysql
106
+ my = mock(Mysql)
107
+ st = mock(Mysql::Stmt)
108
+ Squealer::Database.instance.should_receive(:export).at_least(:once).and_return(my)
109
+ my.should_receive(:prepare).at_least(:once).and_return(st)
110
+ st.should_receive(:execute).at_least(:once)
111
+ end
112
+
113
+ end
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe Squealer::Target do
4
+ let(:export_dbc) { mock(Mysql) }
5
+ let(:table_name) { :test_table }
6
+ let(:row_id) { 0 }
7
+
8
+ before(:each) do
9
+ Squealer::Database.instance.should_receive(:export).at_least(:once).and_return(export_dbc)
10
+ st = mock(Mysql::Stmt)
11
+ export_dbc.should_receive(:prepare).at_least(:once).and_return(st)
12
+ st.should_receive(:execute).at_least(:once)
13
+ end
14
+
15
+ it "sends the sql to the export database" do
16
+ Squealer::Target.new(export_dbc, table_name, row_id) { nil }
17
+ end
18
+
19
+ describe "#target" do
20
+
21
+ it "pushes itself onto the targets stack when starting" do
22
+ @target1 = nil
23
+ @target2 = nil
24
+ target1 = Squealer::Target.new(export_dbc, table_name, row_id) do
25
+ @target1 = Squealer::Target.current
26
+ Squealer::Target.new(export_dbc, "#{table_name}_2", row_id) do
27
+ @target2 = Squealer::Target.current
28
+ @target2.should_not == @target1
29
+ end
30
+ end
31
+ target1.should === @target1
32
+ end
33
+
34
+ it "pops itself off the targets stack when finished" do
35
+ Squealer::Target.new(export_dbc, table_name, row_id) { nil }
36
+ Squealer::Target.current.should be_nil
37
+ end
38
+
39
+ context "generates SQL command strings" do
40
+
41
+ let(:target) { Squealer::Target.new(export_dbc, table_name, row_id) { nil } }
42
+
43
+ it "targets the table" do
44
+ target.sql.should =~ /^INSERT #{table_name} /
45
+ end
46
+
47
+ it "uses an INSERT ... ON DUPLICATE KEY UPDATE statement" do
48
+ target.sql.should =~ /^INSERT .* ON DUPLICATE KEY UPDATE /
49
+ end
50
+
51
+ it "includes the primary key name in the INSERT" do
52
+ target.sql.should =~ / \(id\) VALUES/
53
+ end
54
+
55
+ it "includes the primary key value in the INSERT" do
56
+ # target.sql.should =~ / VALUES \('#{row_id}'\) /
57
+ target.sql.should =~ / VALUES \(\?\) /
58
+ end
59
+
60
+ end
61
+
62
+ context "with inner block" do
63
+
64
+ it "yields inner blocks" do
65
+ block_done = false
66
+ target = Squealer::Target.new(export_dbc, table_name, row_id) { block_done = true }
67
+ block_done.should be_true
68
+ end
69
+
70
+ it "yields inner blocks first" do
71
+ Squealer::Target.new(export_dbc, table_name, row_id) { Squealer::Target.current.sql.should be_empty }
72
+ end
73
+
74
+ it "yields inner blocks first and they can assign to this target" do
75
+ target = Squealer::Target.new(export_dbc, table_name, row_id) { Squealer::Target.current.assign(:colA) { 42 } }
76
+ target.sql.should =~ /colA/
77
+ # target.sql.should =~ /42/
78
+ target.sql.should =~ /\?/
79
+ end
80
+
81
+ context "with 2 columns" do
82
+
83
+ let(:value_1) { 42 }
84
+ let(:target) do
85
+ Squealer::Target.new(export_dbc, table_name, row_id) { Squealer::Target.current.assign(:colA) { value_1 } }
86
+ end
87
+
88
+ it "includes the column name in the INSERT" do
89
+ target.sql.should =~ /\(id,colA\) VALUES/
90
+ end
91
+
92
+ it "includes the column value in the INSERT" do
93
+ # target.sql.should =~ /VALUES \('#{row_id}','#{value_1}'\)/
94
+ target.sql.should =~ /VALUES \(\?,\?\)/
95
+ end
96
+
97
+ it "includes the column name and value in the UPDATE" do
98
+ # target.sql.should =~ /UPDATE colA='#{value_1}'/
99
+ target.sql.should =~ /UPDATE colA=\?/
100
+ end
101
+
102
+ end
103
+
104
+ context "with 3 columns" do
105
+
106
+ let(:value_1) { 42 }
107
+ let(:value_2) { 'foobar' }
108
+ let(:target) do
109
+ Squealer::Target.new(export_dbc, table_name, row_id) do
110
+ Squealer::Target.current.assign(:colA) { value_1 }
111
+ Squealer::Target.current.assign(:colB) { value_2 }
112
+ end
113
+ end
114
+
115
+ it "includes the column names in the INSERT" do
116
+ target.sql.should =~ /\(id,colA,colB\) VALUES/
117
+ end
118
+
119
+ it "includes the column values in the INSERT" do
120
+ # target.sql.should =~ /VALUES \('#{row_id}','#{value_1}','#{value_2}'\)/
121
+ target.sql.should =~ /VALUES \(\?,\?,\?\)/
122
+ end
123
+
124
+ it "includes the column names and values in the UPDATE" do
125
+ # target.sql.should =~ /UPDATE colA='#{value_1}',colB='#{value_2}'/
126
+ target.sql.should =~ /UPDATE colA=\?,colB=\?/
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Time do
4
+
5
+ describe "#to_s" do
6
+ it "uses a MySQL compliant format" do
7
+ Time.gm(2000,"Jan",31).to_s.should == "2000-01-31 00:00:00 UTC"
8
+ end
9
+ end
10
+ end
data/squealer.gemspec ADDED
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{squealer}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Josh Graham", "Durran Jordan"]
12
+ s.date = %q{2010-03-23}
13
+ s.description = %q{Exports mongodb to mysql. More later.}
14
+ s.email = %q{joshua.graham@grahamis.com}
15
+ s.extra_rdoc_files = [
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ ".watchr",
21
+ "README.md",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/example_squeal.rb",
25
+ "lib/squealer.rb",
26
+ "lib/squealer/database.rb",
27
+ "lib/squealer/hash.rb",
28
+ "lib/squealer/object.rb",
29
+ "lib/squealer/target.rb",
30
+ "lib/squealer/time.rb",
31
+ "lib/tasks/jeweler.rake",
32
+ "spec/spec.opts",
33
+ "spec/spec_helper.rb",
34
+ "spec/squealer/database_spec.rb",
35
+ "spec/squealer/hash_spec.rb",
36
+ "spec/squealer/object_spec.rb",
37
+ "spec/squealer/target_spec.rb",
38
+ "spec/squealer/time_spec.rb",
39
+ "squealer.gemspec"
40
+ ]
41
+ s.homepage = %q{http://github.com/delitescere/squealer/}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = %q{1.3.6}
45
+ s.summary = %q{Document-oriented to Relational database exporter}
46
+ s.test_files = [
47
+ "spec/spec_helper.rb",
48
+ "spec/squealer/database_spec.rb",
49
+ "spec/squealer/hash_spec.rb",
50
+ "spec/squealer/object_spec.rb",
51
+ "spec/squealer/target_spec.rb",
52
+ "spec/squealer/time_spec.rb"
53
+ ]
54
+
55
+ if s.respond_to? :specification_version then
56
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
57
+ s.specification_version = 3
58
+
59
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
60
+ s.add_runtime_dependency(%q<mysql>, [">= 2.8.1"])
61
+ s.add_runtime_dependency(%q<mongo>, [">= 0.18.3"])
62
+ else
63
+ s.add_dependency(%q<mysql>, [">= 2.8.1"])
64
+ s.add_dependency(%q<mongo>, [">= 0.18.3"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<mysql>, [">= 2.8.1"])
68
+ s.add_dependency(%q<mongo>, [">= 0.18.3"])
69
+ end
70
+ end
71
+
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: squealer
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 0
9
+ version: 1.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Josh Graham
13
+ - Durran Jordan
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-03-23 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: mysql
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 8
31
+ - 1
32
+ version: 2.8.1
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mongo
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ - 18
45
+ - 3
46
+ version: 0.18.3
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ description: Exports mongodb to mysql. More later.
50
+ email: joshua.graham@grahamis.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - README.md
57
+ files:
58
+ - .gitignore
59
+ - .watchr
60
+ - README.md
61
+ - Rakefile
62
+ - VERSION
63
+ - lib/example_squeal.rb
64
+ - lib/squealer.rb
65
+ - lib/squealer/database.rb
66
+ - lib/squealer/hash.rb
67
+ - lib/squealer/object.rb
68
+ - lib/squealer/target.rb
69
+ - lib/squealer/time.rb
70
+ - lib/tasks/jeweler.rake
71
+ - spec/spec.opts
72
+ - spec/spec_helper.rb
73
+ - spec/squealer/database_spec.rb
74
+ - spec/squealer/hash_spec.rb
75
+ - spec/squealer/object_spec.rb
76
+ - spec/squealer/target_spec.rb
77
+ - spec/squealer/time_spec.rb
78
+ - squealer.gemspec
79
+ has_rdoc: true
80
+ homepage: http://github.com/delitescere/squealer/
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options:
85
+ - --charset=UTF-8
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ requirements: []
103
+
104
+ rubyforge_project:
105
+ rubygems_version: 1.3.6
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: Document-oriented to Relational database exporter
109
+ test_files:
110
+ - spec/spec_helper.rb
111
+ - spec/squealer/database_spec.rb
112
+ - spec/squealer/hash_spec.rb
113
+ - spec/squealer/object_spec.rb
114
+ - spec/squealer/target_spec.rb
115
+ - spec/squealer/time_spec.rb