disposable_db 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea/*
6
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in disposable_db.gemspec
4
+ gemspec
data/LICENSE ADDED
File without changes
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bench/bench.rb ADDED
@@ -0,0 +1,96 @@
1
+ require File.expand_path("../bench_helper", __FILE__)
2
+
3
+ def create_columns(n = 100)
4
+ columns = []
5
+ n.times do |i|
6
+ columns << TableTemplate::Column.new("field_#{i}", String)
7
+ end
8
+ columns
9
+ end
10
+
11
+ def create_database(table_template)
12
+ database = Databases::SQLite.new(:connection_string => 'sqlite://tmp/benchmark.db')
13
+ #database = Databases::SQLite.new
14
+ database.create_table! table_template
15
+ database
16
+ end
17
+
18
+ def create_model
19
+ columns = create_columns
20
+
21
+ tt = TableTemplate.new('benchmark', columns)
22
+
23
+ database = create_database tt
24
+
25
+ DisposableModel.factory(:database => database, :table_name => tt.name)
26
+ end
27
+
28
+ n = 10000
29
+ batch = []
30
+ Benchmark.bm(30) do |x|
31
+ m = create_model
32
+ x.report("generating random data:") { n.times { generate_random_data(m.columns) } }
33
+
34
+ m = create_model
35
+ cols = m.columns
36
+ batch = []
37
+ v = generate_random_data(cols)
38
+ result = RubyProf.profile do
39
+ #x.report("imports with transaction:") do
40
+ n.times do |i|
41
+ batch << v.values
42
+ if batch.length >= 1000
43
+ m.import(cols, batch)
44
+ batch = []
45
+ end
46
+ end
47
+ m.import(cols, batch) unless batch.length < 1
48
+ #end
49
+ end
50
+
51
+ printer = RubyProf::GraphPrinter.new(result)
52
+ printer.print(STDOUT, {})
53
+
54
+ exit
55
+
56
+
57
+ # Print a graph profile to text
58
+ printer = RubyProf::GraphPrinter.new(result)
59
+ printer.print(STDOUT, {})
60
+
61
+ m = create_model
62
+ x.report("single inserts with transaction:") { m.transaction { n.times { m.insert(generate_random_data(m.columns)) } } }
63
+
64
+ m = create_model
65
+ v = generate_random_data(m.columns)
66
+ x.report("single inserts:") { n.times { m.insert(v) } }
67
+
68
+ m = create_model
69
+ h = {}
70
+ m.columns.each { |c| h[c] = :"$new_#{c.to_s}" }
71
+ p = m.dataset.prepare(:insert, :insert_all_columns, h)
72
+ v = generate_random_data(m.columns, "new_")
73
+ x.report("prepared single inserts:") do
74
+ n.times do
75
+ p.call(v)
76
+ end
77
+ end
78
+
79
+ m = create_model
80
+ x.report("single inserts with transaction:") { m.transaction { n.times { m.insert(generate_random_data(m.columns)) } } }
81
+
82
+ m = create_model
83
+ v = generate_random_data(m.columns)
84
+ x.report("multi inserts with transaction:") do
85
+ m.transaction do
86
+ n.times do
87
+ batch build_batch(batch, m.columns, v)
88
+ if batch.length >= 100
89
+ m.import(m.columns, batch)
90
+ batch = []
91
+ end
92
+ end
93
+ m.multi_insert(batch) unless batch.empty?
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'ffaker'
4
+ require 'benchmark'
5
+ require 'ruby-prof'
6
+ require 'disposable_db'
7
+ require 'fileutils'
8
+
9
+ include DisposableDB
10
+
11
+ class TableTemplate::Column
12
+
13
+ def mock
14
+ if self.type.kind_of?(Numeric)
15
+ rand(999999999999999)
16
+ else
17
+ Faker::Name.name
18
+ end
19
+ end
20
+ end
21
+
22
+ def generate_random_data(column_names, prefix = nil)
23
+ data = {}
24
+ column_names.each do |cn|
25
+ data[:"#{prefix}#{cn.to_s}"] = Faker::Name.name
26
+ end
27
+ data
28
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "disposable_db/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "disposable_db"
7
+ s.version = DisposableDB::VERSION
8
+ s.authors = ["Keith Larrimore"]
9
+ s.email = ["keithlarrimore@icehook.com"]
10
+ s.authors = ['Keith Larrimore']
11
+ s.homepage = 'https://github.com/klarrimore/disposable_db'
12
+ s.date = Date.today.to_s
13
+ s.summary = 'A utility that makes it easy to create "on-the-fly databases"'
14
+ s.description = 'A utility that makes it easy to create "on-the-fly databases"'
15
+
16
+ #s.rubyforge_project = "disposable_db"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,bench,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ # specify any dependencies here; for example:
24
+ s.add_development_dependency 'rspec', ['>= 2.9.0']
25
+ s.add_development_dependency 'bundler'
26
+ s.add_development_dependency 'ffaker', ['>= 1.13.0']
27
+ s.add_development_dependency 'ruby-prof'
28
+ s.add_runtime_dependency 'sequel', ['= 3.33.0']
29
+ end
@@ -0,0 +1,39 @@
1
+ require 'logger'
2
+ require 'tempfile'
3
+ require 'sequel'
4
+ require 'disposable_db/version'
5
+ require 'disposable_db/table_template'
6
+ require 'disposable_db/database'
7
+ require 'disposable_db/databases/sqlite'
8
+ require 'disposable_db/disposable_model'
9
+
10
+ module DisposableDB
11
+ class << self
12
+
13
+ def options
14
+ @options ||= {
15
+ :log => true
16
+ }
17
+ end
18
+
19
+ def log(message)
20
+ logger.info("[disposable_db] #{message}") if logging?
21
+ end
22
+
23
+ def logger
24
+ @logger ||= options[:logger] || Logger.new(STDOUT)
25
+ end
26
+
27
+ def logger=(logger)
28
+ @logger = logger
29
+ end
30
+
31
+ def logging?
32
+ options[:log]
33
+ end
34
+
35
+ class DisposableDBError < StandardError #:nodoc:
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ module DisposableDB
2
+ class Database
3
+ attr_accessor :connection
4
+
5
+ def initialize(args = {})
6
+ @connection = args[:connection] || Sequel.sqlite
7
+ end
8
+
9
+ def create_table!(table_template)
10
+ @connection.create_table! table_template.name.to_sym do
11
+ table_template.columns.each do |column|
12
+ column column.name.to_sym, column.type
13
+ end
14
+ end
15
+ end
16
+
17
+ def create_table(table_template)
18
+ @connection.create_table? table_template.name.to_sym do
19
+ table_template.columns.each do |column|
20
+ column column.name.to_sym, column.type
21
+ end
22
+ end
23
+ end
24
+
25
+ def table_exists?(name)
26
+ @connection.table_exists? name
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ module DisposableDB
2
+ module Databases
3
+ class SQLite < Database
4
+
5
+ def intialize(args = {})
6
+ unless args.has_key? :connection
7
+ if args[:connection_string]
8
+ args[:connection] = Sequel.sqlite(args[:connection_string])
9
+ end
10
+ end
11
+
12
+ super(args)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ module DisposableDB
2
+ class DisposableModel
3
+
4
+ class << self
5
+ def build(database, table_name)
6
+
7
+ m = Class.new(Sequel::Model(database.connection)) do
8
+ set_dataset table_name.to_sym
9
+
10
+ def self.database
11
+ @database
12
+ end
13
+
14
+ def self.database=(d)
15
+ @database = d
16
+ end
17
+
18
+ def self.transaction(opts = {}, &block)
19
+ self.database.connection.transaction opts, &block
20
+ end
21
+ end
22
+
23
+ m.database = database
24
+
25
+ m
26
+ end
27
+
28
+ end
29
+
30
+ def DisposableModel.factory(args = {})
31
+ database = args[:database] || Database.new
32
+ table_name = args[:table_name] || 'disposable_table'
33
+ build(database, table_name)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,34 @@
1
+ module DisposableDB
2
+ class TableTemplate
3
+ attr_accessor :name, :columns
4
+
5
+ def initialize(name, columns = [])
6
+ @name = name
7
+ @columns = columns
8
+ end
9
+
10
+ def add_column(column)
11
+ @columns << column
12
+ end
13
+
14
+ class Column
15
+ attr_accessor :name, :type, :indexed
16
+
17
+ def self.types
18
+ # [String, Integer, Fixnum, Bignum, Float, Numeric, BigDecimal, Date, DateTime, Time, File, TrueClass, FalseClass]
19
+ #types = Sequel::Schema::Generator::GENERIC_TYPES
20
+
21
+ #name ? types.select { |t| t.name == name }.first : types
22
+ Sequel::Schema::Generator::GENERIC_TYPES
23
+ end
24
+
25
+ def initialize(name, type, options = {})
26
+ @name = name
27
+ @type = type
28
+ @indexed = options[:indexed] || false
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module DisposableDB
2
+ VERSION = "0.0.1" unless defined? DisposableDB::VERSION
3
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ include DisposableDB::Databases
4
+
5
+ describe Database do
6
+
7
+ it "can be instantiated" do
8
+ Database.new.should be_an_instance_of(Database)
9
+ end
10
+
11
+ it "can create table" do
12
+ columns = []
13
+ columns << TableTemplate::Column.new('t1', Integer)
14
+ columns << TableTemplate::Column.new('t2', String)
15
+
16
+ tt = TableTemplate.new('foo', columns)
17
+
18
+ d = Database.new
19
+ d.table_exists?(tt.name).should be_false
20
+ d.create_table tt
21
+ d.table_exists?(tt.name).should be_true
22
+ end
23
+
24
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe SQLite do
4
+
5
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe DisposableDB do
4
+ it "can log" do
5
+ tf = Tempfile.new('output.txt')
6
+ DisposableDB.logger = Logger.new(tf)
7
+ DisposableDB.log 'foobar'
8
+ tf.close
9
+ File.read(tf.path).should =~ /foobar/
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe DisposableModel do
4
+
5
+ it "can be instantiated" do
6
+ m = DisposableModel.factory(:database => Database.new)
7
+ m.new.should be_a_kind_of(Sequel::Model)
8
+ end
9
+
10
+ it "has a database" do
11
+ m = DisposableModel.factory(:database => Database.new)
12
+ m.database.should be_a_kind_of(Database)
13
+ end
14
+
15
+ it "has a database with connection" do
16
+ m = DisposableModel.factory(:database => Database.new(:connection => Sequel.sqlite))
17
+ m.database.connection.should be_a_kind_of(Sequel::SQLite::Database)
18
+ end
19
+
20
+ it "has a database with adjustable connection" do
21
+ m1 = DisposableModel.factory(:database => Database.new(:connection => Sequel.sqlite))
22
+ m2 = DisposableModel.factory(:database => Database.new(:connection => Sequel.sqlite('/tmp/test.db')))
23
+ m1.database.connection.uri.should == 'sqlite:/'
24
+ m2.database.connection.uri.should == 'sqlite://tmp/test.db'
25
+ end
26
+
27
+ it "has an underlying table with columns" do
28
+ columns = []
29
+ columns << TableTemplate::Column.new('t1', Integer)
30
+ columns << TableTemplate::Column.new('t2', String)
31
+
32
+ tt = TableTemplate.new('foo', columns)
33
+
34
+ database = Databases::SQLite.new
35
+ database.create_table! tt
36
+
37
+ m = DisposableModel.factory(:database => database, :table_name => tt.name)
38
+ m.columns.length.should == columns.length
39
+ end
40
+
41
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'disposable_db'
4
+
5
+ include DisposableDB
6
+
7
+ RSpec.configure do |config|
8
+
9
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe TableTemplate do
4
+
5
+ it "can be instantiated" do
6
+ tt = TableTemplate.new('foo')
7
+ tt.should be_an_instance_of(TableTemplate)
8
+ end
9
+
10
+ it "can add columns" do
11
+ tt = TableTemplate.new('foo')
12
+ columns = []
13
+ columns << TableTemplate::Column.new('t1', Integer)
14
+ columns << TableTemplate::Column.new('t2', String)
15
+
16
+ columns.each do |column|
17
+ tt.add_column column
18
+ end
19
+
20
+ tt.columns.length.should == columns.length
21
+ end
22
+
23
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: disposable_db
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Keith Larrimore
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &11827800 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.9.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *11827800
25
+ - !ruby/object:Gem::Dependency
26
+ name: bundler
27
+ requirement: &11826540 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *11826540
36
+ - !ruby/object:Gem::Dependency
37
+ name: ffaker
38
+ requirement: &11824160 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.13.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *11824160
47
+ - !ruby/object:Gem::Dependency
48
+ name: ruby-prof
49
+ requirement: &11823320 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *11823320
58
+ - !ruby/object:Gem::Dependency
59
+ name: sequel
60
+ requirement: &11822320 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - =
64
+ - !ruby/object:Gem::Version
65
+ version: 3.33.0
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *11822320
69
+ description: A utility that makes it easy to create "on-the-fly databases"
70
+ email:
71
+ - keithlarrimore@icehook.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE
79
+ - README
80
+ - Rakefile
81
+ - bench/bench.rb
82
+ - bench/bench_helper.rb
83
+ - disposable_db.gemspec
84
+ - lib/disposable_db.rb
85
+ - lib/disposable_db/database.rb
86
+ - lib/disposable_db/databases/sqlite.rb
87
+ - lib/disposable_db/disposable_model.rb
88
+ - lib/disposable_db/table_template.rb
89
+ - lib/disposable_db/version.rb
90
+ - spec/database_spec.rb
91
+ - spec/databases/sqlite_spec.rb
92
+ - spec/disposable_db_spec.rb
93
+ - spec/disposable_model_spec.rb
94
+ - spec/spec_helper.rb
95
+ - spec/table_template_spec.rb
96
+ homepage: https://github.com/klarrimore/disposable_db
97
+ licenses: []
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.17
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: A utility that makes it easy to create "on-the-fly databases"
120
+ test_files: []