bomdb 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.
@@ -0,0 +1,36 @@
1
+ require 'json'
2
+
3
+ module BomDB
4
+ module Import
5
+ class Books < Import::Base
6
+
7
+ def reset
8
+ schema.reset(:books)
9
+ end
10
+
11
+ # Expected data format is:
12
+ # [
13
+ # [book_name:String, book_group:String, book_sort:Integer],
14
+ # ...
15
+ # ]
16
+ def json(data)
17
+ if !schema.has_tables?(:books)
18
+ return Import::Result.new(
19
+ success: false,
20
+ error: "Database table 'books' not present."
21
+ )
22
+ end
23
+ ensure_parsed_json(data).each do |name, group, sort|
24
+ @db[:books].insert(
25
+ book_name: name,
26
+ book_group: group,
27
+ book_sort: sort
28
+ )
29
+ end
30
+ Import::Result.new(success: true)
31
+ rescue Sequel::UniqueConstraintViolation => e
32
+ Import::Result.new(success: false, error: e)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,24 @@
1
+ module BomDB
2
+ module Import
3
+ class Result
4
+ attr_reader :success, :error
5
+
6
+ def initialize(success:, error: nil)
7
+ @success = success
8
+ @error = error
9
+ end
10
+
11
+ def success?
12
+ @success
13
+ end
14
+
15
+ def message
16
+ if @success
17
+ "Succeeded"
18
+ else
19
+ @error.to_s
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,62 @@
1
+ module BomDB
2
+ module Import
3
+ class Verses < Import::Base
4
+ TABLES = [:books, :verses, :versions, :contents]
5
+
6
+ def reset
7
+ schema.reset(*(TABLES - [:books]))
8
+ end
9
+
10
+ def json(data)
11
+ if schema.has_tables?(*TABLES)
12
+ ensure_parsed_json(data).each_pair do |book_name, year_versions|
13
+ year_versions.each do |year_version|
14
+ year_version.each_pair do |year, d|
15
+ m = d["meta"]
16
+
17
+ book = @db[:books].where(:book_name => book_name).first
18
+ if book.nil?
19
+ return Import::Result.new(success: false, error: "Unable to find book '#{book_name}'")
20
+ end
21
+
22
+ verse = @db[:verses].where(
23
+ :book_id => book[:book_id],
24
+ :verse_chapter => m["chapter"],
25
+ :verse_number => m["verse"],
26
+ :verse_heading => m["heading"] ? 0 : nil
27
+ ).first
28
+ verse_id = (verse && verse[:verse_id]) || @db[:verses].insert(
29
+ book_id: book[:book_id],
30
+ verse_chapter: m["chapter"],
31
+ verse_number: m["verse"],
32
+ verse_heading: m["heading"] ? 0 : nil
33
+ )
34
+
35
+ version = @db[:versions].where(:version_year => year).first
36
+ version_id = (version && version[:version_id]) || @db[:versions].insert(
37
+ version_name: year.to_s,
38
+ version_year: year
39
+ )
40
+
41
+ @db[:contents].insert(
42
+ version_id: version_id,
43
+ verse_id: verse_id,
44
+ content_body: d["content"]
45
+ )
46
+ end
47
+ end
48
+ end
49
+ Import::Result.new(success: true)
50
+ else
51
+ Import::Result.new(
52
+ success: false,
53
+ error: "Database tables #{TABLES.join(', ')} not ready. Try again with --reset."
54
+ )
55
+ end
56
+ rescue Sequel::UniqueConstraintViolation => e
57
+ Import::Result.new(success: false, error: e)
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ module BomDB
2
+ class Query
3
+ def initialize(edition:, exclude: nil)
4
+ @edition = edition
5
+ @exclude = exclude
6
+ end
7
+
8
+ def query(headings: false)
9
+ db = BomDB.db
10
+ q = db[:verses].
11
+ join(:books, :book_id => :book_id).
12
+ join(:versions).
13
+ join(:contents, :version_id => :version_id, :verse_id => :verses__verse_id).
14
+ order(:book_sort, :verse_heading, :verse_chapter, :verse_number).
15
+ select(:book_name, :verse_chapter, :verse_number, :content_body)
16
+ q.where!(:version_name => @edition) if @edition
17
+ q.where!(:verse_heading => nil) unless headings
18
+ q.exclude!(:verses__verse_id => db[:refs].select(:verse_id).where(:ref_name => @exclude)) if @exclude
19
+ # require 'byebug'; byebug
20
+ # p q
21
+ q
22
+ end
23
+
24
+ def print(book: true, chapter: true, verse: true, sep: ' ')
25
+ shown = false
26
+ query.each do |row|
27
+ shown = true
28
+ puts [
29
+ book && row[:book_name] || nil,
30
+ (chapter || verse) && [
31
+ chapter && row[:verse_chapter] || nil,
32
+ verse && row[:verse_number] || nil
33
+ ].compact.join(":") || nil,
34
+ row[:content_body]
35
+ ].compact.join(sep)
36
+ end
37
+ puts "Nothing found" unless shown
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,12 @@
1
+ module BomDB
2
+ # A range of verses of the Book of Mormon
3
+ class Range
4
+ def initialize(str)
5
+ @str = str
6
+ end
7
+
8
+ def parse
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,92 @@
1
+ require 'set'
2
+
3
+ module BomDB
4
+ class Schema
5
+ def initialize(db)
6
+ @db = db
7
+ end
8
+
9
+ def has_tables?(*table_names)
10
+ Set.new(@db.tables) >= Set.new(table_names)
11
+ end
12
+
13
+ def reset(*table_names)
14
+ drop_tables(table_names)
15
+ create_tables(table_names)
16
+ end
17
+
18
+ def drop_tables(table_names = nil)
19
+ (table_names || @db.tables).each do |name|
20
+ @db.drop_table(name) if @db.tables.include?(name)
21
+ end
22
+ end
23
+
24
+ def create_tables(table_names = nil)
25
+ @db.create_table(:books) do
26
+ primary_key :book_id
27
+
28
+ string :book_name, :unique => true
29
+ string :book_group
30
+ integer :book_sort
31
+ end if include?(table_names, :books)
32
+
33
+ @db.create_table(:verses) do
34
+ primary_key :verse_id
35
+ foreign_key :book_id, :books
36
+
37
+ integer :verse_chapter, :null => true
38
+ integer :verse_number, :null => true
39
+ integer :verse_heading, :null => true
40
+
41
+ index [:book_id, :verse_chapter, :verse_number, :verse_heading], :unique => true
42
+ end if include?(table_names, :verses)
43
+
44
+ @db.create_table(:versions) do
45
+ primary_key :version_id
46
+
47
+ string :version_name
48
+ integer :version_year
49
+ end if include?(table_names, :versions)
50
+
51
+ @db.create_table(:contents) do
52
+ primary_key :content_id
53
+ foreign_key :version_id, :versions
54
+ foreign_key :verse_id, :verses
55
+
56
+ string :content_body
57
+
58
+ index [:version_id, :verse_id], :unique => true
59
+ end if include?(table_names, :contents)
60
+
61
+ @db.create_table(:refs) do
62
+ primary_key :ref_id
63
+ foreign_key :verse_id, :verses
64
+
65
+ string :ref_name
66
+
67
+ string :ref_book
68
+ integer :ref_chapter
69
+ integer :ref_verse
70
+ integer :ref_page_start
71
+ integer :ref_page_end
72
+ boolean :ref_is_parallel
73
+ boolean :ref_is_quotation
74
+ end if include?(table_names, :refs)
75
+
76
+ @db.create_table(:notes) do
77
+ primary_key :note_id
78
+ foreign_key :verse_id, :verses
79
+
80
+ string :note_highlight
81
+ string :note_body
82
+ end if include?(table_names, :notes)
83
+ end
84
+
85
+ protected
86
+
87
+ def include?(table_names, name)
88
+ table_names.nil? ||
89
+ table_names.map{ |n| n.to_sym }.include?(name.to_sym)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,3 @@
1
+ module BomDB
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ require_relative '../spec_helper'
2
+
3
+ # Temporarily set env during block
4
+ def set_env(dict = {}, &block)
5
+ restore = {}
6
+ dict.each_pair{ |k,v| restore[k.to_s] = ENV[k.to_s]; ENV[k.to_s] = v }
7
+ block.call
8
+ restore.each_pair{ |k,v| ENV[k.to_s] = v }
9
+ end
10
+
11
+ describe BomDB::Config do
12
+ let(:config) { BomDB::Config.new(data_dir: '/tmp') }
13
+
14
+ it "reads ENV vars" do
15
+ set_env(BOMDB_DB_PATH: '/tmp/test') do
16
+ expect(BomDB::Config.new.db_path).to eq('/tmp/test')
17
+ end
18
+ end
19
+
20
+ it "loads config from .bomdb" do
21
+ expect(config.db_file).to eq("book_of_mormon.db")
22
+ end
23
+
24
+ it "combines data_dir to make db_path" do
25
+ expect(config.db_path).to eq("/tmp/book_of_mormon.db")
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'spec_helper'
2
+ require 'tmpdir'
3
+
4
+ describe BomDB do
5
+ it "has a version" do
6
+ expect(BomDB::VERSION).to be_a(String)
7
+ end
8
+
9
+ it "has configuration" do
10
+ expect(BomDB.config).to be_a(BomDB::Config)
11
+ end
12
+
13
+ context "with db path" do
14
+ let(:path) { File.join(@dir, "bom.db") }
15
+ before { @dir = Dir.mktmpdir }
16
+ after { FileUtils.remove_entry_secure @dir }
17
+
18
+ it "connects to sqlite db" do
19
+ db = BomDB.db(path)
20
+ expect(db).to be_a(Sequel::SQLite::Database)
21
+ end
22
+
23
+ it "creates a database file" do
24
+ db = BomDB.db(path)
25
+ db.create_table(:test) { primary_key :id }
26
+ expect(File.exist?(path)).to be_truthy
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,4 @@
1
+ require 'rspec'
2
+ require 'byebug'
3
+
4
+ require_relative '../lib/bomdb'
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bomdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Duane Johnson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sequel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.21'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.21'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.19'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.19'
55
+ - !ruby/object:Gem::Dependency
56
+ name: constellation
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.2'
111
+ description: A command-line queryable database of multiple editions of the Book of
112
+ Mormon
113
+ email:
114
+ - duane.johnson@gmail.com
115
+ executables:
116
+ - bomdb
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".bomdb"
121
+ - ".gitignore"
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - bin/bomdb
128
+ - bomdb.gemspec
129
+ - data/book_of_mormon.db
130
+ - data/books.json
131
+ - data/verses.json
132
+ - lib/bomdb.rb
133
+ - lib/bomdb/cli/application.rb
134
+ - lib/bomdb/config.rb
135
+ - lib/bomdb/import/base.rb
136
+ - lib/bomdb/import/biblical_refs.rb
137
+ - lib/bomdb/import/books.rb
138
+ - lib/bomdb/import/result.rb
139
+ - lib/bomdb/import/verses.rb
140
+ - lib/bomdb/query.rb
141
+ - lib/bomdb/range.rb
142
+ - lib/bomdb/schema.rb
143
+ - lib/bomdb/version.rb
144
+ - spec/bomdb/config_spec.rb
145
+ - spec/bomdb_spec.rb
146
+ - spec/spec_helper.rb
147
+ homepage: http://bomdb.wordtree.org
148
+ licenses:
149
+ - MIT
150
+ metadata: {}
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 2.2.2
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: Book of Mormon Database
171
+ test_files:
172
+ - spec/bomdb/config_spec.rb
173
+ - spec/bomdb_spec.rb
174
+ - spec/spec_helper.rb