bomdb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.bomdb +2 -0
- data/.gitignore +13 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +45 -0
- data/LICENSE.txt +22 -0
- data/README.md +66 -0
- data/Rakefile +2 -0
- data/bin/bomdb +5 -0
- data/bomdb.gemspec +31 -0
- data/data/book_of_mormon.db +0 -0
- data/data/books.json +17 -0
- data/data/verses.json +145590 -0
- data/lib/bomdb.rb +27 -0
- data/lib/bomdb/cli/application.rb +131 -0
- data/lib/bomdb/config.rb +32 -0
- data/lib/bomdb/import/base.rb +23 -0
- data/lib/bomdb/import/biblical_refs.rb +359 -0
- data/lib/bomdb/import/books.rb +36 -0
- data/lib/bomdb/import/result.rb +24 -0
- data/lib/bomdb/import/verses.rb +62 -0
- data/lib/bomdb/query.rb +40 -0
- data/lib/bomdb/range.rb +12 -0
- data/lib/bomdb/schema.rb +92 -0
- data/lib/bomdb/version.rb +3 -0
- data/spec/bomdb/config_spec.rb +27 -0
- data/spec/bomdb_spec.rb +30 -0
- data/spec/spec_helper.rb +4 -0
- metadata +174 -0
@@ -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
|
data/lib/bomdb/query.rb
ADDED
@@ -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
|
data/lib/bomdb/range.rb
ADDED
data/lib/bomdb/schema.rb
ADDED
@@ -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,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
|
data/spec/bomdb_spec.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
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
|