teron 0.0.8

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cc7987d1adca37e5e5706ff9fdbeca077ef28a130d54ca046368dd2ed8139e26
4
+ data.tar.gz: bbdf6db66b23c1a1173b15d6e6811f279856883cc399e11505577032988a009e
5
+ SHA512:
6
+ metadata.gz: 38d06c4f49b93497de80cb25800e154be38fa88becab7d6143518061c19b4f073a8906b6a7bf7408b5f7b6d956c809a8c66588ed935635f269893f25d3e252be
7
+ data.tar.gz: e03bf8b54a4774ccac65b23a7e00d9a5b2aaceb425223c1b5ef6acb05faa02a6e40ccbf7a7416bbf8a5835243a97aedde0abb5d4e4a43abdb359ebe7706ef998
@@ -0,0 +1,49 @@
1
+ # Associations for Has Many
2
+ module TeronAssociation
3
+ # The Object to be included
4
+ def belongs_to(class_name, param_options = {})
5
+ # Should Inverse Object Be Updated
6
+ inverse = param_options[:inverse] || true
7
+
8
+ field "#{class_name}_id".to_sym
9
+
10
+ # ==================================
11
+ # Accessor
12
+ # ==================================
13
+ define_method(class_name) do
14
+ # Get Constant
15
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
16
+
17
+ # Get Entry Id
18
+ klass_obj_id = send("#{class_name}_id".to_sym)
19
+ klass.find klass_obj_id
20
+ end
21
+
22
+ # ==================================
23
+ # Add
24
+ # ==================================
25
+ define_method("#{class_name}=") do |klass_obj|
26
+ # Get Constant
27
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
28
+
29
+ raise "Invalid #{klass}; Received #{klass_obj.class})" unless klass_obj.instance_of?(klass)
30
+
31
+ send("#{class_name}_id=", klass_obj.id)
32
+ save!
33
+ end
34
+
35
+ # ==================================
36
+ # Destroy
37
+ # ==================================
38
+ define_method('destroy!') do
39
+ # Get Association Name
40
+ klass_name = self.class.name.downcase.singularize
41
+ # self.class._obj_clear(id)
42
+
43
+ # Remove from included object`
44
+ send(class_name)&.send("#{klass_name}_remove", self) if inverse
45
+
46
+ super()
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,90 @@
1
+ # Associations for Has Many
2
+ module TeronAssociation
3
+ # The Object to do the including
4
+ def has_many(class_name, param_options = {})
5
+ # Should Inverse Object Be Updated
6
+ inverse = param_options[:inverse] || true
7
+
8
+ field "#{class_name}_ids".to_sym, default: -> { [] }
9
+
10
+ # ==================================
11
+ # Accessor
12
+ # ==================================
13
+ define_method(class_name) do
14
+ # Get Constant
15
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
16
+
17
+ # Get Entry Ids
18
+ klass_list = send("#{class_name}_ids".to_sym)
19
+ return klass_list if klass_list.empty?
20
+
21
+ klass_list.map { |x| klass.find x }.compact
22
+ end
23
+
24
+ # ==================================
25
+ # Add
26
+ # ==================================
27
+ define_method("#{class_name}_add") do |klass_obj|
28
+ # Get Constant
29
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
30
+
31
+ raise "Invalid #{klass}; Received #{klass_obj.class})" unless klass_obj.instance_of?(klass)
32
+
33
+ klass_list = send("#{class_name}_ids".to_sym)
34
+ klass_list.push klass_obj.id unless klass_list.include? klass_obj.id
35
+
36
+ # Klass Many Name
37
+ klass_many_name = self.class.to_s.underscore
38
+
39
+ # Update Obj Association
40
+ if inverse
41
+ klass_obj.send("#{klass_many_name}=", self)
42
+ klass_obj.save!
43
+ end
44
+
45
+ save!
46
+ end
47
+
48
+ # ==================================
49
+ # Remove (Meta)
50
+ # Don't think this whould be called directly
51
+ # ==================================
52
+ define_method("#{class_name}_remove") do |klass_obj|
53
+ # Get Constant
54
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
55
+
56
+ raise "Invalid #{klass}; Received #{klass_obj.class})" unless klass_obj.instance_of?(klass)
57
+
58
+ klass_list = send("#{class_name}_ids".to_sym)
59
+ klass_list.delete klass_obj.id if klass_list.include? klass_obj.id
60
+
61
+ # Remove Association on removed object
62
+ if inverse
63
+ klass_many_name = self.class.to_s.underscore
64
+ klass_obj.send("#{klass_many_name}_id=", nil)
65
+ end
66
+
67
+ save!
68
+ end
69
+
70
+ # ==================================
71
+ # Create
72
+ # ==================================
73
+ define_method("#{class_name}_create") do |opts = {}|
74
+ # Get Constant
75
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
76
+ klass_obj = klass.new(opts)
77
+
78
+ send("#{class_name}_add", klass_obj)
79
+
80
+ klass_obj
81
+ end
82
+
83
+ # ==================================
84
+ # Destroy All
85
+ # ==================================
86
+ define_method("#{class_name}_destroy_all") do
87
+ send(class_name).each(&:destroy!) if inverse
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,101 @@
1
+ # Associations for Has Many
2
+ module TeronAssociation
3
+ # The Object to do the including
4
+ def has_one(class_name, param_options = {})
5
+ # @relationships ||= []
6
+
7
+ # Should Inverse Object Be Updated
8
+ inverse = if param_options.key?(:inverse)
9
+ param_options[:inverse]
10
+ else
11
+ true
12
+ end
13
+
14
+ field "#{class_name}_id".to_sym
15
+
16
+ # ==================================
17
+ # Accessor
18
+ # ==================================
19
+ define_method(class_name) do
20
+ # Get Constant
21
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
22
+
23
+ # Get Entry Id
24
+ klass_one = send("#{class_name}_id".to_sym)
25
+ return klass_one if klass_one.nil?
26
+
27
+ klass.find klass_one
28
+ end
29
+
30
+ # ==================================
31
+ # Add
32
+ # ==================================
33
+ define_method("#{class_name}=") do |klass_obj|
34
+ # Get Constant
35
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
36
+
37
+ raise "Invalid #{klass}; Received #{klass_obj.class})" unless klass_obj.instance_of?(klass)
38
+
39
+ send("#{class_name}_id=", klass_obj.id)
40
+ save!
41
+ end
42
+
43
+ # ==================================
44
+ # Remove (Meta)
45
+ # Don't think this whould be called directly
46
+ # ==================================
47
+ define_method("#{class_name}_remove") do |klass_obj|
48
+ # Get Constant
49
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
50
+
51
+ # Validate Correct Klass Object
52
+ raise "Invalid #{klass}; Received #{klass_obj.class})" unless klass_obj.instance_of?(klass)
53
+
54
+ klass_name = self.class.name.downcase.singularize
55
+
56
+ # Get Entry Id
57
+ # klass_one = send("#{class_name}_id".to_sym)
58
+ # return klass_one if klass_one.nil?
59
+
60
+ klass_obj.send("#{klass_name}_id=", nil) if inverse
61
+ send("#{class_name}_id=", nil)
62
+
63
+ save!
64
+ end
65
+
66
+ # ==================================
67
+ # Create
68
+ # ==================================
69
+ define_method("#{class_name}_create") do |opts = {}|
70
+ # Get Constant
71
+ klass = class_name.to_s.capitalize.singularize.classify.constantize
72
+ klass_obj = klass.new(opts)
73
+
74
+ send("#{class_name}=", klass_obj)
75
+
76
+ # Klass Has One Name
77
+ klass_one_name = self.class.to_s.underscore
78
+
79
+ # Update Obj Association
80
+ if inverse
81
+ klass_obj.send("#{klass_one_name}=", self)
82
+ klass_obj.save!
83
+ end
84
+
85
+ save!
86
+
87
+ klass_obj
88
+ end
89
+
90
+ # # ==================================
91
+ # # Destroy All
92
+ # # ==================================
93
+ # define_method("#{class_name}_destroy_all") do
94
+ # send(class_name).each(&:destroy!) if inverse
95
+ # end
96
+
97
+ # class_variable_set(:@@relationships, @relationships)
98
+
99
+ # true
100
+ end
101
+ end
data/lib/field.rb ADDED
@@ -0,0 +1,27 @@
1
+ # Field Actions
2
+ module TeronField
3
+ def field(param_name, param_options = {})
4
+ unless class_variables.include? :@@data
5
+ class_variable_set(:@@data, {})
6
+ class_variable_set(:@@mutex, Mutex.new)
7
+ class_variable_set(:@@object_list, {})
8
+ end
9
+
10
+ @params ||= [{
11
+ name: :id,
12
+ options: { default: -> { SecureRandom.uuid }, dump: true }
13
+ }]
14
+
15
+ param_options[:dump] = true unless param_options.key? :dump
16
+
17
+ @params.push(
18
+ name: param_name,
19
+ options: param_options
20
+ )
21
+ attr_accessor param_name.to_sym
22
+
23
+ class_variable_set(:@@params, @params)
24
+
25
+ nil
26
+ end
27
+ end
data/lib/record.rb ADDED
@@ -0,0 +1,52 @@
1
+ # Saving/Records Keeper
2
+ module TeronRecords
3
+ def save!
4
+ self.class._mutex.synchronize do
5
+ # Handle Dump vs No Dump Variables
6
+ payload = self.class.class_variable_get(:@@params).each_with_object({}) do |data, obj|
7
+ value = attributes[data[:name]]
8
+ obj[data[:name]] = data.dig(:options, :dump) ? Marshal.load(Marshal.dump(value)) : value
9
+
10
+ obj
11
+ end
12
+
13
+ self.class._data[id] = payload
14
+ end
15
+
16
+ self.class._obj_clear id
17
+
18
+ true
19
+ end
20
+
21
+ alias save save!
22
+
23
+ def destroy!
24
+ self.class._mutex.synchronize do
25
+ self.class._data.delete id
26
+ end
27
+
28
+ self.class._obj_clear id
29
+
30
+ true
31
+ end
32
+
33
+ def attributes
34
+ instance_variables.each_with_object({}) do |name, obj|
35
+ key = name.to_s.delete('@').to_sym
36
+ obj[key] = instance_variable_get(name)
37
+
38
+ obj
39
+ end
40
+ end
41
+
42
+ def reload
43
+ klass_obj = self.class.find id
44
+
45
+ instance_variables.each do |name|
46
+ key = name.to_s.delete('@').to_sym
47
+ instance_variable_set(name, klass_obj.send(key))
48
+ end
49
+
50
+ true
51
+ end
52
+ end
data/lib/teron.rb ADDED
@@ -0,0 +1,141 @@
1
+ # ==============================================================
2
+ # ___ ____ ____ ____ __ _
3
+ # | |=== |--< [__] | \|
4
+ #
5
+ # ======== [ The Devious Teron ] ========
6
+ # ==============================================================
7
+
8
+ # Attributes
9
+ require 'securerandom'
10
+ require_relative 'field'
11
+
12
+ # In Memory Collection
13
+ require_relative 'record'
14
+
15
+ # Associations
16
+ require 'active_support/core_ext/string/inflections' ## Constantize
17
+
18
+ require_relative 'associations/has_many'
19
+ require_relative 'associations/has_one'
20
+ require_relative 'associations/belongs_to'
21
+
22
+ # Initializtion Helper
23
+ class Teron
24
+ attr_accessor :id
25
+
26
+ include TeronRecords
27
+ extend TeronField
28
+ extend TeronAssociation
29
+
30
+ def inspect
31
+ "#<#{self.class.name} #{inspect_vars.join(', ')}>"
32
+ end
33
+
34
+ def inspect_vars
35
+ instance_variables.map do |name|
36
+ "#{name}: #{instance_variable_get(name)}"
37
+ end
38
+ end
39
+
40
+ def initialize(params = {})
41
+ self.class.class_variable_get(:@@params).each do |param|
42
+ value = if params.key? param[:name]
43
+ params[param[:name]]
44
+ else
45
+ default = param.dig(:options, :default)
46
+ if default.instance_of?(Proc)
47
+ default.call
48
+ else
49
+ # Ensure Deep Clone
50
+ param.dig(:options, :dump) ? Marshal.load(Marshal.dump(default)) : default
51
+
52
+ end
53
+ end
54
+
55
+ instance_variable_set("@#{param[:name]}", value) if value
56
+ end
57
+ end
58
+
59
+ class << self
60
+ def _data
61
+ class_variable_get(:@@data)
62
+ end
63
+
64
+ # Store of In Memory already loaded objects
65
+ def _object_list
66
+ class_variable_get(:@@object_list)
67
+ end
68
+
69
+ def _mutex
70
+ class_variable_get(:@@mutex)
71
+ end
72
+
73
+ def first
74
+ return nil if count.zero?
75
+
76
+ _obj_create _data.values[0]
77
+ end
78
+
79
+ def last
80
+ return nil if count.zero?
81
+
82
+ _obj_create _data.values[-1]
83
+ end
84
+
85
+ def count
86
+ _data.size
87
+ end
88
+
89
+ def _obj_create(obj_data)
90
+ _mutex.synchronize do
91
+ _object_list[obj_data[:id]] = new obj_data unless _object_list.key? obj_data[:id]
92
+ end
93
+
94
+ _object_list[obj_data[:id]]
95
+ end
96
+
97
+ def _obj_clear(obj_id)
98
+ _mutex.synchronize do
99
+ _object_list.delete obj_id if _object_list.key? obj_id
100
+ end
101
+ end
102
+
103
+ def find_by(args)
104
+ return nil if args.nil?
105
+ return nil if count.zero?
106
+
107
+ key, value = args.first
108
+ obj = _data.values.find { |x| x[key] == value }
109
+
110
+ return nil unless obj
111
+
112
+ _obj_create obj
113
+ end
114
+
115
+ def where(args)
116
+ return [] if args.nil?
117
+ return [] if count.zero?
118
+
119
+ objs = _data.values.select do |value|
120
+ args.all? { |k, v| value[k] == v }
121
+ end
122
+
123
+ objs.map { |x| _obj_create x }
124
+ end
125
+
126
+ def all
127
+ return [] if count.zero?
128
+
129
+ _data.values.map { |x| _obj_create x }
130
+ end
131
+
132
+ def find(key)
133
+ return nil if key.nil?
134
+ return nil if count.zero?
135
+
136
+ return nil unless _data.key? key
137
+
138
+ _obj_create _data[key]
139
+ end
140
+ end
141
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: teron
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ platform: ruby
6
+ authors:
7
+ - Davin Walker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.80'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.80'
55
+ description: Gimme an easy way to initialize database less classes
56
+ email:
57
+ - dishcandanty@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/associations/belongs_to.rb
63
+ - lib/associations/has_many.rb
64
+ - lib/associations/has_one.rb
65
+ - lib/field.rb
66
+ - lib/record.rb
67
+ - lib/teron.rb
68
+ homepage: https://gitlab.com/davinwalker/teron
69
+ licenses:
70
+ - MIT
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.0.3
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Experimental Simple Class Initialization
91
+ test_files: []