Class: OpenC3::SortedModel
- Defined in:
- lib/openc3/models/sorted_model.rb
Direct Known Subclasses
Constant Summary collapse
- SORTED_TYPE =
To be overridden by base class
'sorted'.freeze
- PRIMARY_KEY =
To be overridden by base class
'__SORTED'.freeze
Instance Attribute Summary collapse
-
#start ⇒ Object
readonly
Returns the value of attribute start.
Attributes inherited from Model
#name, #plugin, #scope, #updated_at
Class Method Summary collapse
-
.all(scope:, limit: 100) ⇒ Array<Hash>
Array up to the limit of the models (as Hash objects) stored under the primary key.
-
.count(scope:) ⇒ Integer
Count of the members stored under the primary key.
-
.destroy(scope:, start:) ⇒ Integer
Remove member from a sorted set.
-
.get(start:, scope:) ⇒ String|nil
String of the saved json or nil if start not found.
-
.get_current_value(scope:) ⇒ String|nil
Json or nil if metadata empty.
-
.notify(scope:, kind:, start:, stop: nil) ⇒ Object
MUST be overridden by any subclasses.
-
.pk(scope) ⇒ Object
MUST be overridden by any subclasses.
-
.range(start:, stop:, scope:, limit: 100) ⇒ Array|nil
Array up to 100 of this model or empty array.
-
.range_destroy(scope:, start:, stop:) ⇒ Integer
Remove members from min to max of the sorted set.
Instance Method Summary collapse
-
#as_json(*a) ⇒ Hash
JSON encoding of this model.
-
#create(update: false) ⇒ Object
Update the Redis hash at primary_key based on the initial passed start The member is set to the JSON generated via calling as_json.
-
#destroy ⇒ Object
destroy the activity from the redis database.
-
#initialize(start:, scope:, type: SORTED_TYPE, **kwargs) ⇒ SortedModel
constructor
A new instance of SortedModel.
-
#notify(kind:, extra: nil) ⇒ Object
-
update the redis stream / timeline topic that something has changed.
-
#update(start:) ⇒ Object
Update the Redis hash at primary_key.
-
#validate_start(update: false) ⇒ Object
start MUST be a positive integer.
Methods inherited from Model
#check_disable_erb, #deploy, #destroyed?, filter, find_all_by_plugin, from_json, get_all_models, get_model, handle_config, names, set, store, store_queued, #undeploy
Constructor Details
#initialize(start:, scope:, type: SORTED_TYPE, **kwargs) ⇒ SortedModel
Returns a new instance of SortedModel.
108 109 110 111 112 113 |
# File 'lib/openc3/models/sorted_model.rb', line 108 def initialize(start:, scope:, type: SORTED_TYPE, **kwargs) # Name becomes the start in the base class super(self.class.pk(scope), name: start.to_s, scope: scope, **kwargs) @type = type # For the as_json, from_json round trip @start = start end |
Instance Attribute Details
#start ⇒ Object (readonly)
Returns the value of attribute start.
103 104 105 |
# File 'lib/openc3/models/sorted_model.rb', line 103 def start @start end |
Class Method Details
.all(scope:, limit: 100) ⇒ Array<Hash>
Returns Array up to the limit of the models (as Hash objects) stored under the primary key.
58 59 60 61 |
# File 'lib/openc3/models/sorted_model.rb', line 58 def self.all(scope:, limit: 100) result = Store.zrevrangebyscore(self.pk(scope), '+inf', '-inf', limit: [0, limit]) return result.map { |item| JSON.parse(item, :allow_nan => true, :create_additions => true) } end |
.count(scope:) ⇒ Integer
Returns count of the members stored under the primary key.
83 84 85 |
# File 'lib/openc3/models/sorted_model.rb', line 83 def self.count(scope:) return Store.zcard(self.pk(scope)) end |
.destroy(scope:, start:) ⇒ Integer
Remove member from a sorted set
89 90 91 92 93 |
# File 'lib/openc3/models/sorted_model.rb', line 89 def self.destroy(scope:, start:) result = Store.zremrangebyscore(self.pk(scope), start, start) self.notify(kind: 'deleted', start: start, scope: scope) return result end |
.get(start:, scope:) ⇒ String|nil
Returns String of the saved json or nil if start not found.
51 52 53 54 55 |
# File 'lib/openc3/models/sorted_model.rb', line 51 def self.get(start:, scope:) result = Store.zrangebyscore(self.pk(scope), start, start) return JSON.parse(result[0], :allow_nan => true, :create_additions => true) unless result.empty? nil end |
.get_current_value(scope:) ⇒ String|nil
Returns json or nil if metadata empty.
64 65 66 67 68 69 |
# File 'lib/openc3/models/sorted_model.rb', line 64 def self.get_current_value(scope:) start = Time.now.to_i array = Store.zrevrangebyscore(self.pk(scope), start, '-inf', limit: [0, 1]) return nil if array.empty? return array[0] end |
.notify(scope:, kind:, start:, stop: nil) ⇒ Object
MUST be overridden by any subclasses
46 47 48 |
# File 'lib/openc3/models/sorted_model.rb', line 46 def self.notify(scope:, kind:, start:, stop: nil) # Do nothing by default end |
.pk(scope) ⇒ Object
MUST be overridden by any subclasses
41 42 43 |
# File 'lib/openc3/models/sorted_model.rb', line 41 def self.pk(scope) return "#{scope}#{PRIMARY_KEY}" end |
.range(start:, stop:, scope:, limit: 100) ⇒ Array|nil
Returns Array up to 100 of this model or empty array.
74 75 76 77 78 79 80 |
# File 'lib/openc3/models/sorted_model.rb', line 74 def self.range(start:, stop:, scope:, limit: 100) if start > stop raise SortedInputError.new "start: #{start} must be before stop: #{stop}" end result = Store.zrangebyscore(self.pk(scope), start, stop, limit: [0, limit]) return result.map { |item| JSON.parse(item, :allow_nan => true, :create_additions => true) } end |
.range_destroy(scope:, start:, stop:) ⇒ Integer
Remove members from min to max of the sorted set.
97 98 99 100 101 |
# File 'lib/openc3/models/sorted_model.rb', line 97 def self.range_destroy(scope:, start:, stop:) result = Store.zremrangebyscore(self.pk(scope), start, stop) self.notify(kind: 'deleted', start: start, stop: stop, scope: scope) return result end |
Instance Method Details
#as_json(*a) ⇒ Hash
Returns JSON encoding of this model.
172 173 174 175 176 177 |
# File 'lib/openc3/models/sorted_model.rb', line 172 def as_json(*a) { **super(*a), 'start' => @start, 'type' => SORTED_TYPE, } end |
#create(update: false) ⇒ Object
Update the Redis hash at primary_key based on the initial passed start The member is set to the JSON generated via calling as_json
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/openc3/models/sorted_model.rb', line 131 def create(update: false) validate_start(update: update) @updated_at = Time.now.to_nsec_from_epoch SortedModel.destroy(scope: @scope, start: update) if update Store.zadd(@primary_key, @start, JSON.generate(as_json(:allow_nan => true))) if update notify(kind: 'updated') else notify(kind: 'created') end end |
#destroy ⇒ Object
destroy the activity from the redis database
151 152 153 154 |
# File 'lib/openc3/models/sorted_model.rb', line 151 def destroy self.class.destroy(scope: @scope, start: @start) notify(kind: 'deleted') end |
#notify(kind:, extra: nil) ⇒ Object
Returns [] update the redis stream / timeline topic that something has changed.
157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/openc3/models/sorted_model.rb', line 157 def notify(kind:, extra: nil) notification = { 'data' => JSON.generate(as_json(:allow_nan => true)), 'kind' => kind, 'type' => 'calendar', } notification['extra'] = extra unless extra.nil? begin CalendarTopic.write_entry(notification, scope: @scope) rescue StandardError => e raise SortedError.new "Failed to write to stream: #{notification}, #{e}" end end |
#update(start:) ⇒ Object
Update the Redis hash at primary_key
144 145 146 147 148 |
# File 'lib/openc3/models/sorted_model.rb', line 144 def update(start:) orig_start = @start @start = start create(update: orig_start) end |
#validate_start(update: false) ⇒ Object
start MUST be a positive integer
116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/openc3/models/sorted_model.rb', line 116 def validate_start(update: false) unless @start.is_a?(Integer) raise SortedInputError.new "start must be integer: #{@start}" end if @start.to_i < 0 raise SortedInputError.new "start must be positive: #{@start}" end if !update and self.class.get(start: @start, scope: @scope) raise SortedOverlapError.new "duplicate, existing data at #{@start}" end @start = @start.to_i end |