isomorfeus-data 23.9.0.rc1 → 23.9.0.rc3

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: 2bd98dab77bb6bd9275f22c1e5f3445bea4f9790c7cd8af78689d04079e61231
4
- data.tar.gz: b4acd2f6522de4a85f1c87f7958a6b67d7221b1435bc7ace10981338381b6173
3
+ metadata.gz: dc95d885418b6e12dc9362e26f7e82675688da923045593a3747a1aab0a1e167
4
+ data.tar.gz: 5f6b105e0ed4b58fbfbd771d8406b453dd478a9427c046a5a63bcac4ea5cb27e
5
5
  SHA512:
6
- metadata.gz: 7097cd901c6caeed1809f82975c659e26eb1023b83e194b8a2a79e02ff4b5b198a0e7c8e08f8cb18048e8b79846548b4006a20f55b3d7a41d8d00fb7e3ad9f5b
7
- data.tar.gz: aea81c3a73635815f02dd1d6e9c3a4c819e5a9fc2c079cf10096c2ed127b9e1626655f7be82f6a53614dab52c517e1dbd085a6a854f5f4240f13e4b257c8ef9f
6
+ metadata.gz: c77b8a0f96568725c56f20e300597d201d0d2f5b126425cad25e6405d2c9f9ffc05e2d8e451cc17796ec4c522da17223c76902c5c958a853dc90163b61e85c63
7
+ data.tar.gz: aa546e9a214a5e5470e6421f26f74945dbdc06d674666486763ecedc4ec4bc8d54ef8bb9f2af9200d86a7601fb6c70c7783cc02039a01717ded61788dc302fc5
@@ -15,7 +15,7 @@ module Isomorfeus
15
15
  next_enh.call(action)
16
16
  end
17
17
 
18
- FILE_ACTION_TYPES = %w[FILE_LOAD FILE_SAVE FILE_CREATE FILE_DESTROY]
18
+ FILE_ACTION_TYPES = %w[FILE_LOAD FILE_SAVE FILE_CREATE FILE_SEARCH FILE_DESTROY]
19
19
  FILE_MERGE_TYPES = %w[FILE_SAVE FILE_CREATE]
20
20
 
21
21
  CLIENT_FILE_ENHANCER = proc do |action, next_enh|
@@ -180,8 +180,7 @@ module Isomorfeus
180
180
  if data
181
181
  content_type = Marcel::MimeType.for(data)
182
182
  data_uri = item_class.format_data_uri(content_type, data)
183
- revision = meta[:revision]
184
- item_hash = { data_uri: data_uri, revision: revision }
183
+ item_hash = { data_uri: data_uri }.merge(meta)
185
184
  end
186
185
  action = { type: 'DATA_MERGE', data: { item_class_name => { item_key => item_hash }}}
187
186
  elsif action_type == 'FILE_SAVE'
@@ -191,6 +190,7 @@ module Isomorfeus
191
190
  data_uri = action[:data_uri]
192
191
  authorization_error!(action) unless Isomorfeus.current_user.authorized?(item_class, :save, { key: item_key, data_uri: data_uri })
193
192
  revision = action[:revision]
193
+ name = action[:name]
194
194
  sid = SID.new(item_class_name, item_key)
195
195
  meta = item_class.file_accelerator.meta(sid: sid)
196
196
  stored_revision = meta[:revision]
@@ -201,7 +201,7 @@ module Isomorfeus
201
201
  res = item_class.before_save_block.call(key: item_key, data_uri: data_uri)
202
202
  data_uri = res[:data_uri] if res.is_a?(Hash) && res.key?(:data_uri)
203
203
  end
204
- if item_class.file_accelerator.save(sid: sid, data: URI::Data.new(data_uri).data, meta: { revision: revision })
204
+ if item_class.file_accelerator.save(sid: sid, data: URI::Data.new(data_uri).data, meta: { revision: revision, name: name })
205
205
  item_class.after_save_block.call(key: item_key, data_uri: data_uri) if item_class.after_save_block
206
206
  else
207
207
  instance_uuid = nil
@@ -210,13 +210,14 @@ module Isomorfeus
210
210
  revision = 0
211
211
  instance_uuid = nil
212
212
  end
213
- action = { type: 'DATA_MERGE', data: { item_class_name => { item_key => { data_uri: data_uri, revision: revision, instance_uuid: instance_uuid }}}}
213
+ action = { type: 'DATA_MERGE', data: { item_class_name => { item_key => { data_uri: data_uri, revision: revision, name: name, instance_uuid: instance_uuid }}}}
214
214
  elsif action_type == 'FILE_CREATE'
215
215
  item_class_name = action[:class_name]
216
216
  item_key = action[:key]
217
217
  item_class = get_verified_class(item_class_name)
218
218
  data_uri = action[:data_uri]
219
219
  authorization_error!(action) unless Isomorfeus.current_user.authorized?(item_class, :create, { key: item_key, data_uri: data_uri })
220
+ name = action[:name]
220
221
  sid = SID.new(item_class_name, item_key)
221
222
  meta = item_class.file_accelerator.meta(sid: sid)
222
223
  stored_revision = meta ? meta[:revision] : nil
@@ -227,7 +228,7 @@ module Isomorfeus
227
228
  res = item_class.before_create_block.call(key: item_key, data_uri: data_uri)
228
229
  data_uri = res[:data_uri] if res.is_a?(Hash) && res.key?(:data_uri)
229
230
  end
230
- if item_class.file_accelerator.create(sid: sid, data: URI::Data.new(data_uri).data, meta: { revision: revision })
231
+ if item_class.file_accelerator.create(sid: sid, data: URI::Data.new(data_uri).data, meta: { revision: revision, name: name })
231
232
  item_class.after_create_block.call(key: item_key, data_uri: data_uri) if item_class.after_create_block
232
233
  else
233
234
  stored_revision = 0
@@ -237,7 +238,36 @@ module Isomorfeus
237
238
  revision = stored_revision
238
239
  instance_uuid = nil
239
240
  end
240
- action = { type: 'DATA_ADD', data: { item_class_name => { item_key => { data_uri: data_uri, revision: revision, instance_uuid: instance_uuid }}}}
241
+ action = { type: 'DATA_ADD', data: { item_class_name => { item_key => { data_uri: data_uri, revision: revision, name: name, instance_uuid: instance_uuid }}}}
242
+ elsif action_type == 'FILE_SEARCH'
243
+ item_class_name = action[:class_name]
244
+ item_class = get_verified_class(item_class_name)
245
+ query = action[:query].to_sym
246
+ params = action[:params]
247
+ raise "Invalid params #{params}!" unless params.nil? || params.is_a?(Hash)
248
+ params.transform_keys!(&:to_sym) if params
249
+ authorization_error!(action) unless Isomorfeus.current_user.authorized?(item_class, :search, { query: query, params: params })
250
+ result = []
251
+ query_string = item_class.queries.dig(query, :query_string)
252
+ raise "Invalid query '#{query}'!" unless query_string
253
+ options = item_class.queries[query][:options] || {}
254
+ fa = item_class.file_accelerator
255
+ full_query = if params.is_a?(Hash)
256
+ if options[:escape_params]
257
+ escaped_params = params.to_h do |k,v|
258
+ [k, oa.escape(v)]
259
+ end
260
+ query_string % escaped_params
261
+ else
262
+ query_string % params
263
+ end
264
+ else
265
+ query_string
266
+ end
267
+ fa.search_each(full_query, options) do |key|
268
+ result << SID.new(item_class_name, key).to_s
269
+ end
270
+ action = { type: 'DATA_MERGE', data: { queries: { item_class_name => { query => { Oj.dump(params, mode: :strict) => { result_time: Time.now.httpdate, result: result }}}}}}
241
271
  elsif action_type == 'FILE_DESTROY'
242
272
  item_class_name = action[:class_name]
243
273
  item_key = action[:key]
@@ -273,7 +303,7 @@ module Isomorfeus
273
303
  end
274
304
 
275
305
  def get_verified_class(item_class_name)
276
- raise "Invalid data class!" unless Isomorfeus.valid_data_class_name?(item_class_name)
306
+ raise "Invalid data class #{item_class_name}!" unless Isomorfeus.valid_data_class_name?(item_class_name)
277
307
  item_class = Isomorfeus.cached_data_class(item_class_name)
278
308
  end
279
309
 
@@ -36,6 +36,20 @@ module Isomorfeus
36
36
  File.exist?(path)
37
37
  end
38
38
 
39
+ def search_each(_query, _options, &block)
40
+ if block_given?
41
+ each(&block)
42
+ else
43
+ files = []
44
+ each { |file| files << file }
45
+ files
46
+ end
47
+ end
48
+
49
+ def each(&block)
50
+ internal_each(@store_path, &block)
51
+ end
52
+
39
53
  def create(sid:, data:, meta:)
40
54
  path, meta_path = check_and_prepare_paths(key: sid.key)
41
55
  File.binwrite(path, data)
@@ -76,18 +90,23 @@ module Isomorfeus
76
90
 
77
91
  private
78
92
 
93
+ def internal_each(path, &block)
94
+ Dir.each_child(path) do |entry_name|
95
+ unless entry_name.end_with?('__meta__')
96
+ new_path = File.join(path, entry_name)
97
+ key = new_path[(@store_path.size+1)..-1]
98
+ if File.file?(new_path)
99
+ block.call(key)
100
+ elsif Dir.exist?(File.join(new_path))
101
+ internal_each(new_path, &block)
102
+ end
103
+ end
104
+ end
105
+ end
106
+
79
107
  def check_and_prepare_paths(key:)
80
- Isomorfeus.raise_error(message: 'Invalid key (contains ".." or "\\")') if key.include?('..') || key.include?('\\')
81
- elements = key.split('/')
82
- Isomorfeus.raise_error(message: 'Invalid key (contains more than 2 slashes "/")') if elements.size > 3
83
- file = elements.pop
84
- path = if elements.size > 0
85
- dir_path = ::File.expand_path(::File.join(@store_path, *elements))
86
- FileUtils.mkdir_p(dir_path) unless Dir.exist?(dir_path)
87
- File.join(dir_path, file)
88
- else
89
- File.join(@store_path, file)
90
- end
108
+ Isomorfeus.raise_error(message: 'Invalid key, must contain word characters or "-" only!') unless key.match?(SID::SID_S_KEY_RE)
109
+ path = File.join(@store_path, key)
91
110
  [path, "#{path}__meta__"]
92
111
  end
93
112
  end
@@ -1,4 +1,5 @@
1
1
  class SID
2
+ SID_S_KEY_RE = /\A[\w\/\-]+\z/
2
3
  SID_S_RE = /\ASID__([a-zA-Z0-9:]+)__([\w\/\-]+)__\z/ # must use this way for compatiblity
3
4
 
4
5
  class << self
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Data
3
- VERSION = '23.9.0.rc1'
3
+ VERSION = '23.9.0.rc3'
4
4
  end
5
5
  end
@@ -18,6 +18,14 @@ class LucidDataGeneric
18
18
  def current_user
19
19
  Isomorfeus.current_user
20
20
  end
21
+
22
+ def query(name, query_string, options = nil)
23
+ queries[name] = { query_string: query_string, options: options }
24
+ end
25
+
26
+ def queries
27
+ @queries ||= {}
28
+ end
21
29
  end
22
30
 
23
31
  if RUBY_ENGINE == 'opal'
data/lib/lucid_file.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  class LucidFile < LucidDataGeneric
2
2
  include LucidI18nMixin
3
3
 
4
- VALID_METHODS = %i[key data data_uri content_type]
4
+ VALID_METHODS = %i[key data data_uri name content_type]
5
5
 
6
6
  class << self
7
7
  def api_path(key:)
@@ -12,6 +12,15 @@ class LucidFile < LucidDataGeneric
12
12
  "data:#{c};base64,#{Base64.strict_encode64(d)}"
13
13
  end
14
14
 
15
+ def search(query = :all, params = nil)
16
+ proxy_instance = LucidObject::SearchResultProxy.new(self.name, query, params)
17
+ unless proxy_instance.loaded?
18
+ Isomorfeus.something_loading!
19
+ Isomorfeus.store.deferred_dispatch(type: 'FILE_SEARCH', class_name: self.name, query: query, params: params)
20
+ end
21
+ proxy_instance
22
+ end
23
+
15
24
  def destroy(key:)
16
25
  Isomorfeus.store.deferred_dispatch(type: 'FILE_DESTROY', class_name: self.name, key: key)
17
26
  true
@@ -25,11 +34,12 @@ class LucidFile < LucidDataGeneric
25
34
  end
26
35
  end
27
36
 
28
- def initialize(key: nil, content_type: nil, data: nil, data_uri: nil, _loading: false)
37
+ def initialize(key: nil, content_type: nil, data: nil, data_uri: nil, name: nil, _loading: false)
29
38
  super(key: key)
30
39
  _update_paths
31
40
  loaded = loaded?
32
41
  @changed_uri_string = nil
42
+ @changed_name = name if name
33
43
  if data_uri
34
44
  @changed_uri_string = data_uri
35
45
  elsif data || content_type
@@ -47,7 +57,7 @@ class LucidFile < LucidDataGeneric
47
57
  d = data_uri
48
58
  unchange!
49
59
  Isomorfeus.something_loading!
50
- Isomorfeus.store.deferred_dispatch(type: "FILE_CREATE", class_name: @class_name, key: @key, data_uri: d, instance_uuid: instance_uuid, revision: 0)
60
+ Isomorfeus.store.deferred_dispatch(type: "FILE_CREATE", class_name: @class_name, key: @key, data_uri: d, name: name, instance_uuid: instance_uuid, revision: 0)
51
61
  self
52
62
  end
53
63
 
@@ -57,16 +67,16 @@ class LucidFile < LucidDataGeneric
57
67
  d = data_uri
58
68
  unchange!
59
69
  Isomorfeus.something_loading!
60
- Isomorfeus.store.deferred_dispatch(type: "FILE_SAVE", class_name: @class_name, key: @key, data_uri: d, instance_uuid: instance_uuid, revision: @last_revision)
70
+ Isomorfeus.store.deferred_dispatch(type: "FILE_SAVE", class_name: @class_name, key: @key, data_uri: d, name: name, instance_uuid: instance_uuid, revision: @last_revision)
61
71
  self
62
72
  end
63
73
 
64
- def [](name)
65
- self.send(name) if VALID_METHODS.include?(name)
74
+ def [](n)
75
+ self.send(n) if VALID_METHODS.include?(n)
66
76
  end
67
77
 
68
- def []=(name, value)
69
- self.send("#{name}=".to_sym, value) if VALID_METHODS.include?(name)
78
+ def []=(n, value)
79
+ self.send("#{n}=".to_sym, value) if VALID_METHODS.include?(n)
70
80
  end
71
81
 
72
82
  def unchange!
@@ -75,7 +85,7 @@ class LucidFile < LucidDataGeneric
75
85
  end
76
86
 
77
87
  def _update_paths
78
- @store_path = [:data_state, @class_name, @key, :data_uri]
88
+ @store_path = [:data_state, @class_name, @key]
79
89
  end
80
90
 
81
91
  def content_type
@@ -84,13 +94,13 @@ class LucidFile < LucidDataGeneric
84
94
 
85
95
  def content_type=(c)
86
96
  changed!
87
- uri_string = @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)
97
+ uri_string = @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)&.fetch(:data_uri, nil)
88
98
  @changed_uri_string = self.class.format_data_uri(c, URI::Data.new(uri_string).data)
89
99
  c
90
100
  end
91
101
 
92
102
  def data_uri
93
- @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)
103
+ @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)&.fetch(:data_uri, nil)
94
104
  end
95
105
 
96
106
  def data_uri=(d)
@@ -118,6 +128,15 @@ class LucidFile < LucidDataGeneric
118
128
  @changed_uri_string = self.class.format_data_uri(ct, d)
119
129
  end
120
130
 
131
+ def name
132
+ @changed_name ? @changed_name : Isomorfeus.store.dig(*@store_path)&.fetch(:name, nil)
133
+ end
134
+
135
+ def name=(n)
136
+ changed!
137
+ @changed_name = name
138
+ end
139
+
121
140
  if RUBY_ENGINE != 'opal'
122
141
  class << self
123
142
  def inherited(base)
@@ -128,6 +147,21 @@ class LucidFile < LucidDataGeneric
128
147
  @file_accelerator ||= Isomorfeus::Data::FileAccelerator.new(self)
129
148
  end
130
149
 
150
+ def each(&block)
151
+ if block_given?
152
+ file_accelerator.each do |key|
153
+ block.call self.load(key: key)
154
+ end
155
+ else
156
+ Enumerator.new do |yielder|
157
+ file_accelerator.each do |key|
158
+ yielder << self.load(key: key)
159
+ end
160
+ end
161
+ end
162
+ end
163
+ alias to_enum each
164
+
131
165
  def exist?(key:)
132
166
  raise "Not authorized!" unless current_user.authorized?(self, :load, key: key)
133
167
  file_accelerator.exist?(sid: SID.new(self.name, key))
data/lib/lucid_object.rb CHANGED
@@ -95,6 +95,11 @@ class LucidObject < LucidDataGeneric
95
95
  proxy_instance
96
96
  end
97
97
 
98
+ def destroy(key:)
99
+ Isomorfeus.store.deferred_dispatch(type: 'DATA_DESTROY', class_name: self.name, key: key)
100
+ true
101
+ end
102
+
98
103
  def load!(key:, instance: nil)
99
104
  instance = self.new(key: key, _loading: true) unless instance
100
105
  Isomorfeus.something_loading!
@@ -102,11 +107,6 @@ class LucidObject < LucidDataGeneric
102
107
  instance
103
108
  end
104
109
 
105
- def destroy(key:)
106
- Isomorfeus.store.deferred_dispatch(type: 'DATA_DESTROY', class_name: self.name, key: key)
107
- true
108
- end
109
-
110
110
  def escape_string(s)
111
111
  s.gsub(/([\\\&\:\(\)\[\]\{\}\!\"\~\^\|\<\>\=\*\?\+\-\s])/, '\\\\\1')
112
112
  end
@@ -117,14 +117,6 @@ class LucidObject < LucidDataGeneric
117
117
  data_class.load(key: sid.key)
118
118
  end
119
119
 
120
- def query(name, query_string, options = nil)
121
- queries[name] = { query_string: query_string, options: options }
122
- end
123
-
124
- def queries
125
- @queries ||= {}
126
- end
127
-
128
120
  def field_types
129
121
  # determines how the item is stored in the index
130
122
  @field_types ||= {}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isomorfeus-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 23.9.0.rc1
4
+ version: 23.9.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-09 00:00:00.000000000 Z
11
+ date: 2023-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -106,70 +106,70 @@ dependencies:
106
106
  requirements:
107
107
  - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: 23.9.0.rc1
109
+ version: 23.9.0.rc3
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - '='
115
115
  - !ruby/object:Gem::Version
116
- version: 23.9.0.rc1
116
+ version: 23.9.0.rc3
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: isomorfeus-policy
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - '='
122
122
  - !ruby/object:Gem::Version
123
- version: 23.9.0.rc1
123
+ version: 23.9.0.rc3
124
124
  type: :runtime
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - '='
129
129
  - !ruby/object:Gem::Version
130
- version: 23.9.0.rc1
130
+ version: 23.9.0.rc3
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: isomorfeus-preact
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - '='
136
136
  - !ruby/object:Gem::Version
137
- version: 23.9.0.rc1
137
+ version: 23.9.0.rc3
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - '='
143
143
  - !ruby/object:Gem::Version
144
- version: 23.9.0.rc1
144
+ version: 23.9.0.rc3
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: isomorfeus-redux
147
147
  requirement: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - '='
150
150
  - !ruby/object:Gem::Version
151
- version: 23.9.0.rc1
151
+ version: 23.9.0.rc3
152
152
  type: :runtime
153
153
  prerelease: false
154
154
  version_requirements: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - '='
157
157
  - !ruby/object:Gem::Version
158
- version: 23.9.0.rc1
158
+ version: 23.9.0.rc3
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: isomorfeus-transport
161
161
  requirement: !ruby/object:Gem::Requirement
162
162
  requirements:
163
163
  - - '='
164
164
  - !ruby/object:Gem::Version
165
- version: 23.9.0.rc1
165
+ version: 23.9.0.rc3
166
166
  type: :runtime
167
167
  prerelease: false
168
168
  version_requirements: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - '='
171
171
  - !ruby/object:Gem::Version
172
- version: 23.9.0.rc1
172
+ version: 23.9.0.rc3
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: rake
175
175
  requirement: !ruby/object:Gem::Requirement