request-log-analyzer 1.2.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/bin/request-log-analyzer +33 -19
  2. data/lib/cli/database_console.rb +26 -0
  3. data/lib/cli/database_console_init.rb +42 -0
  4. data/lib/cli/tools.rb +1 -1
  5. data/lib/request_log_analyzer/aggregator/database_inserter.rb +81 -0
  6. data/lib/request_log_analyzer/aggregator/summarizer.rb +2 -2
  7. data/lib/request_log_analyzer/aggregator.rb +4 -0
  8. data/lib/request_log_analyzer/controller.rb +23 -7
  9. data/lib/request_log_analyzer/database/base.rb +114 -0
  10. data/lib/request_log_analyzer/database/connection.rb +38 -0
  11. data/lib/request_log_analyzer/database.rb +177 -0
  12. data/lib/request_log_analyzer/file_format.rb +6 -3
  13. data/lib/request_log_analyzer/mailer.rb +46 -0
  14. data/lib/request_log_analyzer/request.rb +2 -1
  15. data/lib/request_log_analyzer/source/{database.rb → database_loader.rb} +1 -1
  16. data/lib/request_log_analyzer/source/log_parser.rb +28 -15
  17. data/lib/request_log_analyzer/source.rb +7 -2
  18. data/lib/request_log_analyzer.rb +5 -8
  19. data/request-log-analyzer.gemspec +8 -8
  20. data/spec/database.yml +17 -0
  21. data/spec/fixtures/rails.db +0 -0
  22. data/spec/integration/command_line_usage_spec.rb +14 -9
  23. data/spec/lib/macros.rb +16 -0
  24. data/spec/lib/mocks.rb +18 -6
  25. data/spec/unit/aggregator/database_inserter_spec.rb +93 -0
  26. data/spec/unit/database/base_class_spec.rb +190 -0
  27. data/spec/unit/database/connection_spec.rb +34 -0
  28. data/spec/unit/database/database_spec.rb +138 -0
  29. data/spec/unit/source/log_parser_spec.rb +12 -0
  30. metadata +29 -16
  31. data/lib/request_log_analyzer/aggregator/database.rb +0 -220
  32. data/spec/spec.opts +0 -3
  33. data/spec/unit/aggregator/database_spec.rb +0 -245
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/ruby
2
- require File.dirname(__FILE__) + '/../lib/request_log_analyzer'
3
- require File.dirname(__FILE__) + '/../lib/cli/command_line_arguments'
4
- require File.dirname(__FILE__) + '/../lib/cli/progressbar'
5
- require File.dirname(__FILE__) + '/../lib/cli/tools'
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
3
+ require 'request_log_analyzer'
4
+ require 'cli/command_line_arguments'
5
+ require 'lib/cli/progressbar'
6
+ require 'lib/cli/tools'
6
7
 
7
8
  # Parse the arguments given via commandline
8
9
  begin
@@ -11,40 +12,49 @@ begin
11
12
  command_line.command(:install) do |install|
12
13
  install.parameters = 1
13
14
  end
14
-
15
+
16
+ command_line.command(:console) do |cons|
17
+ cons.option(:database, :alias => :d, :required => true)
18
+ cons.option(:format, :alias => :f, :default => 'rails')
19
+ cons.option(:apache_format)
20
+ end
21
+
15
22
  command_line.command(:strip) do |strip|
16
23
  strip.minimum_parameters = 1
17
- strip.option(:format, :alias => :f, :default => 'rails')
24
+ strip.option(:format, :alias => :f, :default => 'rails')
18
25
  strip.option(:output, :alias => :o)
19
26
  strip.switch(:discard_teaser_lines, :t)
20
27
  strip.switch(:keep_junk_lines, :j)
21
28
  end
22
-
29
+
23
30
  command_line.option(:format, :alias => :f, :default => 'rails')
24
31
  command_line.option(:apache_format)
25
-
32
+
26
33
  command_line.option(:file, :alias => :e)
34
+ command_line.option(:mail, :alias => :m)
27
35
  command_line.option(:parse_strategy, :default => 'assume-correct')
28
36
  command_line.option(:dump)
29
-
37
+
30
38
  command_line.option(:aggregator, :alias => :a, :multiple => true)
31
- command_line.option(:database, :alias => :d)
39
+
40
+ command_line.option(:database, :alias => :d)
41
+ command_line.switch(:reset_database)
32
42
 
33
43
  # filtering options
34
44
  command_line.option(:select, :multiple => true, :parameters => 2)
35
45
  command_line.option(:reject, :multiple => true, :parameters => 2)
36
46
  command_line.option(:after)
37
- command_line.option(:before)
38
-
47
+ command_line.option(:before)
48
+
39
49
  command_line.switch(:boring, :b)
40
- command_line.option(:output, :alias => :o, :default => 'FixedWidth')
50
+ command_line.option(:output, :alias => :o, :default => 'FixedWidth')
41
51
  command_line.option(:report_width, :default => terminal_width - 1)
42
-
52
+
43
53
  command_line.switch(:debug)
44
-
45
- command_line.minimum_parameters = 1
54
+
55
+ command_line.minimum_parameters = 1
46
56
  end
47
-
57
+
48
58
  rescue CommandLine::Error => e
49
59
  puts "Request-log-analyzer, by Willem van Bergen and Bart ten Brinke - version #{RequestLogAnalyzer::VERSION}"
50
60
  puts "Website: http://railsdoctors.com"
@@ -65,6 +75,7 @@ rescue CommandLine::Error => e
65
75
  puts " --database <filename>, -d: Creates an SQLite3 database of all the parsed request information."
66
76
  puts " --debug Print debug information while parsing."
67
77
  puts " --file <filename> Output to file."
78
+ puts " --mail <emailaddress> Send report to an email address."
68
79
  puts " --output <format> Output format. Supports 'HTML' and 'FixedWidth' (default)"
69
80
  puts " --dump <filename> Dump the YAML formatted results in the given file"
70
81
  puts
@@ -83,11 +94,14 @@ end
83
94
  case arguments.command
84
95
  when :install
85
96
  install_rake_tasks(arguments.parameters[0])
97
+ when :console
98
+ require 'cli/database_console'
99
+ DatabaseConsole.new(arguments).run!
86
100
  when :strip
87
- require File.dirname(__FILE__) + '/../lib/request_log_analyzer/log_processor'
101
+ require File.dirname(__FILE__) + '/../lib/request_log_analyzer/log_processor'
88
102
  RequestLogAnalyzer::LogProcessor.build(:strip, arguments).run!
89
103
  else
90
- puts "Request-log-analyzer, by Willem van Bergen and Bart ten Brinke - version #{RequestLogAnalyzer::VERSION}"
104
+ puts "Request-log-analyzer, by Willem van Bergen and Bart ten Brinke - version #{RequestLogAnalyzer::VERSION}"
91
105
  puts "Website: http://railsdoctors.com"
92
106
  puts
93
107
 
@@ -0,0 +1,26 @@
1
+
2
+ class DatabaseConsole
3
+
4
+ IRB = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
5
+
6
+ def initialize(arguments)
7
+ @arguments = arguments
8
+ end
9
+
10
+ def run!
11
+ libraries = ['irb/completion', 'rubygems', './lib/request_log_analyzer', './lib/cli/database_console_init']
12
+ libaries_string = libraries.map { |l| "-r #{l}" }.join(' ')
13
+
14
+ ENV['RLA_DBCONSOLE_DATABASE'] = @arguments[:database]
15
+ if @arguments[:apache_format]
16
+ ENV['RLA_DBCONSOLE_FORMAT'] = 'apache'
17
+ ENV['RLA_DBCONSOLE_FORMAT_ARGUMENT'] = @arguments[:apache_format]
18
+ else
19
+ ENV['RLA_DBCONSOLE_FORMAT'] = @arguments[:format]
20
+ end
21
+ # ENV['RLA_DBCONSOLE_FORMAT_ARGS'] = arguments['database']
22
+
23
+ exec("#{IRB} #{libaries_string} --simple-prompt")
24
+ end
25
+ end
26
+
@@ -0,0 +1,42 @@
1
+ # Setup the include path
2
+ $:.unshift(File.dirname(__FILE__) + '/..')
3
+
4
+ $database = RequestLogAnalyzer::Database.new(ENV['RLA_DBCONSOLE_DATABASE'])
5
+ $database.load_database_schema!
6
+
7
+ require 'cli/tools'
8
+
9
+ def wordwrap(string, max = 80, indent = "")
10
+ strings = [""]
11
+ string.split(", ").each do |item|
12
+ if strings.last.length == 0 || strings.last.length + item.length <= max
13
+ strings.last << item << ', '
14
+ else
15
+ strings << (item + ', ')
16
+ end
17
+ end
18
+ strings.map(&:strip).join("\n#{indent}").slice(0..-2)
19
+ end
20
+
21
+ class Request
22
+ def inspect
23
+ request_inspect = "Request[id: #{id}]"
24
+ request_inspect << " <#{lines.first.source.filename}>" if lines.first.source
25
+
26
+ inspected_lines = lines.map do |line|
27
+ inspect_line = " - #{line.line_type} (line #{line.lineno})"
28
+ if (inspect_attributes = line.attributes.reject { |(k, v)| [:id, :source_id, :request_id, :lineno].include?(k.to_sym) }).any?
29
+ inspect_attributes = inspect_attributes.map { |(k,v)| "#{k} = #{v.inspect}" }.join(', ')
30
+ inspect_line << "\n " + wordwrap(inspect_attributes, terminal_width - 6, " ")
31
+ end
32
+ inspect_line
33
+ end
34
+
35
+ request_inspect << "\n" << inspected_lines.join("\n") << "\n\n"
36
+ end
37
+ end
38
+
39
+ puts "request-log-analyzer database console"
40
+ puts "-------------------------------------"
41
+ puts "The following ActiveRecord classes are available:"
42
+ puts $database.orm_classes.join(", ")
data/lib/cli/tools.rb CHANGED
@@ -13,7 +13,7 @@ def terminal_width(default_width = 81)
13
13
  end
14
14
  rescue
15
15
  begin
16
- IO.popen('stty -a') do |pipe|
16
+ IO.popen('stty -a 2>&1') do |pipe|
17
17
  column_line = pipe.detect { |line| /(\d+) columns/ =~ line }
18
18
  raise unless column_line
19
19
  $1.to_i
@@ -0,0 +1,81 @@
1
+
2
+ module RequestLogAnalyzer::Aggregator
3
+
4
+ # The database aggregator will create an SQLite3 database with all parsed request information.
5
+ #
6
+ # The prepare method will create a database schema according to the file format definitions.
7
+ # It will also create ActiveRecord::Base subclasses to interact with the created tables.
8
+ # Then, the aggregate method will be called for every parsed request. The information of
9
+ # these requests is inserted into the tables using the ActiveRecord classes.
10
+ #
11
+ # A requests table will be created, in which a record is inserted for every parsed request.
12
+ # For every line type, a separate table will be created with a request_id field to point to
13
+ # the request record, and a field for every parsed value. Finally, a warnings table will be
14
+ # created to log all parse warnings.
15
+ class DatabaseInserter < Base
16
+
17
+ attr_reader :request_count, :sources, :database
18
+
19
+ # Establishes a connection to the database and creates the necessary database schema for the
20
+ # current file format
21
+ def prepare
22
+ @sources = {}
23
+ @database = RequestLogAnalyzer::Database.new(options[:database])
24
+ @database.file_format = source.file_format
25
+
26
+ database.drop_database_schema! if options[:reset_database]
27
+ database.create_database_schema!
28
+ end
29
+
30
+ # Aggregates a request into the database
31
+ # This will create a record in the requests table and create a record for every line that has been parsed,
32
+ # in which the captured values will be stored.
33
+ def aggregate(request)
34
+ @request_object = database.request_class.new(:first_lineno => request.first_lineno, :last_lineno => request.last_lineno)
35
+ request.lines.each do |line|
36
+ class_columns = database.get_class(line[:line_type]).column_names.reject { |column| ['id', 'source_id', 'request_id'].include?(column) }
37
+ attributes = Hash[*line.select { |(k, v)| class_columns.include?(k.to_s) }.flatten]
38
+ attributes[:source_id] = @sources[line[:source]].id if @sources[line[:source]]
39
+ @request_object.send("#{line[:line_type]}_lines").build(attributes)
40
+ end
41
+ @request_object.save!
42
+ rescue SQLite3::SQLException => e
43
+ raise Interrupt, e.message
44
+ end
45
+
46
+ # Finalizes the aggregator by closing the connection to the database
47
+ def finalize
48
+ @request_count = database.request_class.count
49
+ database.disconnect
50
+ database.remove_orm_classes!
51
+ end
52
+
53
+ # Records w warining in the warnings table.
54
+ def warning(type, message, lineno)
55
+ database.warning_class.create!(:warning_type => type.to_s, :message => message, :lineno => lineno)
56
+ end
57
+
58
+ # Records source changes in the sources table
59
+ def source_change(change, filename)
60
+ case change
61
+ when :started
62
+ @sources[filename] = database.source_class.create!(:filename => filename)
63
+ when :finished
64
+ @sources[filename].update_attributes!(:filesize => File.size(filename), :mtime => File.mtime(filename))
65
+ end
66
+ end
67
+
68
+ # Prints a short report of what has been inserted into the database
69
+ def report(output)
70
+ output.title('Request database created')
71
+
72
+ output << "A database file has been created with all parsed request information.\n"
73
+ output << "#{@request_count} requests have been added to the database.\n"
74
+ output << "\n"
75
+ output << "To open a Ruby console to inspect the database, run the following command.\n"
76
+ output << output.colorize(" $ request-log-analyzer console -d #{options[:database]}\n", :bold)
77
+ output << "\n"
78
+ end
79
+
80
+ end
81
+ end
@@ -130,9 +130,9 @@ module RequestLogAnalyzer::Aggregator
130
130
  output.with_style(:cell_separator => false) do
131
131
  output.table({:width => 20}, {:font => :bold}) do |rows|
132
132
  rows << ['Parsed lines:', source.parsed_lines]
133
- rows << ['Parsed requests:', source.parsed_requests]
134
133
  rows << ['Skipped lines:', source.skipped_lines]
135
-
134
+ rows << ['Parsed requests:', source.parsed_requests]
135
+ rows << ['Skipped requests:', source.skipped_requests]
136
136
  rows << ["Warnings:", @warnings_encountered.map { |(key, value)| "#{key}: #{value}" }.join(', ')] if has_warnings?
137
137
  end
138
138
  end
@@ -44,6 +44,10 @@ module RequestLogAnalyzer::Aggregator
44
44
  # in this function.
45
45
  def report(output)
46
46
  end
47
+
48
+ # The source_change function gets called when handling a source is started or finished.
49
+ def source_change(change, filename)
50
+ end
47
51
 
48
52
  end
49
53
  end
@@ -32,7 +32,10 @@ module RequestLogAnalyzer
32
32
  def self.build(arguments)
33
33
  options = { }
34
34
 
35
- options[:database] = arguments[:database] if arguments[:database]
35
+ # Database command line options
36
+ options[:database] = arguments[:database] if arguments[:database]
37
+ options[:reset_database] = arguments[:reset_database]
38
+
36
39
  options[:debug] = arguments[:debug]
37
40
  options[:dump] = arguments[:dump]
38
41
 
@@ -40,6 +43,9 @@ module RequestLogAnalyzer
40
43
  if arguments[:file]
41
44
  output_file = File.new(arguments[:file], "w+")
42
45
  options[:output] = output_class.new(output_file, :width => 80, :color => false, :characters => :ascii)
46
+ elsif arguments[:mail]
47
+ output_mail = RequestLogAnalyzer::Mailer.new(arguments[:mail])
48
+ options[:output] = output_class.new(output_mail, :width => 80, :color => false, :characters => :ascii)
43
49
  else
44
50
  options[:output] = output_class.new(STDOUT, :width => arguments[:report_width].to_i,
45
51
  :color => !arguments[:boring], :characters => (arguments[:boring] ? :ascii : :utf))
@@ -68,7 +74,7 @@ module RequestLogAnalyzer
68
74
  end
69
75
 
70
76
  controller = Controller.new(RequestLogAnalyzer::Source::LogParser.new(file_format, options), options)
71
- #controller = Controller.new(RequestLogAnalyzer::Source::Database.new(file_format, options), options)
77
+ #controller = Controller.new(RequestLogAnalyzer::Source::DatabaseLoader.new(file_format, options), options)
72
78
 
73
79
  options[:parse_strategy] = arguments[:parse_strategy]
74
80
 
@@ -92,9 +98,9 @@ module RequestLogAnalyzer
92
98
  arguments[:aggregator].each { |agg| controller.add_aggregator(agg.to_sym) }
93
99
 
94
100
  # register the database
95
- controller.add_aggregator(:database) if arguments[:database] && !arguments[:aggregator].include?('database')
96
- controller.add_aggregator(:summarizer) if arguments[:aggregator].empty?
97
-
101
+ controller.add_aggregator(:summarizer) if arguments[:aggregator].empty?
102
+ controller.add_aggregator(:database_inserter) if arguments[:database] && !arguments[:aggregator].include?('database')
103
+
98
104
  # register the echo aggregator in debug mode
99
105
  controller.add_aggregator(:echo) if arguments[:debug]
100
106
 
@@ -128,6 +134,8 @@ module RequestLogAnalyzer
128
134
 
129
135
  # Handle progress messagess
130
136
  @source.progress = lambda { |message, value| handle_progress(message, value) } if @source
137
+
138
+ @source.source_changes = lambda { |change, filename| handle_source_change(change, filename) } if @source
131
139
  end
132
140
 
133
141
  # Progress function.
@@ -151,6 +159,11 @@ module RequestLogAnalyzer
151
159
  end
152
160
  end
153
161
 
162
+ # Source change handler
163
+ def handle_source_change(change, filename)
164
+ @aggregators.each { |agg| agg.source_change(change, File.expand_path(filename, Dir.pwd)) }
165
+ end
166
+
154
167
  # Adds an aggregator to the controller. The aggregator will be called for every request
155
168
  # that is parsed from the provided sources (see add_source)
156
169
  def add_aggregator(agg)
@@ -180,8 +193,9 @@ module RequestLogAnalyzer
180
193
  # Push a request to all the aggregators (@aggregators).
181
194
  # <tt>request</tt> The request to push to the aggregators.
182
195
  def aggregate_request(request)
183
- return unless request
196
+ return false unless request
184
197
  @aggregators.each { |agg| agg.aggregate(request) }
198
+ return true
185
199
  end
186
200
 
187
201
  # Runs RequestLogAnalyzer
@@ -198,8 +212,8 @@ module RequestLogAnalyzer
198
212
  install_signal_handlers
199
213
 
200
214
  @source.each_request do |request|
201
- aggregate_request(filter_request(request))
202
215
  break if @interrupted
216
+ aggregate_request(filter_request(request))
203
217
  end
204
218
 
205
219
  @aggregators.each { |agg| agg.finalize }
@@ -217,6 +231,8 @@ module RequestLogAnalyzer
217
231
  puts "Mail to contact@railsdoctors.com or visit us at http://railsdoctors.com"
218
232
  puts "Thanks for using request-log-analyzer!"
219
233
  @output.io.close
234
+ elsif @output.io.kind_of?(RequestLogAnalyzer::Mailer)
235
+ @output.io.mail
220
236
  end
221
237
  end
222
238
 
@@ -0,0 +1,114 @@
1
+ class RequestLogAnalyzer::Database::Base < ActiveRecord::Base
2
+
3
+ self.abstract_class = true
4
+
5
+ def <=>(other)
6
+ if (source_id.nil? && other.source_id.nil?) || (source_comparison = source_id <=> other.source_id) == 0
7
+ lineno <=> other.lineno
8
+ else
9
+ source_comparison
10
+ end
11
+ end
12
+
13
+ def line_type
14
+ self.class.name.underscore.gsub(/_line$/, '').to_sym
15
+ end
16
+
17
+ cattr_accessor :database, :line_definition
18
+
19
+ def self.subclass_from_line_definition(definition)
20
+ klass = Class.new(RequestLogAnalyzer::Database::Base)
21
+ klass.set_table_name("#{definition.name}_lines")
22
+
23
+ klass.line_definition = definition
24
+
25
+ # Set relations with requests and sources table
26
+ klass.belongs_to :request
27
+ klass.belongs_to :source
28
+
29
+ # Serialize complex fields into the database
30
+ definition.captures.select { |c| c.has_key?(:provides) }.each do |capture|
31
+ klass.send(:serialize, capture[:name], Hash)
32
+ end
33
+
34
+ database.request_class.has_many "#{definition.name}_lines".to_sym
35
+ database.source_class.has_many "#{definition.name}_lines".to_sym
36
+
37
+ return klass
38
+ end
39
+
40
+ def self.subclass_from_table(table)
41
+ raise "Table #{table} not found!" unless database.connection.table_exists?(table)
42
+
43
+ klass = Class.new(RequestLogAnalyzer::Database::Base)
44
+ klass.set_table_name(table)
45
+
46
+ if klass.column_names.include?('request_id')
47
+ klass.belongs_to :request
48
+ database.request_class.has_many table.to_sym
49
+ end
50
+
51
+ if klass.column_names.include?('source_id')
52
+ klass.belongs_to :source
53
+ database.source_class.has_many table.to_sym
54
+ end
55
+
56
+ return klass
57
+ end
58
+
59
+ def self.drop_table!
60
+ database.connection.remove_index(self.table_name, [:source_id]) rescue nil
61
+ database.connection.remove_index(self.table_name, [:request_id]) rescue nil
62
+ database.connection.drop_table(self.table_name) if database.connection.table_exists?(self.table_name)
63
+ end
64
+
65
+ def self.create_table!
66
+ raise "No line_definition available to base table schema on!" unless self.line_definition
67
+
68
+ unless table_exists?
69
+ database.connection.create_table(table_name.to_sym) do |t|
70
+
71
+ # Default fields
72
+ t.column :request_id, :integer
73
+ t.column :source_id, :integer
74
+ t.column :lineno, :integer
75
+
76
+ line_definition.captures.each do |capture|
77
+ # Add a field for every capture
78
+ t.column(capture[:name], column_type(capture[:type]))
79
+
80
+ # If the capture provides other field as well, create columns for them, too
81
+ capture[:provides].each { |field, field_type| t.column(field, column_type(field_type)) } if capture[:provides].kind_of?(Hash)
82
+ end
83
+ end
84
+ end
85
+
86
+ # Add indices to table for more speedy querying
87
+ database.connection.add_index(self.table_name.to_sym, [:request_id]) # rescue
88
+ database.connection.add_index(self.table_name.to_sym, [:source_id]) # rescue
89
+ end
90
+
91
+
92
+ # Function to determine the column type for a field
93
+ # TODO: make more robust / include in file-format definition
94
+ def self.column_type(type_indicator)
95
+ case type_indicator
96
+ when :eval; :text
97
+ when :hash; :text
98
+ when :text; :text
99
+ when :string; :string
100
+ when :sec; :double
101
+ when :msec; :double
102
+ when :duration; :double
103
+ when :float; :double
104
+ when :double; :double
105
+ when :integer; :integer
106
+ when :int; :int
107
+ when :timestamp; :datetime
108
+ when :datetime; :datetime
109
+ when :date; :date
110
+ else :string
111
+ end
112
+ end
113
+
114
+ end
@@ -0,0 +1,38 @@
1
+ module RequestLogAnalyzer::Database::Connection
2
+
3
+ def self.from_string(string)
4
+ hash = {}
5
+ if string =~ /^(?:\w+=(?:[^;])*;)*\w+=(?:[^;])*$/
6
+ string.scan(/(\w+)=([^;]*);?/) { |variable, value| hash[variable.to_sym] = value }
7
+ elsif string =~ /^(\w+)\:\/\/(?:(?:([^:]+)(?:\:([^:]+))?\@)?([\w\.-]+)\/)?([\w\:\-\.\/]+)$/
8
+ hash[:adapter], hash[:username], hash[:password], hash[:host], hash[:database] = $1, $2, $3, $4, $5
9
+ hash.delete_if { |k, v| v.nil? }
10
+ end
11
+ return hash.empty? ? nil : hash
12
+ end
13
+
14
+ def connect(connection_identifier)
15
+ if connection_identifier.kind_of?(Hash)
16
+ RequestLogAnalyzer::Database::Base.establish_connection(connection_identifier)
17
+ elsif connection_identifier == ':memory:'
18
+ RequestLogAnalyzer::Database::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
19
+ elsif connection_hash = RequestLogAnalyzer::Database::Connection.from_string(connection_identifier)
20
+ RequestLogAnalyzer::Database::Base.establish_connection(connection_hash)
21
+ elsif connection_identifier.kind_of?(String) # Normal SQLite 3 database file
22
+ RequestLogAnalyzer::Database::Base.establish_connection(:adapter => 'sqlite3', :database => connection_identifier)
23
+ elsif connection_identifier.nil?
24
+ nil
25
+ else
26
+ raise "Cannot connect with this connection_identifier: #{connection_identifier.inspect}"
27
+ end
28
+ end
29
+
30
+ def disconnect
31
+ RequestLogAnalyzer::Database::Base.remove_connection
32
+ end
33
+
34
+ def connection
35
+ RequestLogAnalyzer::Database::Base.connection
36
+ end
37
+
38
+ end