marty 14.0.0 → 14.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 268b89d12df4e9698333655172962a7ae5cdb083298bbf3260d5e9314527a4cf
4
- data.tar.gz: 033e4df522a0627af012eb84174cbad90e556e055a0a0d29383dd33dc13aa65f
3
+ metadata.gz: fd079baae110bb7b7b5fdfefa0cb1c5a1c03779cbab01c8ff3f92e587cb1e6e3
4
+ data.tar.gz: fdf66588c81dee9eec99458c29ea3a519cb454b40340ba344a3daab42da2544d
5
5
  SHA512:
6
- metadata.gz: b936825cf18110a8a02691a02f35a1c8c74eb655d1ceed88600d16e2aeb8543cdb7d4e5d36fe026a0d9947d15a556cee7b4c0e6518878ddf90f7de792633d6a8
7
- data.tar.gz: 9d447d0881e640da79cdbcdbce23d9ce01ab851722c8decde17d944f48e3fd5799df4ed35ee04aa983c083741cf9b391b512b343fd3d5cee8dc7839b3b3b2488
6
+ metadata.gz: ad18ce255689328fbdb69490b4b47fbcdd97866953e92d7a68e838e2185443116539fbd65c16cc84c30ed9d9d08f2c8399b054cdced48769f48d414f523f5463
7
+ data.tar.gz: 1dd8b6f97729917f3e6dece1c20464eb01f3617fd6c5862cde4d897714680aee950bc255c4287f6b2c90183690d156978d11eefa2e1a2b86fda71a177efbf3b8
@@ -1,3 +1,4 @@
1
1
  app/assets/javascripts/marty/codemirror/*
2
2
  !.schemalintrc.js
3
+ !.schemalint-rules/*
3
4
  !.eslintrc.js
@@ -10,7 +10,8 @@ module.exports = {
10
10
  Ext: "readonly",
11
11
  CodeMirror: "readonly",
12
12
  module: "writable",
13
- process: "readonly"
13
+ process: "readonly",
14
+ require: "readonly"
14
15
  },
15
16
  parserOptions: {
16
17
  ecmaVersion: 6
@@ -0,0 +1,5 @@
1
+ const preferVarcharWithoutSizeLimit = require("./preferVarcharWithoutSizeLimit");
2
+
3
+ module.exports = {
4
+ preferVarcharWithoutSizeLimit
5
+ };
@@ -0,0 +1,29 @@
1
+ const preferVarcharWithoutSizeLimit = {
2
+ name: "prefer-varchar-without-size-limit",
3
+ docs: {
4
+ description: "Prefer using VARCHAR without size limit over varchar(255)",
5
+ url: "..."
6
+ },
7
+
8
+ process({ schemaObject, report }) {
9
+ const validator = ({ name: tableName }) => (column) => {
10
+ const columnName = column.name;
11
+ const type = column.type;
12
+
13
+ if (type.startsWith("varchar") && column.maxLength) {
14
+ report({
15
+ rule: this.name,
16
+ identifier: `${schemaObject.name}.${tableName}.${columnName}`,
17
+ message: `Prefer varchar to ${type}(${column.maxLength}) types`,
18
+ suggestedMigration: `ALTER TABLE "${tableName}" ALTER COLUMN "${columnName}" TYPE VARCHAR;`
19
+ });
20
+ }
21
+ };
22
+
23
+ schemaObject.tables.forEach((table) => {
24
+ table.columns.forEach(validator(table));
25
+ });
26
+ }
27
+ };
28
+
29
+ module.exports = preferVarcharWithoutSizeLimit;
@@ -7,16 +7,13 @@ module.exports = {
7
7
  charset: "utf8"
8
8
  },
9
9
 
10
- // plugins: ['./custom-rules'],
10
+ plugins: ["./.schemalint-rules"],
11
11
 
12
12
  rules: {
13
13
  "name-casing": ["error", "snake"],
14
14
  "name-inflection": ["error", "plural"],
15
- "prefer-jsonb-to-json": ["error"]
16
- // FIXME: user varchar with no size limit instead
17
- // We would need to update lib so it would return column size info
18
- // And create our own rule that checks that
19
- // "prefer-text-to-varchar": ["error"]
15
+ "prefer-jsonb-to-json": ["error"],
16
+ "prefer-varchar-without-size-limit": ["error"]
20
17
  },
21
18
 
22
19
  schemas: [{ name: "public" }],
@@ -1,3 +1,27 @@
1
+ 14.2.0 - 2020-05-05
2
+ =====================================================
3
+ * Treating passed nil to data grids in the same way as missing attribute
4
+ broke our lookups. Roll that change back. With this change, the behavior
5
+ would be the following:
6
+
7
+ In non strict null mode:
8
+ missing attribute matches everything
9
+ passed nil matches only wildcard keys (empty keys)
10
+
11
+ In strict_null_mode:
12
+ missing attribute matches only NULLs and wildcard keys
13
+ passed nil matches only NULLs and wildcard keys
14
+
15
+ 14.2.0 - 2020-05-05
16
+ =====================================================
17
+ * Adds `Marty::Diagnostic::Version.git_tag` method that is used in diags and can be redifined in Marty apps.
18
+
19
+ 14.1.0 - 2020-05-01
20
+ =====================
21
+ * Add cleaner service and migration. The job is disabled by default.
22
+
23
+ In monkey.rb override `CLASSES_TO_CLEAN` with the desired classes to be scanned/cleaned.
24
+
1
25
  14.0.0 - 2020-04-28
2
26
  =====================================================
3
27
  * Adds NULL support for data grid matchers:
@@ -9,6 +33,10 @@ NULL can be combined with other values in array
9
33
 
10
34
  * DataGrid's PLPGSQL lookups are no longer supported
11
35
 
36
+ 13.2.0 - 2020-04-30
37
+ =====================
38
+ * Add PDF content type handling
39
+
12
40
  13.1.0 - 2020-04-14
13
41
  =====================
14
42
  * Use ruby for Marty::DataGrid lookups. That gives a small performance boost and simplifies the code.
@@ -0,0 +1,16 @@
1
+ module Marty
2
+ class CleanerJob < ::Marty::CronJob
3
+ def perform
4
+ system_login = Rails.configuration.marty.system_account
5
+ Marty::Logger.info("Starting CleanerJob as user: #{system_login}")
6
+ system_user = Marty::User.find_by(login: system_login)
7
+
8
+ Marty::Promises::Ruby::Create.call(
9
+ module_name: 'Marty::Cleaner::CleanAll',
10
+ method_name: 'call',
11
+ method_args: [],
12
+ params: { _user_id: system_user&.id }
13
+ )
14
+ end
15
+ end
16
+ end
@@ -201,13 +201,15 @@ class Marty::DataGrid < Marty::Base
201
201
 
202
202
  unless dgh['strict_null_mode']
203
203
  next unless h_passed.key?(attr)
204
- # FIXME: Make sure it won't break lookups
204
+
205
+ # FIXME: Treating passed nil in the same way
206
+ # as missing broke our lookups. Maybe we should get back to it later.
205
207
  # Before missing attribute would match anything,
206
208
  # while explicitly passed nil would only match wildcard keys
207
209
  # We want to be consistent and treat nil attribute as missing one,
208
210
  # unless it's a stict_null_mode, where nil would be explicitly mapped
209
211
  # to NULL keys
210
- next if val.nil?
212
+ # next if val.nil?
211
213
  end
212
214
 
213
215
  converted_val = if val.nil?
@@ -240,7 +242,7 @@ class Marty::DataGrid < Marty::Base
240
242
  checks.all? do |check|
241
243
  converted_val.send(check[0], check[1])
242
244
  end
243
- elsif key_val.nil? # Non-wildcard lookup
245
+ elsif key_val.nil?
244
246
  val.nil?
245
247
  elsif m_type == 'boolean'
246
248
  key_val == converted_val
@@ -0,0 +1,39 @@
1
+ module Marty
2
+ module Cleaner
3
+ module CleanAll
4
+ LOG_DAYS_KEY = 'log_days'
5
+ MCFLY_DAYS_KEY = 'mcfly_days'
6
+ TS_DAYS_KEY = 'timestamp_days'
7
+
8
+ class << self
9
+ def log(table_type, table_name)
10
+ ::Marty::Logger.log(table_type, 'Start Clean', table_name)
11
+ count = yield
12
+ ::Marty::Logger.log(
13
+ table_type,
14
+ 'End Clean',
15
+ "#{table_name} (#{count} records deleted)"
16
+ )
17
+ end
18
+
19
+ def call
20
+ window_config = ::Marty::Cleaner::MaintenanceWindow.call
21
+ log_days = window_config.fetch(LOG_DAYS_KEY, 60)
22
+ mcfly_days = window_config.fetch(MCFLY_DAYS_KEY, 365 * 3)
23
+ ts_days = window_config.fetch(TS_DAYS_KEY, 365 * 3)
24
+
25
+ [
26
+ [LOG_DAYS_KEY, log_days],
27
+ [MCFLY_DAYS_KEY, mcfly_days],
28
+ [TS_DAYS_KEY, ts_days]
29
+ ].each do |key, value|
30
+ raise "'#{key}' must be an integer" unless value.is_a?(Integer)
31
+ end
32
+ ::Marty::Cleaner::Logs.call(log_days)
33
+ ::Marty::Cleaner::McflyModels.call(mcfly_days)
34
+ ::Marty::Cleaner::TimestampModels.call(ts_days)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ module Marty
2
+ module Cleaner
3
+ module Logs
4
+ class << self
5
+ def call(days)
6
+ Marty::Log.where(
7
+ 'timestamp < ?', Time.zone.today - days.to_i.days
8
+ ).delete_all
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,49 @@
1
+ module Marty
2
+ module Cleaner
3
+ module MaintenanceWindow
4
+ CONFIG_KEY = 'CLEANER_MAINTENANCE_WINDOW'
5
+ HASH_KEYS = ['day', 'range'].freeze
6
+ DEFAULT_DAY = 'saturday'
7
+ DEFAULT_RANGE = ['00:00', '24:00'].freeze
8
+ DAYNAMES = Date::DAYNAMES.map(&:downcase).to_set
9
+
10
+ class << self
11
+ def call
12
+ window = ::Marty::Config.fetch(CONFIG_KEY)
13
+ raise "'#{CONFIG_KEY}' is not a hash'" unless window.is_a?(Hash)
14
+
15
+ day, range = HASH_KEYS.map do |k|
16
+ raise "'#{k}' is missing from '#{CONFIG_KEY}'" unless window.key?(k)
17
+
18
+ window[k] || 'Marty::Cleaner::MaintenanceWindow'\
19
+ "::DEFAULT_#{k.upcase}".constantize
20
+ end
21
+
22
+ raise '\'day\' must be a String' unless day.is_a?(String)
23
+
24
+ pday = day.downcase
25
+ raise '\'day\' must be a valid day of the week' unless
26
+ DAYNAMES.member?(pday)
27
+
28
+ # DisableTriggers call can impact the system so we only want to
29
+ # clean on a specific maintenance days
30
+ unless Time.zone.now.send("#{pday}?")
31
+ raise "#{name.demodulize} can only be called on "\
32
+ "#{pday.capitalize}"
33
+ end
34
+
35
+ raise '\'range\' must be an array of length 2' unless
36
+ range.is_a?(Array) && range.size == 2
37
+
38
+ prange = range.map { |r| Time.zone.parse(r) }
39
+ raise 'invalid range specified' unless prange.all?
40
+
41
+ raise "Current time not within maintenance window: #{prange}" unless
42
+ Time.zone.now.between?(prange.first, prange.second)
43
+
44
+ window.merge('range' => prange, 'day' => pday)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,29 @@
1
+ module Marty
2
+ module Cleaner
3
+ module McflyModels
4
+ LOG_MESSAGE_TYPE = 'mcfly_model_cleaner'
5
+
6
+ CLASSES_TO_CLEAN = [
7
+ # Add these to monkey.rb in the format
8
+ # ::YourApp::YourModelA,
9
+ # ::YourApp::YourModelB
10
+ ].freeze
11
+
12
+ class << self
13
+ def call(days_to_keep)
14
+ CLASSES_TO_CLEAN.each do |klass|
15
+ table_name = klass.table_name
16
+ # Need to disable the McFly triggers first
17
+ ::Marty::McflyHelper::DisableTriggers.call(table_name) do
18
+ ::Marty::Cleaner::CleanAll.log(LOG_MESSAGE_TYPE, table_name) do
19
+ klass.where(
20
+ 'obsoleted_dt <= ?', Time.zone.now - days_to_keep.days
21
+ ).delete_all
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module Marty
2
+ module Cleaner
3
+ module TimestampModels
4
+ LOG_MESSAGE_TYPE = 'timestamp_model_cleaner'
5
+
6
+ CLASSES_TO_CLEAN = [
7
+ # Add these to monkey.rb in the format
8
+ # ::YourApp::YourModelA,
9
+ # ::YourApp::YourModelB
10
+ ].freeze
11
+
12
+ class << self
13
+ def call(days_to_keep)
14
+ CLASSES_TO_CLEAN.each do |klass|
15
+ table_name = klass.table_name
16
+ ::Marty::Cleaner::CleanAll.log(LOG_MESSAGE_TYPE, table_name) do
17
+ klass.where(
18
+ 'updated_at <= ?', Time.zone.now - days_to_keep.days
19
+ ).delete_all
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Marty
4
+ module McflyHelper
5
+ module DisableTriggers
6
+ class << self
7
+ def call(*tables)
8
+ conn = ActiveRecord::Base.connection
9
+ tables.each do |table_name|
10
+ conn.execute("ALTER TABLE #{table_name} DISABLE TRIGGER USER;")
11
+ end
12
+
13
+ yield
14
+ ensure
15
+ tables.each do |table_name|
16
+ conn.execute("ALTER TABLE #{table_name} ENABLE TRIGGER USER;")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ class ScheduleCleanerJob < ActiveRecord::Migration[5.1]
2
+ def up
3
+ noon_on_saturdays_cron = '0 12 * * 6'
4
+
5
+ Marty::BackgroundJob::Schedule.reset_column_information
6
+
7
+ schedule = Marty::BackgroundJob::Schedule.new(
8
+ job_class: 'Marty::CleanerJob',
9
+ cron: noon_on_saturdays_cron,
10
+ state: 'off',
11
+ arguments: [],
12
+ )
13
+
14
+ schedule.save!
15
+ end
16
+
17
+ def down
18
+ Marty::BackgroundJob::Schedule.find_by(
19
+ job_class: 'Marty::CleanerJob'
20
+ )&.destroy
21
+ end
22
+ end
@@ -1,5 +1,11 @@
1
1
  module Marty::Diagnostic
2
2
  class Version < Base
3
+ def self.git_tag
4
+ git_tag = `cd #{Rails.root}; git describe --tags --always --abbrev=7;`.strip
5
+ git_datetime = `cd #{Rails.root}; git log -1 --format=%cd;`.strip
6
+ "#{git_tag} (#{git_datetime})"
7
+ end
8
+
3
9
  diagnostic_fn do
4
10
  begin
5
11
  submodules = `cd #{Rails.root}; git submodule`.split("\n").map do |s|
@@ -11,12 +17,11 @@ module Marty::Diagnostic
11
17
  }
12
18
  end.reduce(&:merge) || {}
13
19
 
14
- git_tag = `cd #{Rails.root}; git describe --tags --always --abbrev=7;`.strip
15
- git_datetime = `cd #{Rails.root}; git log -1 --format=%cd;`.strip
16
- git = { 'Root Git' => "#{git_tag} (#{git_datetime})" }.merge(submodules)
20
+ git = { 'Root Git' => git_tag }.merge(submodules)
17
21
  rescue StandardError
18
22
  git = { 'Root Git' => error('Failed accessing git') }
19
23
  end
24
+
20
25
  rbv = "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} (#{RUBY_PLATFORM})"
21
26
  {
22
27
  'Marty' => Marty::VERSION,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Marty
4
- VERSION = '14.0.0'
4
+ VERSION = '14.3.0'
5
5
  end
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "private": true,
3
3
  "scripts": {
4
- "eslint-check": "eslint 'app/**/*.{js,jsx}' ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
5
- "eslint-write": "eslint --fix 'app/**/*.{js,jsx}' ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
6
- "prettier-check": "prettier --check \"app/**/*.{js,jsx,css,scss}\" ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
7
- "prettier-write": "prettier --write \"app/**/*.{js,jsx,css,scss}\" ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
4
+ "eslint-check": "eslint 'app/**/*.{js,jsx}' ./.schemalint-rules ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
5
+ "eslint-write": "eslint --fix 'app/**/*.{js,jsx}' ./.schemalint-rules ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
6
+ "prettier-check": "prettier --check \"app/**/*.{js,jsx,css,scss}\" ./.schemalint-rules/**/* ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
7
+ "prettier-write": "prettier --write \"app/**/*.{js,jsx,css,scss}\" ./.schemalint-rules/**/* ./.schemalintrc.js ./.eslintrc.js ./prettier.config.js",
8
8
  "lint": "yarn run eslint-check && yarn run prettier-check",
9
9
  "lint-fix": "yarn run eslint-write && yarn run prettier-write",
10
10
  "lint-schema": "schemalint"
@@ -14,7 +14,7 @@ module Marty::Diagnostic
14
14
  end
15
15
 
16
16
  def git
17
- tag = `cd #{Rails.root}; git describe --tags --always;`.strip
17
+ tag = `cd #{Rails.root}; git describe --tags --always --abbrev=7;`.strip
18
18
  git_datetime = `cd #{Rails.root}; git log -1 --format=%cd;`.strip
19
19
 
20
20
  "#{tag} (#{git_datetime})"
@@ -1,4 +1,4 @@
1
- ENV['DELAYED_VER'] = `cd #{Rails.root.to_s}; git describe --tags --always`.strip
1
+ ENV['DELAYED_VER'] = Marty::Diagnostic::Version.git_tag
2
2
 
3
3
  if Rails.env.test?
4
4
  # set a really small delay in test environment so that it doesn't