yaml-file-db 0.1.1 → 0.1.6

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: 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
  - - ">="