yaml-file-db 0.1.1 → 0.1.6

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: dcccc03ffdf919d10a071489113df40c30a6bdc7895648b333ce3fc892a95322
4
- data.tar.gz: 9a5b1b311ed1cf15c73ecdc5fe2e33bd2e3471973d7909569d25881f579081b8
3
+ metadata.gz: e267ac60c172096d2484e3e86854886c4c4dbbeb7c895cae083eea0781d4fb00
4
+ data.tar.gz: 96258128806aea1f96017700203a485f204da736ab0ebcffce36fbfdc2654f57
5
5
  SHA512:
6
- metadata.gz: c8569acad2ff389a8827dfb4203aa56525de1465849f01be2fa3f1f04742015d8fc615bf7c778f463ad8e752ceee1254928d268e3e3ee7568e704a5f4f2cd340
7
- data.tar.gz: c4189b21b1b971969a0f2dfe3d2bb48ca181689f827b8e4bedefdd1033bb263f531c7248da2a364ef7d23d195ef802a58f2bb1c8f4ebd6ac4e668212e96684a8
6
+ metadata.gz: 34099bed1433f9fe540fb4a0f5f1a9a16c63b44f17b2809f6a535438da4968b6e1ae7874278b1628335f391b8fa280af442cd03235b6235764fe01b2501b4c73
7
+ data.tar.gz: ef76c1a1cafe075452fdaaf0d2f0250c0141a05cf81edf028c76bdf54cfb8e22653464df87e15e7430bebcc76367f650f838ff937f6ea3b3b5ac630fe4f950fa
data/lib/yaml-file-db.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/inflector'
2
4
  require 'json-schema'
3
5
  require 'yaml'
4
6
 
5
- require 'yaml-file-db/database.rb'
6
- require 'yaml-file-db/exception.rb'
7
- require 'yaml-file-db/row.rb'
7
+ require 'yaml-file-db/database'
8
+ require 'yaml-file-db/exception'
9
+ require 'yaml-file-db/row'
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module YDB
2
4
  class Database
3
-
4
- INTERNAL_VARS = [:@errors, :@schemas, :@source].freeze
5
+ INTERNAL_VARS = %i[@errors @schemas @source].freeze
5
6
 
6
7
  attr_reader :errors, :schemas, :source
7
8
 
@@ -11,15 +12,16 @@ module YDB
11
12
  @source = source
12
13
  end
13
14
 
14
- def build()
15
- build_tables()
16
- build_relationships()
15
+ def build
16
+ build_tables
17
+ build_relationships
18
+ check_relationships
17
19
  self
18
20
  end
19
21
 
20
22
  private
21
23
 
22
- def build_tables()
24
+ def build_tables
23
25
  Dir["#{@source}/*"].each do |table_path|
24
26
  table = {}
25
27
 
@@ -29,37 +31,51 @@ module YDB
29
31
  schema_path = "#{@schemas}/#{table_name.singularize}.yml"
30
32
 
31
33
  Dir["#{table_path}/*.yml"].each do |source|
32
- begin
33
- row = Object.const_get(klass_name).new(source, schema_path)
34
- table[row.id] = row
35
- rescue ValidationError => error
36
- @errors << "#{source}: #{error.to_s}"
37
- end
34
+ row = Object.const_get(klass_name).new(source, schema_path)
35
+ table[row.id] = row
36
+ rescue ValidationError => e
37
+ @errors << "[#{source.split('/')[-3..].join('/')}] #{e}"
38
38
  end
39
39
 
40
40
  instance_variable_set("@#{table_name}", table)
41
- self.class.send("attr_reader", table_name.to_sym)
41
+ self.class.send('attr_reader', table_name.to_sym)
42
42
  end
43
43
  end
44
44
 
45
- def build_relationships()
45
+ def build_relationships
46
+ keywords = keywords()
47
+ iterate_over_rows do |row|
48
+ row.build_relationships(self, keywords)
49
+ end
50
+ end
51
+
52
+ def check_relationships
53
+ keywords = keywords()
54
+ iterate_over_rows do |row|
55
+ row.check_relationships(self, keywords)
56
+ end
57
+ end
58
+
59
+ def keywords
46
60
  keywords = []
47
- (self.instance_variables - INTERNAL_VARS).each do |var|
48
- keywords << var.to_s[1..-1]
49
- keywords << var.to_s[1..-1].singularize
61
+ (instance_variables - INTERNAL_VARS).each do |var|
62
+ keywords << var.to_s[1..]
63
+ keywords << var.to_s[1..].singularize
50
64
  end
51
- self.instance_variables.each do |var|
65
+ keywords
66
+ end
67
+
68
+ def iterate_over_rows(&block)
69
+ instance_variables.each do |var|
52
70
  next if INTERNAL_VARS.include? var
71
+
53
72
  table = instance_variable_get var
54
- table.each do |id, row|
55
- begin
56
- row.build_relationships(self, keywords)
57
- rescue ValidationError => error
58
- @errors << "#{row.source}: #{error.to_s}"
73
+ table.each do |_id, row|
74
+ block.call(row).each do |error|
75
+ @errors << "[#{row.source.split('/')[-3..].join('/')}] #{error}"
59
76
  end
60
77
  end
61
78
  end
62
79
  end
63
-
64
80
  end
65
81
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module YDB
2
4
  class ValidationError < StandardError
3
5
  end
@@ -1,66 +1,100 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module YDB
2
4
  class Row
3
- INTERNAL_VARS = [:@id, :@source].freeze
5
+ INTERNAL_VARS = %i[@id @source].freeze
4
6
 
5
7
  attr_reader :id, :source
6
8
 
7
9
  def initialize(source, schema_path)
8
- @id = File.basename(source, ".yml")
10
+ @id = File.basename(source, '.yml')
9
11
  @source = source
10
12
 
11
- validate_filename()
13
+ validate_filename
12
14
  build(source, schema_path)
13
15
  end
14
16
 
15
17
  def build_relationships(db, keywords)
16
- self.instance_variables.each do |var|
17
- next if INTERNAL_VARS.include? var
18
- keyword = var.to_s[1..-1]
19
-
20
- if keywords.include? keyword
21
- if keyword.pluralize == keyword
22
- array = instance_variable_get var
23
- entities = db.public_send(keyword.to_sym)
24
- value = []
25
- array.each do |primary_key|
26
- entity = entities[primary_key]
27
- raise ValidationError.new("invalid primary_key #{primary_key}") if entity.nil?
28
- value << entity
18
+ errors = []
19
+ iterate_over_columns do |key, value|
20
+ if keywords.include?(key)
21
+ if key.pluralize == key
22
+ rows = []
23
+ table = db.public_send(key.to_sym)
24
+ value.each do |primary_key|
25
+ row = table[primary_key]
26
+ errors << "Invalid primary_key: #{primary_key} isn't part of table #{key}" if row.nil?
27
+ rows << row
29
28
  end
30
- instance_variable_set("@#{keyword}", value)
29
+ instance_variable_set("@#{key}", rows)
31
30
  else
32
- primary_key = instance_variable_get var
33
- entity = db.public_send(keyword.pluralize.to_sym)[primary_key]
34
- raise ValidationError.new("invalid primary_key #{primary_key}") if entity.nil?
35
- instance_variable_set("@#{keyword}", entity)
31
+ row = db.public_send(key.pluralize.to_sym)[value]
32
+ errors << "Invalid primary_key: #{value} isn't part of table #{key.pluralize}" if row.nil?
33
+ instance_variable_set("@#{key}", row)
36
34
  end
37
35
  end
38
36
  end
37
+ errors
38
+ end
39
+
40
+ def check_relationships(_db, keywords)
41
+ errors = []
42
+ iterate_over_columns do |key, value|
43
+ if keywords.include?(key)
44
+ next if value.nil?
45
+
46
+ value = [value] if value.is_a?(YDB::Row)
47
+ value.each do |row|
48
+ if row.respond_to?(self.class.to_s.downcase.to_sym)
49
+ unless row.public_send(self.class.to_s.downcase.to_sym) == self
50
+ errors << "Inconsistent relationship: #{row.id} doesn't link back to #{id}"
51
+ end
52
+ elsif row.respond_to?(self.class.to_s.downcase.pluralize.to_sym)
53
+ unless row.public_send(self.class.to_s.downcase.pluralize.to_sym).include?(self)
54
+ errors << "Inconsistent relationship: #{row.id} doesn't link back to #{id}"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ errors
39
61
  end
40
62
 
41
63
  private
42
64
 
43
65
  def build(source, schema_path)
44
- doc = YAML.load(File.read(source))
45
- raise ValidationError.new("invalid YAML") if doc == false
66
+ doc = YAML.safe_load(File.read(source))
67
+ raise ValidationError, 'Invalid YAML document' if doc.nil?
46
68
 
47
- schema = YAML.load(File.read(schema_path))
69
+ schema = YAML.safe_load(File.read(schema_path))
48
70
  begin
49
- JSON::Validator.validate!(schema, doc, :parse_data => false)
50
- rescue JSON::Schema::ValidationError => error
51
- raise ValidationError.new("invalid data (#{error.message})")
71
+ JSON::Validator.validate!(schema, doc, parse_data: false)
72
+ rescue JSON::Schema::ValidationError => e
73
+ raise ValidationError, "Invalid data: #{e.message}"
52
74
  end
53
75
 
54
76
  doc.each do |name, value|
55
77
  instance_variable_set("@#{name}", value)
56
- next if self.respond_to? name.to_sym
57
- self.class.send("attr_reader", name.to_sym)
78
+ next if respond_to?(name.to_sym)
79
+
80
+ self.class.send('attr_reader', name.to_sym)
58
81
  end
59
82
  end
60
83
 
61
- def validate_filename()
62
- raise ValidationError.new("invalid filename") unless self.id =~ /^[\w-]+$/
84
+ def iterate_over_columns(&block)
85
+ instance_variables.each do |var|
86
+ next if INTERNAL_VARS.include?(var)
87
+
88
+ key = var.to_s[1..]
89
+ value = instance_variable_get(var)
90
+ block.call(key, value)
91
+ end
63
92
  end
64
93
 
94
+ def validate_filename
95
+ return if id =~ /\A[a-z\d][a-z\d-]*[a-z\d]\z/i
96
+
97
+ raise ValidationError, "Invalid filename: #{id} doesn't follow dash-case convention"
98
+ end
65
99
  end
66
100
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yaml-file-db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis-Philippe Gauthier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-15 00:00:00.000000000 Z
11
+ date: 2021-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -72,7 +72,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 2.6.0
76
76
  required_rubygems_version: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - ">="