marty 1.0.23 → 1.0.24
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/app/components/marty/grid.rb +7 -6
- data/app/components/marty/log_view.rb +76 -0
- data/app/components/marty/main_auth_app.rb +60 -1
- data/app/models/marty/log.rb +56 -0
- data/config/locales/en.yml +6 -0
- data/lib/marty/logger.rb +26 -0
- data/lib/marty/version.rb +1 -1
- data/marty.gemspec +1 -0
- data/spec/dummy/config/application.rb +2 -0
- data/spec/features/log_view_spec.rb +90 -0
- data/spec/lib/logger_spec.rb +100 -0
- data/spec/spec_helper.rb +6 -2
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86b79d602a84a7fea3fbca2b3704a8f9ccf6b00b
|
4
|
+
data.tar.gz: 0720c7fe854939427a378e0cca9cfc8ebf96302f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4d7f133d884839c72815a068934c54b26f7c366850fda2c313cd600a277eb93d2f438d5ad932fa5b66a9f0b9b25d7177465e209bdd1e8127d0309e4bc37fed7
|
7
|
+
data.tar.gz: 429013d616affaa52db3d1eaffe52bc6402fd5e70245fb61f7de855debe7cbc68cd6214cb3e2c29dee96e535f80cc0da5e996c7a8ecc37c37df90e4dda5a873d
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -32,13 +32,14 @@ class Marty::Grid < ::Netzke::Grid::Base
|
|
32
32
|
super
|
33
33
|
|
34
34
|
c.permissions = {
|
35
|
-
create:
|
36
|
-
read:
|
37
|
-
update:
|
38
|
-
delete:
|
35
|
+
create: class_can?(:create),
|
36
|
+
read: class_can?(:read),
|
37
|
+
update: class_can?(:update),
|
38
|
+
delete: class_can?(:delete)
|
39
39
|
}
|
40
|
-
|
41
|
-
c.
|
40
|
+
|
41
|
+
c.editing = :both
|
42
|
+
c.store_config = {page_size: 30}
|
42
43
|
end
|
43
44
|
|
44
45
|
def has_search_action?
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Marty::LogView < Marty::Grid
|
2
|
+
include Marty::Extras::Layout
|
3
|
+
has_marty_permissions read: [:admin],
|
4
|
+
update: [:admin]
|
5
|
+
|
6
|
+
def configure(c)
|
7
|
+
super
|
8
|
+
|
9
|
+
c.title ||= I18n.t('log_viewer', default: "Log Viewer")
|
10
|
+
c.model = "Marty::Log"
|
11
|
+
c.paging = :buffered
|
12
|
+
c.editing = :in_form
|
13
|
+
c.attributes = [
|
14
|
+
:timestamp,
|
15
|
+
:message_type,
|
16
|
+
:message,
|
17
|
+
:details
|
18
|
+
]
|
19
|
+
|
20
|
+
c.store_config.merge!(sorters: [{property: :timestamp, direction: 'DESC'}])
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_context_menu
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_form_items
|
28
|
+
[
|
29
|
+
:timestamp,
|
30
|
+
:message_type,
|
31
|
+
:message,
|
32
|
+
textarea_field(:details).merge!({height: 400})
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
component :edit_window do |c|
|
37
|
+
super(c)
|
38
|
+
c.width = 1200
|
39
|
+
end
|
40
|
+
|
41
|
+
attribute :message_type do |c|
|
42
|
+
c.text = I18n.t("log_grid.message_type")
|
43
|
+
c.width = 100
|
44
|
+
c.read_only = true
|
45
|
+
end
|
46
|
+
|
47
|
+
attribute :message do |c|
|
48
|
+
c.text = I18n.t("log_grid.message")
|
49
|
+
c.width = 400
|
50
|
+
c.read_only = true
|
51
|
+
end
|
52
|
+
|
53
|
+
attribute :timestamp do |c|
|
54
|
+
c.text = I18n.t("log_grid.timestamp")
|
55
|
+
c.width = 200
|
56
|
+
c.read_only = true
|
57
|
+
c.xtype = :datecolumn
|
58
|
+
c.format = 'Y-m-d h:i:s.u'
|
59
|
+
c.field_config = {
|
60
|
+
xtype: :displayfield,
|
61
|
+
}
|
62
|
+
c.getter = lambda { |r| Time.at(r.timestamp) }
|
63
|
+
end
|
64
|
+
|
65
|
+
column :details do |c|
|
66
|
+
c.getter = lambda { |r| CGI.escapeHTML(r.details) }
|
67
|
+
end
|
68
|
+
|
69
|
+
attribute :details do |c|
|
70
|
+
c.text = I18n.t("log_grid.details")
|
71
|
+
c.width = 900
|
72
|
+
c.read_only = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
LogView = Marty::LogView
|
@@ -47,6 +47,20 @@ class Marty::MainAuthApp < Marty::AuthApp
|
|
47
47
|
}
|
48
48
|
end
|
49
49
|
|
50
|
+
def log_menu
|
51
|
+
[
|
52
|
+
{
|
53
|
+
text: 'Log Maintenance',
|
54
|
+
icon: icon_hack(:wrench),
|
55
|
+
disabled: !self.class.has_admin_perm?,
|
56
|
+
menu: [
|
57
|
+
:log_view,
|
58
|
+
:log_cleanup,
|
59
|
+
]
|
60
|
+
}
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
50
64
|
def system_menu
|
51
65
|
{
|
52
66
|
text: I18n.t("system"),
|
@@ -60,7 +74,7 @@ class Marty::MainAuthApp < Marty::AuthApp
|
|
60
74
|
:event_view,
|
61
75
|
:reload_scripts,
|
62
76
|
:load_seed,
|
63
|
-
] + background_jobs_menu
|
77
|
+
] + background_jobs_menu + log_menu
|
64
78
|
}
|
65
79
|
end
|
66
80
|
|
@@ -235,6 +249,21 @@ class Marty::MainAuthApp < Marty::AuthApp
|
|
235
249
|
a.disabled = !self.class.has_admin_perm?
|
236
250
|
end
|
237
251
|
|
252
|
+
action :log_view do |a|
|
253
|
+
a.text = 'View Log'
|
254
|
+
a.tooltip = 'View Log'
|
255
|
+
a.handler = :netzke_load_component_by_action
|
256
|
+
a.icon = :cog
|
257
|
+
a.disabled = !self.class.has_admin_perm?
|
258
|
+
end
|
259
|
+
|
260
|
+
action :log_cleanup do |a|
|
261
|
+
a.text = 'Cleanup Log Table'
|
262
|
+
a.tooltip = 'Delete old log records'
|
263
|
+
a.icon = :cog
|
264
|
+
a.disabled = !self.class.has_admin_perm?
|
265
|
+
end
|
266
|
+
|
238
267
|
######################################################################
|
239
268
|
|
240
269
|
def bg_command(param)
|
@@ -268,6 +297,15 @@ class Marty::MainAuthApp < Marty::AuthApp
|
|
268
297
|
client.show_detail res.html_safe.gsub("\n","<br/>"), 'Delayed Job Restart'
|
269
298
|
end
|
270
299
|
|
300
|
+
endpoint :log_cleanup do |params|
|
301
|
+
begin
|
302
|
+
Marty::Log.cleanup(params)
|
303
|
+
rescue => e
|
304
|
+
res = e.message
|
305
|
+
client.show_detail res.html_safe.gsub("\n","<br/>"), 'Log Cleanup'
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
271
309
|
######################################################################
|
272
310
|
# Postings
|
273
311
|
|
@@ -401,6 +439,23 @@ class Marty::MainAuthApp < Marty::AuthApp
|
|
401
439
|
this.server.bgStatus({});
|
402
440
|
}
|
403
441
|
JS
|
442
|
+
|
443
|
+
c.netzke_on_log_cleanup = l(<<-JS)
|
444
|
+
function(params) {
|
445
|
+
var me = this;
|
446
|
+
Ext.Msg.show({
|
447
|
+
title: 'Log Cleanup',
|
448
|
+
msg: 'Enter number of days to keep',
|
449
|
+
width: 375,
|
450
|
+
buttons: Ext.Msg.OKCANCEL,
|
451
|
+
prompt: true,
|
452
|
+
fn: function (btn, value) {
|
453
|
+
btn == "ok" && me.server.logCleanup(value);
|
454
|
+
}
|
455
|
+
});
|
456
|
+
}
|
457
|
+
JS
|
458
|
+
|
404
459
|
end
|
405
460
|
|
406
461
|
action :select_posting do |a|
|
@@ -444,6 +499,10 @@ class Marty::MainAuthApp < Marty::AuthApp
|
|
444
499
|
c.disabled = Marty::Util.warped?
|
445
500
|
end
|
446
501
|
|
502
|
+
component :log_view do |c|
|
503
|
+
c.klass = Marty::LogView
|
504
|
+
end
|
505
|
+
|
447
506
|
endpoint :reload_scripts do |params|
|
448
507
|
Marty::Script.load_scripts
|
449
508
|
client.netzke_notify 'Scripts have been reloaded'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Marty::Log < Marty::Base
|
2
|
+
|
3
|
+
def self.logfile
|
4
|
+
@logfile ||= Rails.root.join('log', Rails.env + '.sql').to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
establish_connection({
|
8
|
+
adapter: "sqlite3",
|
9
|
+
database: logfile
|
10
|
+
})
|
11
|
+
self.table_name = "log"
|
12
|
+
self.primary_key = "id"
|
13
|
+
|
14
|
+
def self.db_init
|
15
|
+
db = SQLite3::Database.new(Marty::Log.logfile)
|
16
|
+
db.execute <<-SQL
|
17
|
+
CREATE TABLE IF NOT EXISTS log (
|
18
|
+
id INTEGER PRIMARY KEY,
|
19
|
+
message_type TEXT,
|
20
|
+
message TEXT,
|
21
|
+
timestamp REAL,
|
22
|
+
details BLOB )
|
23
|
+
SQL
|
24
|
+
db
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.write_log(type, message, details)
|
28
|
+
begin
|
29
|
+
@db ||= db_init
|
30
|
+
stmt = @db.prepare <<-SQL
|
31
|
+
INSERT INTO log (message_type, message, timestamp, details)
|
32
|
+
values (?, ?, ?, ?)
|
33
|
+
SQL
|
34
|
+
stmt.bind_param(1, type.to_s)
|
35
|
+
stmt.bind_param(2, message)
|
36
|
+
stmt.bind_param(3, Time.zone.now.to_f)
|
37
|
+
stmt.bind_param(4, details.pretty_inspect)
|
38
|
+
|
39
|
+
stmt.execute
|
40
|
+
rescue => e
|
41
|
+
Marty::Util.logger.error("Marty::Logger failure: #{e.message}")
|
42
|
+
ensure
|
43
|
+
stmt.close if stmt rescue nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.cleanup(days_to_keep)
|
48
|
+
raise "Must give numeric value. (Got '#{days_to_keep}')" unless
|
49
|
+
(Float(days_to_keep) rescue false)
|
50
|
+
@db ||= db_init
|
51
|
+
cutoff = Time.zone.now.to_i - days_to_keep.to_i*60*60*24
|
52
|
+
@db.execute <<-SQL
|
53
|
+
delete from log where timestamp <= #{cutoff}
|
54
|
+
SQL
|
55
|
+
end
|
56
|
+
end
|
data/config/locales/en.yml
CHANGED
data/lib/marty/logger.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
|
3
|
+
class Marty::Logger
|
4
|
+
|
5
|
+
def self.method_missing(m, *args, &block)
|
6
|
+
return super unless
|
7
|
+
[:debug, :info, :warn, :error, :fatal, :unknown].include?(m)
|
8
|
+
Marty::Util.logger.send(m, args[0]) if Marty::Util.logger.respond_to?(m)
|
9
|
+
log(m, *args)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.log(type, message, details=nil)
|
13
|
+
Marty::Log.write_log(type, message, details)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.with_logging(error_message, error_data)
|
17
|
+
begin
|
18
|
+
yield
|
19
|
+
rescue => e
|
20
|
+
error(error_message, { message: e.message,
|
21
|
+
data: error_data })
|
22
|
+
raise "#{error_message}: #{e.message}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/marty/version.rb
CHANGED
data/marty.gemspec
CHANGED
@@ -32,6 +32,8 @@ module Dummy
|
|
32
32
|
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
33
33
|
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
34
34
|
# config.time_zone = 'Central Time (US & Canada)'
|
35
|
+
config.active_record.default_timezone = :local
|
36
|
+
config.time_zone = 'Pacific Time (US & Canada)'
|
35
37
|
|
36
38
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
37
39
|
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'logger view', js: true, capybara: true do
|
4
|
+
|
5
|
+
def manual_insert(type, message, ts, detail)
|
6
|
+
stmt = @db.prepare <<-SQL
|
7
|
+
INSERT INTO log (message_type, message, timestamp, details)
|
8
|
+
VALUES (?, ?, ?, ?)
|
9
|
+
SQL
|
10
|
+
stmt.bind_param(1, type)
|
11
|
+
stmt.bind_param(2, message)
|
12
|
+
stmt.bind_param(3, ts)
|
13
|
+
stmt.bind_param(4, detail)
|
14
|
+
stmt.execute
|
15
|
+
stmt.close
|
16
|
+
end
|
17
|
+
|
18
|
+
before(:all) do
|
19
|
+
self.use_transactional_fixtures = false
|
20
|
+
@db = SQLite3::Database.new(Marty::Log.logfile)
|
21
|
+
|
22
|
+
info_s = { info: 'message' }
|
23
|
+
error_s = [1, 2, 3, { error: 'message' }]
|
24
|
+
fatal_s = ["string", 123, { fatal: "message", another_key: 'value' }]
|
25
|
+
Marty::Logger.info('info message', nil)
|
26
|
+
Marty::Logger.error('error message', error_s)
|
27
|
+
Marty::Logger.fatal('fatal message', fatal_s)
|
28
|
+
manual_insert("debug", "hi mom", (Time.zone.now - 5.days).to_i,
|
29
|
+
["one", "two", 3, 4.0].pretty_inspect)
|
30
|
+
manual_insert("warn", "all your base", (Time.zone.now - 10.days).to_i,
|
31
|
+
[5].pretty_inspect)
|
32
|
+
@ts = (@db.execute "select timestamp from log order by timestamp desc").map do
|
33
|
+
|(ts)|
|
34
|
+
Time.zone.at(ts).strftime('%Y-%m-%dT%H:%M:%S.%L%:z')
|
35
|
+
end
|
36
|
+
|
37
|
+
@clean_file = "/tmp/clean_#{Process.pid}.psql"
|
38
|
+
save_clean_db(@clean_file)
|
39
|
+
populate_test_users
|
40
|
+
end
|
41
|
+
|
42
|
+
after(:all) do
|
43
|
+
restore_clean_db(@clean_file)
|
44
|
+
@db.execute "delete from log"
|
45
|
+
@db.close
|
46
|
+
self.use_transactional_fixtures = true
|
47
|
+
end
|
48
|
+
|
49
|
+
let(:logview) { netzke_find('log_view') }
|
50
|
+
it "updates views correctly" do
|
51
|
+
log_in_as('marty')
|
52
|
+
press('System')
|
53
|
+
show_submenu('Log Maintenance')
|
54
|
+
press('View Log')
|
55
|
+
wait_for_ready
|
56
|
+
exp_types = ["fatal", "error", "info", "debug", "warn"]
|
57
|
+
exp_messages = ["fatal message", "error message",
|
58
|
+
"info message", "hi mom", "all your base"]
|
59
|
+
exp_details = [ "[\"string\", 123, {:fatal=>\"message\", "\
|
60
|
+
":another_key=>\"value\"}]\n",
|
61
|
+
"[1, 2, 3, {:error=>\"message\"}]\n",
|
62
|
+
"nil\n",
|
63
|
+
"[\"one\", \"two\", 3, 4.0]\n",
|
64
|
+
"[5]\n"]
|
65
|
+
[[nil, 5], [7, 4], [3, 3], [0, 0]].each do |days, exp_count|
|
66
|
+
if days
|
67
|
+
press('System')
|
68
|
+
show_submenu('Log Maintenance')
|
69
|
+
press('Cleanup Log Table')
|
70
|
+
wait_for_ajax
|
71
|
+
find(:xpath, "//input[contains(@id, 'textfield')]", wait: 5).set(days)
|
72
|
+
press('OK')
|
73
|
+
wait_for_ready
|
74
|
+
find(:refresh).click
|
75
|
+
wait_for_ready
|
76
|
+
end
|
77
|
+
cnt = logview.row_count()
|
78
|
+
expect(cnt).to eq(exp_count)
|
79
|
+
types = logview.col_values('message_type', cnt, 0)
|
80
|
+
messages = logview.col_values('message', cnt, 0)
|
81
|
+
details = logview.col_values('details', cnt, 0).
|
82
|
+
map { |d| CGI.unescapeHTML(d) }
|
83
|
+
ts = logview.col_values('timestamp', cnt, 0)
|
84
|
+
expect(ts).to eq(@ts.slice(0,exp_count))
|
85
|
+
expect(types).to eq(exp_types.slice(0,exp_count))
|
86
|
+
expect(messages).to eq(exp_messages.slice(0,exp_count))
|
87
|
+
expect(details).to eq(exp_details.slice(0,exp_count))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Marty
|
4
|
+
describe Logger do
|
5
|
+
before(:all) do
|
6
|
+
self.use_transactional_fixtures = false
|
7
|
+
end
|
8
|
+
before(:each) do
|
9
|
+
@db = SQLite3::Database.new(Marty::Log.logfile)
|
10
|
+
end
|
11
|
+
after(:each) do
|
12
|
+
@db.execute "delete from log"
|
13
|
+
@db.close
|
14
|
+
end
|
15
|
+
after(:all) do
|
16
|
+
self.use_transactional_fixtures = true
|
17
|
+
end
|
18
|
+
|
19
|
+
it "logs" do
|
20
|
+
File.open(Rails.root.join("log/test.log")) do |f|
|
21
|
+
f.seek(0, IO::SEEK_END)
|
22
|
+
info_s = { info: 'message' }
|
23
|
+
error_s = [1, 2, 3, { error: 'message' }]
|
24
|
+
fatal_s = ["string", 123, { fatal: "message", another_key: 'value' }]
|
25
|
+
Marty::Logger.info('info message', info_s)
|
26
|
+
Marty::Logger.error('error message', error_s)
|
27
|
+
Marty::Logger.fatal('fatal message', fatal_s)
|
28
|
+
rails_log = f.readlines
|
29
|
+
log = @db.execute "select * from log"
|
30
|
+
log_detail = []
|
31
|
+
log_ts = []
|
32
|
+
log.each do |l|
|
33
|
+
id, type, msg, ts, detail_str = l
|
34
|
+
log_detail[id] = [type, msg, detail_str]
|
35
|
+
log_ts[id] = ts
|
36
|
+
end
|
37
|
+
expect(rails_log).to eq(["info message\n",
|
38
|
+
"error message\n",
|
39
|
+
"fatal message\n"])
|
40
|
+
expect(log_detail[1]).to eq(["info", "info message",
|
41
|
+
info_s.pretty_inspect])
|
42
|
+
expect(log_detail[2]).to eq(["error", "error message",
|
43
|
+
error_s.pretty_inspect])
|
44
|
+
expect(log_detail[3]).to eq(["fatal", "fatal message",
|
45
|
+
fatal_s.pretty_inspect])
|
46
|
+
(1..3).each do |idx|
|
47
|
+
expect(log_ts[idx]).to be_within(5).of(Time.zone.now.to_i)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
it "with_logging" do
|
52
|
+
bd = 'block description'
|
53
|
+
the_error = 'error during my block'
|
54
|
+
data = [1, 2, 3, Marty::User.first]
|
55
|
+
begin
|
56
|
+
Marty::Logger.with_logging(bd, data) do
|
57
|
+
raise the_error
|
58
|
+
end
|
59
|
+
rescue => e
|
60
|
+
raised = e.message
|
61
|
+
end
|
62
|
+
expect(raised).to eq("#{bd}: #{the_error}")
|
63
|
+
log = Marty::Log.first
|
64
|
+
expect(log.message_type).to eq('error')
|
65
|
+
expect(log.message).to eq(bd)
|
66
|
+
expect(log.details).to eq({ message: the_error,
|
67
|
+
data: data }.pretty_inspect)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
describe "Logger errors" do
|
71
|
+
it "fails gracefully" do
|
72
|
+
allow(Marty::Log).to receive(:db_init).
|
73
|
+
and_raise("Error initializing DB")
|
74
|
+
Marty::Log.instance_variable_set(:@db, nil)
|
75
|
+
File.open(Rails.root.join("log/test.log")) do |f|
|
76
|
+
f.seek(0, IO::SEEK_END)
|
77
|
+
expect{Marty::Logger.info('info message', [1,2,3])}.not_to raise_error
|
78
|
+
rails_log = f.readlines
|
79
|
+
expect(rails_log).to eq(["info message\n",
|
80
|
+
"Marty::Logger failure: Error initializing DB\n"])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
it "fails gracefully in ensure" do
|
84
|
+
Marty::Logger.info('init db', [])
|
85
|
+
close_err = 'Error closing statement'
|
86
|
+
allow_any_instance_of(SQLite3::Statement).to receive(:close).
|
87
|
+
and_raise(close_err)
|
88
|
+
File.open(Rails.root.join("log/test.log")) do |f|
|
89
|
+
f.seek(0, IO::SEEK_END)
|
90
|
+
expect{Marty::Logger.info('ensure message', [1,2,3])}.not_to raise_error
|
91
|
+
rails_log = f.readlines
|
92
|
+
expect(rails_log).to eq(["ensure message\n"])
|
93
|
+
allow_any_instance_of(SQLite3::Statement).to receive(:close).
|
94
|
+
and_call_original
|
95
|
+
sleep 1
|
96
|
+
Marty::Log.cleanup(0)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,9 +11,12 @@ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__
|
|
11
11
|
|
12
12
|
Dir[Rails.root.join("../support/**/*.rb")].each { |f| require f }
|
13
13
|
|
14
|
+
CLASSES_TO_EXCLUDE_FROM_SHARED = ["Marty::Log"]
|
14
15
|
class ActiveRecord::Base
|
15
16
|
mattr_accessor :shared_connection
|
16
|
-
|
17
|
+
class << self
|
18
|
+
alias_method :orig_connection, :connection
|
19
|
+
end
|
17
20
|
def self.clear_connection
|
18
21
|
@@shared_connection = nil
|
19
22
|
end
|
@@ -21,7 +24,8 @@ class ActiveRecord::Base
|
|
21
24
|
clear_connection
|
22
25
|
|
23
26
|
def self.connection
|
24
|
-
|
27
|
+
CLASSES_TO_EXCLUDE_FROM_SHARED.include?(model_name) ? orig_connection :
|
28
|
+
@@shared_connection || retrieve_connection
|
25
29
|
end
|
26
30
|
|
27
31
|
def self.reset_shared_connection
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arman Bostani
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2017-03-
|
17
|
+
date: 2017-03-21 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: pg
|
@@ -156,6 +156,20 @@ dependencies:
|
|
156
156
|
- - ">="
|
157
157
|
- !ruby/object:Gem::Version
|
158
158
|
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: sqlite3
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :runtime
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
159
173
|
description: Marty is a framework for viewing and reporting on versioned data.
|
160
174
|
email:
|
161
175
|
- arman.bostani@pnmac.com
|
@@ -187,6 +201,7 @@ files:
|
|
187
201
|
- app/components/marty/grid_append_only.rb
|
188
202
|
- app/components/marty/import_type_view.rb
|
189
203
|
- app/components/marty/live_search_grid_panel.rb
|
204
|
+
- app/components/marty/log_view.rb
|
190
205
|
- app/components/marty/main_auth_app.rb
|
191
206
|
- app/components/marty/mcfly_grid_panel.rb
|
192
207
|
- app/components/marty/new_posting_form.rb
|
@@ -392,6 +407,7 @@ files:
|
|
392
407
|
- app/models/marty/grid_index_numrange.rb
|
393
408
|
- app/models/marty/grid_index_string.rb
|
394
409
|
- app/models/marty/import_type.rb
|
410
|
+
- app/models/marty/log.rb
|
395
411
|
- app/models/marty/name_validator.rb
|
396
412
|
- app/models/marty/pg_enum.rb
|
397
413
|
- app/models/marty/posting.rb
|
@@ -450,6 +466,7 @@ files:
|
|
450
466
|
- lib/marty/data_importer.rb
|
451
467
|
- lib/marty/engine.rb
|
452
468
|
- lib/marty/lazy_column_loader.rb
|
469
|
+
- lib/marty/logger.rb
|
453
470
|
- lib/marty/mcfly_query.rb
|
454
471
|
- lib/marty/migrations.rb
|
455
472
|
- lib/marty/monkey.rb
|
@@ -1556,6 +1573,7 @@ files:
|
|
1556
1573
|
- spec/features/javascripts/job_dashboard_live_search.js.coffee
|
1557
1574
|
- spec/features/javascripts/login.js.coffee
|
1558
1575
|
- spec/features/jobs_dashboard_spec.rb
|
1576
|
+
- spec/features/log_view_spec.rb
|
1559
1577
|
- spec/features/reporting_spec.rb
|
1560
1578
|
- spec/features/scripting_spec.rb
|
1561
1579
|
- spec/features/scripting_test_spec.rb
|
@@ -1565,6 +1583,7 @@ files:
|
|
1565
1583
|
- spec/job_helper.rb
|
1566
1584
|
- spec/lib/data_exporter_spec.rb
|
1567
1585
|
- spec/lib/data_importer_spec.rb
|
1586
|
+
- spec/lib/logger_spec.rb
|
1568
1587
|
- spec/lib/migrations/vw_marty_postings.sql.expected
|
1569
1588
|
- spec/lib/migrations_spec.rb
|
1570
1589
|
- spec/lib/xl_spec.rb
|