teron 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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: []