Class: Poefy::Database

Inherits:
Object
  • Object
show all
Includes:
HandleError, StringManipulation
Defined in:
lib/poefy/database.rb

Constant Summary collapse

@@final =

Finalizer must be a class variable.

proc { |dbase, sproc| proc {
  sproc.each { |k, v| v.close }
  dbase.close if dbase
} }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db_file, console = false) ⇒ Database

Returns a new instance of Database.



31
32
33
34
35
36
37
# File 'lib/poefy/database.rb', line 31

def initialize db_file, console = false
  @db_file = db_file
  @console = console
  @sproc = {}
  db
  ObjectSpace.define_finalizer(self, @@final.call(@db, @sproc))
end

Instance Attribute Details

#consoleObject (readonly)

Returns the value of attribute console.



23
24
25
# File 'lib/poefy/database.rb', line 23

def console
  @console
end

#db_fileObject (readonly)

Returns the value of attribute db_file.



23
24
25
# File 'lib/poefy/database.rb', line 23

def db_file
  @db_file
end

Instance Method Details

#closeObject

Close the database file.



61
62
63
64
65
# File 'lib/poefy/database.rb', line 61

def close
  @sproc.each { |k, v| v.close rescue nil }
  @db.close if @db
  @db = nil
end

#dbObject

Open global database session, if not already existing. This is called in all methods where it is needed. So no need to

execute it before any calling code.


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/poefy/database.rb', line 42

def db
  if not @db
    if !exists?
      @db = nil
    else
      begin
        @db = SQLite3::Database.open(@db_file)
        @db.results_as_hash = true
      rescue
        @db = nil
        return handle_error 'ERROR: Database contains invalid structure'
      end
      create_sprocs
    end
  end
  @db
end

#execute!(sql) ⇒ Object

Execute an SQL request.



113
114
115
116
117
118
119
# File 'lib/poefy/database.rb', line 113

def execute! sql
  begin
    db.execute sql
  rescue
    return handle_error 'ERROR: Database has incorrect table structure', []
  end
end

#exists?Boolean

See if the database file exists or not.

Returns:

  • (Boolean)


68
69
70
# File 'lib/poefy/database.rb', line 68

def exists?
  File.exists?(@db_file)
end

#format_sql_string(string) ⇒ Object

Format a string for SQL.



122
123
124
# File 'lib/poefy/database.rb', line 122

def format_sql_string string
  string.gsub('"','""')
end

#make_new(lines) ⇒ Object

Creates a database with the correct format.

Convert input lines array to SQL import format file.
Delete database if already exists.
Create database using SQL import file.
Delete both files.


77
78
79
# File 'lib/poefy/database.rb', line 77

def make_new lines
  make_new!(lines) if !exists?
end

#make_new!(lines) ⇒ Object

Force new database, overwriting existing.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/poefy/database.rb', line 82

def make_new! lines

  # Convert the lines array into an import file.
  sql_import_file = save_sql_import_file lines

  # Delete any existing database.
  File.delete(@db_file) if File.exists?(@db_file)

  # Write SQL and SQLite instructions to temp file,
  #   import to database, delete temp file.
  # The SQL file is finicky. Each line requires no leading whitespace.
  sql_instruction_file = tmpfile
  sql = %Q[
    CREATE TABLE IF NOT EXISTS lines (
      line TEXT, syllables INT, final_word TEXT, rhyme TEXT
    );
    CREATE INDEX idx ON lines (rhyme, final_word, line);
    .separator "\t"
    .import #{sql_import_file} lines
  ].split("\n").map(&:strip).join("\n")
  File.open(sql_instruction_file, 'w') { |fo| fo.write sql }

  # Create the database using the SQL instructions.
  `sqlite3 #{@db_file} < #{sql_instruction_file}`

  # Delete temporary files.
  File.delete sql_instruction_file
  File.delete sql_import_file
end

#sproc_lines_all!(rhyme, syllable_min_max = nil) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/poefy/database.rb', line 140

def sproc_lines_all! rhyme, syllable_min_max = nil
  db
  @la = Hash.new { |h,k| h[k] = {} } if @la.nil?
  if @la[rhyme][syllable_min_max].nil?
    @la[rhyme][syllable_min_max] = if syllable_min_max
      sproc_lines_all_syllables(rhyme, syllable_min_max)
    else
      sproc_lines_all(rhyme)
    end
  end
  @la[rhyme][syllable_min_max].dup
end

#sproc_rhymes_all!(rhyme_count, syllable_min_max = nil) ⇒ Object

Public interfaces for private stored procedure methods. Use instance variables to keep a cache of the results.



128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/poefy/database.rb', line 128

def sproc_rhymes_all! rhyme_count, syllable_min_max = nil
  db
  @rbc = Hash.new { |h,k| h[k] = {} } if @rbc.nil?
  if @rbc[rhyme_count][syllable_min_max].nil?
    @rbc[rhyme_count][syllable_min_max] = if syllable_min_max
      sproc_rhymes_by_count_syllables(rhyme_count, syllable_min_max)
    else
      sproc_rhymes_by_count(rhyme_count)
    end
  end
  @rbc[rhyme_count][syllable_min_max].dup
end