marty 14.0.0 → 14.3.0

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 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