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 +7 -0
- data/lib/associations/belongs_to.rb +49 -0
- data/lib/associations/has_many.rb +90 -0
- data/lib/associations/has_one.rb +101 -0
- data/lib/field.rb +27 -0
- data/lib/record.rb +52 -0
- data/lib/teron.rb +141 -0
- metadata +91 -0
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: []
|