isomorfeus-data 2.5.4 → 22.9.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/isomorfeus/data/config.rb +8 -25
- data/lib/isomorfeus/data/enhancer.rb +291 -0
- data/lib/isomorfeus/data/file_accelerator.rb +95 -0
- data/lib/isomorfeus/data/object_accelerator.rb +81 -73
- data/lib/isomorfeus/data/rack_middleware.rb +73 -0
- data/lib/isomorfeus/data/reducer.rb +47 -17
- data/lib/isomorfeus/data/sid.rb +34 -0
- data/lib/isomorfeus/data/version.rb +1 -1
- data/lib/isomorfeus-data.rb +27 -32
- data/lib/lucid_data_generic.rb +163 -0
- data/lib/lucid_file.rb +137 -0
- data/lib/lucid_object.rb +431 -0
- metadata +51 -47
- data/lib/data_uri/open_uri.rb +0 -22
- data/lib/data_uri/uri.rb +0 -61
- data/lib/data_uri.rb +0 -4
- data/lib/isomorfeus/data/field_support.rb +0 -247
- data/lib/isomorfeus/data/generic_class_api.rb +0 -127
- data/lib/isomorfeus/data/generic_instance_api.rb +0 -171
- data/lib/isomorfeus/data/handler/generic.rb +0 -133
- data/lib/isomorfeus_data/lucid_file/base.rb +0 -10
- data/lib/isomorfeus_data/lucid_file/mixin.rb +0 -281
- data/lib/isomorfeus_data/lucid_object/base.rb +0 -10
- data/lib/isomorfeus_data/lucid_object/mixin.rb +0 -236
- data/lib/isomorfeus_data/lucid_query/base.rb +0 -10
- data/lib/isomorfeus_data/lucid_query/mixin.rb +0 -112
- data/lib/isomorfeus_data/lucid_query_result.rb +0 -113
- data/opal/iso_uri.rb +0 -29
- data/opal/uri/common.rb +0 -18
- data/opal/uri/generic.rb +0 -47
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Isomorfeus
|
4
|
+
module Data
|
5
|
+
class RackMiddleware
|
6
|
+
NOT_FOUND = [404, {}, ['Not found!']].freeze
|
7
|
+
NOT_AUTHORIZED = [401, {}, ['Not authorized!']].freeze
|
8
|
+
|
9
|
+
FILES_REGEXP = /\A\/files\/([A-Za-z\:]+)\/([A-Za-z0-9\-\/_]+)\z/
|
10
|
+
|
11
|
+
def initialize(app)
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
unless env['isomorfeus_store_initialized']
|
17
|
+
Isomorfeus.init_store
|
18
|
+
Isomorfeus.store.clear!
|
19
|
+
env['isomorfeus_store_initialized'] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
path_info = env['PATH_INFO']
|
23
|
+
|
24
|
+
if path_info.start_with?(Isomorfeus.api_files_path)
|
25
|
+
begin
|
26
|
+
m = FILES_REGEXP.match(path_info)
|
27
|
+
return NOT_FOUND unless m
|
28
|
+
type_class_name = m[1]
|
29
|
+
key = m[2]
|
30
|
+
|
31
|
+
return NOT_FOUND unless Isomorfeus.valid_data_class_name?(type_class_name)
|
32
|
+
|
33
|
+
type_class = Isomorfeus.cached_data_class(type_class_name)
|
34
|
+
return NOT_FOUND unless type_class.ancestors.include?(LucidFile)
|
35
|
+
|
36
|
+
env['isomorfeus_user_session'] = Isomorfeus::Transport::RackMiddleware.user_from_env(env) unless env.key?('isomorfeus_user_session')
|
37
|
+
user, session_id = env['isomorfeus_user_session']
|
38
|
+
|
39
|
+
authorized = false
|
40
|
+
begin
|
41
|
+
Thread.current[:isomorfeus_user] = user
|
42
|
+
Thread.current[:isomorfeus_session_id] = session_id
|
43
|
+
authorized = true if user.authorized?(type_class, :load, key: key)
|
44
|
+
ensure
|
45
|
+
Thread.current[:isomorfeus_user] = nil
|
46
|
+
Thread.current[:isomorfeus_session_id] = nil
|
47
|
+
end
|
48
|
+
return NOT_AUTHORIZED unless authorized
|
49
|
+
data = type_class.file_accelerator.load_data(sid: SID.new(type_class_name, key))
|
50
|
+
|
51
|
+
return NOT_FOUND unless data
|
52
|
+
|
53
|
+
mime_type = Marcel::MimeType.for(data)
|
54
|
+
headers = { Rack::CONTENT_TYPE => mime_type }
|
55
|
+
|
56
|
+
return [200, headers, [data]]
|
57
|
+
rescue
|
58
|
+
return NOT_FOUND
|
59
|
+
end
|
60
|
+
else
|
61
|
+
@app.call(env)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def check_and_prepare_path(class_name:, key:)
|
66
|
+
# '..', '.' and other critical characters are already excluded by the FILES_REGEXP
|
67
|
+
elements = key.split('/')
|
68
|
+
Isomorfeus.raise_error(message: 'Invalid key (contains more than 2 slashes "/")') if elements.size > 3
|
69
|
+
::File.expand_path(::File.join(Isomorfeus.files_path, class_name, *elements))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -1,30 +1,60 @@
|
|
1
1
|
module Isomorfeus
|
2
2
|
module Data
|
3
3
|
module Reducer
|
4
|
-
|
5
|
-
|
4
|
+
if RUBY_ENGINE == 'opal'
|
5
|
+
CLIENT_REDUCER = proc do |prev_state, action|
|
6
6
|
action_type = action[:type]
|
7
|
-
if action_type.
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
when 'DATA_LOAD'
|
16
|
-
prev_state.deep_merge(action[:data])
|
7
|
+
if action_type == 'DATA_STATE' && action.key?(:set_state)
|
8
|
+
action[:set_state]
|
9
|
+
elsif action_type == 'REDUX_MERGE'
|
10
|
+
red_state = action.dig(:state, :data_state)
|
11
|
+
if red_state
|
12
|
+
new_state = prev_state ? prev_state.deep_dup : {}
|
13
|
+
new_state.deep_merge!(red_state)
|
17
14
|
else
|
18
|
-
prev_state
|
15
|
+
prev_state || {}
|
19
16
|
end
|
17
|
+
elsif action_type == 'DATA_MERGE'
|
18
|
+
new_state = prev_state ? prev_state.deep_dup : {}
|
19
|
+
new_state.deep_merge!(action[:data])
|
20
|
+
new_state
|
20
21
|
else
|
21
|
-
prev_state
|
22
|
+
prev_state || {}
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
def self.add_reducer_to_store
|
27
|
+
::Redux::Store.preloaded_state_merge!(data_state: {})
|
28
|
+
::Redux::Store.add_reducers(data_state: CLIENT_REDUCER)
|
29
|
+
end
|
30
|
+
else # RUBY_ENGINE
|
31
|
+
SERVER_REDUCER = proc do |prev_state, action|
|
32
|
+
action_type = action[:type]
|
33
|
+
if action_type == 'DATA_STATE' && action.key?(:set_state)
|
34
|
+
action[:set_state]
|
35
|
+
elsif action_type == 'DATA_MERGE'
|
36
|
+
new_state = prev_state ? prev_state.deep_dup : {}
|
37
|
+
new_state.deep_merge!(action[:data])
|
38
|
+
new_state
|
39
|
+
elsif action_type == 'DATA_SET'
|
40
|
+
new_state = prev_state ? prev_state.deep_dup : {}
|
41
|
+
if !new_state[action[:class_name]]
|
42
|
+
new_state[action[:class_name]] = {}
|
43
|
+
else
|
44
|
+
new_state[action[:class_name]].delete(action[:key])
|
45
|
+
end
|
46
|
+
new_state[action[:class_name]][action[:key]] = action[:data]
|
47
|
+
new_state
|
48
|
+
else
|
49
|
+
prev_state || {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.add_reducer_to_store
|
54
|
+
::Redux::Store.preloaded_state_merge!(data_state: {})
|
55
|
+
::Redux::Store.add_reducers(data_state: SERVER_REDUCER)
|
56
|
+
end
|
57
|
+
end # RUBY_ENGINE
|
28
58
|
end
|
29
59
|
end
|
30
60
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class SID
|
2
|
+
SID_S_RE = /\ASID__([a-zA-Z0-9:]+)__([\w\/\-]+)__\z/ # must use this way for compatiblity
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def from_s(sid_s)
|
6
|
+
m = SID_S_RE.match(sid_s)
|
7
|
+
self.new(m[1], m[2]) if m
|
8
|
+
end
|
9
|
+
|
10
|
+
def is?(string)
|
11
|
+
SID_S_RE.match?(string)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :class_name
|
16
|
+
attr_reader :key
|
17
|
+
|
18
|
+
if RUBY_ENGINE == 'opal'
|
19
|
+
def initialize(class_name, key)
|
20
|
+
@class_name = class_name
|
21
|
+
@key = key
|
22
|
+
end
|
23
|
+
else
|
24
|
+
def initialize(class_name, key)
|
25
|
+
raise "Invalid class name '#{class_name}!" unless Isomorfeus.valid_data_class_name?(class_name)
|
26
|
+
@class_name = class_name
|
27
|
+
@key = key
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"SID__#{@class_name}__#{@key}__"
|
33
|
+
end
|
34
|
+
end
|
data/lib/isomorfeus-data.rb
CHANGED
@@ -1,50 +1,45 @@
|
|
1
|
-
require 'base64'
|
2
|
-
require 'stringio'
|
3
|
-
if RUBY_ENGINE == 'opal'
|
4
|
-
require 'iso_uri'
|
5
|
-
end
|
6
|
-
require 'data_uri'
|
7
|
-
require 'securerandom'
|
8
|
-
require 'isomorfeus-policy'
|
9
1
|
require 'isomorfeus-transport'
|
2
|
+
require 'isomorfeus-redux'
|
10
3
|
require 'isomorfeus-i18n'
|
4
|
+
require 'isomorfeus-preact'
|
5
|
+
require 'isomorfeus-policy'
|
11
6
|
require 'isomorfeus/data/config'
|
12
|
-
require 'isomorfeus/data/
|
13
|
-
require 'isomorfeus/data/generic_class_api'
|
14
|
-
require 'isomorfeus/data/generic_instance_api'
|
7
|
+
require 'isomorfeus/data/sid'
|
15
8
|
|
16
|
-
if RUBY_ENGINE
|
17
|
-
require 'isomorfeus/data/reducer'
|
18
|
-
Isomorfeus::Data::Reducer.add_reducer_to_store
|
19
|
-
Isomorfeus.zeitwerk.push_dir('isomorfeus_data')
|
20
|
-
require_tree 'isomorfeus_data', autoload: true
|
21
|
-
Isomorfeus.zeitwerk.push_dir('data')
|
22
|
-
else
|
9
|
+
if RUBY_ENGINE != 'opal'
|
23
10
|
require 'fileutils'
|
24
11
|
require 'uri'
|
25
12
|
require 'oj'
|
26
13
|
require 'active_support'
|
27
14
|
require 'active_support/core_ext/hash'
|
28
|
-
|
15
|
+
require 'marcel'
|
29
16
|
require 'isomorfeus-ferret'
|
30
17
|
require 'isomorfeus/data/object_accelerator'
|
18
|
+
require 'isomorfeus/data/file_accelerator'
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'lucid_data_generic'
|
22
|
+
require 'lucid_object'
|
23
|
+
require 'lucid_file'
|
24
|
+
|
25
|
+
require 'isomorfeus/data/reducer'
|
26
|
+
Isomorfeus::Data::Reducer.add_reducer_to_store
|
31
27
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
require 'isomorfeus/data/enhancer'
|
29
|
+
Isomorfeus::Data::Enhancer.add_enhancer_to_store
|
30
|
+
|
31
|
+
if RUBY_ENGINE == 'opal'
|
32
|
+
Isomorfeus.zeitwerk.push_dir('isomorfeus_data')
|
33
|
+
require_tree 'isomorfeus_data', autoload: true
|
34
|
+
Isomorfeus.zeitwerk.push_dir('data')
|
35
|
+
else
|
36
|
+
require 'isomorfeus/data/rack_middleware'
|
39
37
|
|
40
|
-
|
38
|
+
Isomorfeus.add_middleware(Isomorfeus::Data::RackMiddleware)
|
41
39
|
|
42
40
|
require 'iso_opal'
|
43
|
-
Opal.append_path(__dir__.untaint) unless IsoOpal.
|
44
|
-
uri_path = File.expand_path(File.join(__dir__.untaint, '..', 'opal'))
|
45
|
-
Opal.append_path(uri_path) unless IsoOpal.paths.include?(uri_path)
|
41
|
+
Opal.append_path(__dir__.untaint) unless IsoOpal.paths_include?(__dir__.untaint)
|
46
42
|
|
47
43
|
path = File.expand_path(File.join('app', 'data'))
|
48
|
-
|
49
|
-
Isomorfeus.zeitwerk.push_dir(path)
|
44
|
+
Isomorfeus.zeitwerk.push_dir(path) if Dir.exist?(path)
|
50
45
|
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
class LucidDataGeneric
|
2
|
+
class << self
|
3
|
+
def create(key: nil, **things)
|
4
|
+
new(key: key, **things).create
|
5
|
+
end
|
6
|
+
|
7
|
+
def load(key:)
|
8
|
+
instance = self.new(key: key, _loading: true)
|
9
|
+
instance.loaded? ? instance : load!(key: key, instance: instance)
|
10
|
+
end
|
11
|
+
|
12
|
+
def destroyed?(key:)
|
13
|
+
Isomorfeus.store.dig(:data_state, self.name, key, :revision) == -1
|
14
|
+
end
|
15
|
+
|
16
|
+
def current_user
|
17
|
+
Isomorfeus.current_user
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if RUBY_ENGINE == 'opal'
|
22
|
+
class << self
|
23
|
+
# callbacks
|
24
|
+
def before_load(&block); end
|
25
|
+
def after_load(&block); end
|
26
|
+
def before_create(&block); end
|
27
|
+
def after_create(&block); end
|
28
|
+
def before_save(&block); end
|
29
|
+
def after_save(&block); end
|
30
|
+
def before_destroy(&block); end
|
31
|
+
def after_destroy(&block); end
|
32
|
+
end
|
33
|
+
else # RUBY_ENGINE
|
34
|
+
class << self
|
35
|
+
# callbacks
|
36
|
+
|
37
|
+
def before_create(&block)
|
38
|
+
@before_create_block = block
|
39
|
+
end
|
40
|
+
|
41
|
+
def after_create(&block)
|
42
|
+
@after_create_block = block
|
43
|
+
end
|
44
|
+
|
45
|
+
def before_load(&block)
|
46
|
+
@before_load_block = block
|
47
|
+
end
|
48
|
+
|
49
|
+
def after_load(&block)
|
50
|
+
@after_load_block = block
|
51
|
+
end
|
52
|
+
|
53
|
+
def before_save(&block)
|
54
|
+
@before_save_block = block
|
55
|
+
end
|
56
|
+
|
57
|
+
def after_save(&block)
|
58
|
+
@after_save_block = block
|
59
|
+
end
|
60
|
+
|
61
|
+
def before_destroy(&block)
|
62
|
+
@before_destroy_block = block
|
63
|
+
end
|
64
|
+
|
65
|
+
def after_destroy(&block)
|
66
|
+
@after_destroy_block = block
|
67
|
+
end
|
68
|
+
|
69
|
+
# callback readers
|
70
|
+
|
71
|
+
attr_reader :before_create_block, :after_create_block
|
72
|
+
attr_reader :before_load_block, :after_load_block
|
73
|
+
attr_reader :before_save_block, :after_save_block
|
74
|
+
attr_reader :before_destroy_block, :after_destroy_block
|
75
|
+
end
|
76
|
+
|
77
|
+
def pub_sub_client
|
78
|
+
Isomorfeus.pub_sub_client
|
79
|
+
end
|
80
|
+
end # RUBY_ENGINE
|
81
|
+
|
82
|
+
def initialize(key: nil)
|
83
|
+
@key = key.nil? ? SecureRandom.uuid : key.to_s
|
84
|
+
@self_class = self.class
|
85
|
+
@class_name = @self_class.name
|
86
|
+
@class_name = @class_name.split('>::').last if @class_name.start_with?('#<')
|
87
|
+
@changed = false
|
88
|
+
end
|
89
|
+
|
90
|
+
def loaded?
|
91
|
+
revision > 0
|
92
|
+
end
|
93
|
+
|
94
|
+
def instance_uuid
|
95
|
+
@instance_uuid ||= SecureRandom.uuid
|
96
|
+
end
|
97
|
+
|
98
|
+
def state_instance_uuid
|
99
|
+
Isomorfeus.store.dig(:data_state, @class_name, @key, :instance_uuid)
|
100
|
+
end
|
101
|
+
|
102
|
+
def revision
|
103
|
+
Isomorfeus.store.dig(:data_state, @class_name, @key, :revision) || 0
|
104
|
+
end
|
105
|
+
|
106
|
+
def created?
|
107
|
+
(state_instance_uuid == instance_uuid) && (revision == 1)
|
108
|
+
end
|
109
|
+
|
110
|
+
def saved?
|
111
|
+
(state_instance_uuid == instance_uuid) && (revision == (@last_revision + 1))
|
112
|
+
end
|
113
|
+
|
114
|
+
def reload
|
115
|
+
unchange!
|
116
|
+
@self_class.load!(key: @key, instance: self)
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
def destroy
|
121
|
+
@self_class.destroy(key: @key)
|
122
|
+
end
|
123
|
+
|
124
|
+
def destroyed?
|
125
|
+
@self_class.destroyed?(key: @key)
|
126
|
+
end
|
127
|
+
|
128
|
+
def changed!
|
129
|
+
@changed = true
|
130
|
+
end
|
131
|
+
|
132
|
+
def unchange!
|
133
|
+
@changed = false
|
134
|
+
end
|
135
|
+
|
136
|
+
def key
|
137
|
+
@key
|
138
|
+
end
|
139
|
+
|
140
|
+
def key=(k)
|
141
|
+
@key = k.to_s
|
142
|
+
end
|
143
|
+
|
144
|
+
def changed?
|
145
|
+
@changed
|
146
|
+
end
|
147
|
+
|
148
|
+
def sid
|
149
|
+
SID.new(@class_name, @key)
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_n
|
153
|
+
sid.to_s
|
154
|
+
end
|
155
|
+
|
156
|
+
def current_user
|
157
|
+
Isomorfeus.current_user
|
158
|
+
end
|
159
|
+
|
160
|
+
def pub_sub_client
|
161
|
+
Isomorfeus.pub_sub_client
|
162
|
+
end
|
163
|
+
end
|
data/lib/lucid_file.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
class LucidFile < LucidDataGeneric
|
2
|
+
include LucidI18nMixin
|
3
|
+
|
4
|
+
VALID_METHODS = %i[key data data_uri content_type]
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def api_path(key:)
|
8
|
+
"#{Isomorfeus.api_files_path}#{self.name}/#{key}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def format_data_uri(c, d)
|
12
|
+
"data:#{c};base64,#{Base64.strict_encode64(d)}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy(key:)
|
16
|
+
Isomorfeus.store.deferred_dispatch(type: 'FILE_DESTROY', class_name: self.name, key: key)
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def load!(key:, instance: nil)
|
21
|
+
instance = self.new(key: key, _loading: true) unless instance
|
22
|
+
Isomorfeus.something_loading!
|
23
|
+
Isomorfeus.store.deferred_dispatch(type: 'FILE_LOAD', class_name: self.name, key: key)
|
24
|
+
instance
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(key: nil, content_type: nil, data: nil, data_uri: nil, _loading: false)
|
29
|
+
super(key: key)
|
30
|
+
_update_paths
|
31
|
+
loaded = loaded?
|
32
|
+
@changed_uri_string = nil
|
33
|
+
if data_uri
|
34
|
+
@changed_uri_string = data_uri
|
35
|
+
elsif data || content_type
|
36
|
+
data = data.to_s unless data.is_a?(String)
|
37
|
+
if RUBY_ENGINE != 'opal'
|
38
|
+
content_type = Marcel::MimeType.for(data) unless content_type
|
39
|
+
end
|
40
|
+
@changed_uri_string = self.class.format_data_uri(content_type, data)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def create
|
45
|
+
raise 'Already created!' if revision > 0
|
46
|
+
@last_revision = 0
|
47
|
+
d = data_uri
|
48
|
+
unchange!
|
49
|
+
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)
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def save
|
55
|
+
@last_revision = revision
|
56
|
+
return create if @last_revision == 0
|
57
|
+
d = data_uri
|
58
|
+
unchange!
|
59
|
+
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)
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def [](name)
|
65
|
+
self.send(name) if VALID_METHODS.include?(name)
|
66
|
+
end
|
67
|
+
|
68
|
+
def []=(name, value)
|
69
|
+
self.send("#{name}=".to_sym, value) if VALID_METHODS.include?(name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def unchange!
|
73
|
+
super
|
74
|
+
@changed_uri_string = nil
|
75
|
+
end
|
76
|
+
|
77
|
+
def _update_paths
|
78
|
+
@store_path = [:data_state, @class_name, @key, :data_uri]
|
79
|
+
end
|
80
|
+
|
81
|
+
def content_type
|
82
|
+
data_uri_object&.content_type
|
83
|
+
end
|
84
|
+
|
85
|
+
def content_type=(c)
|
86
|
+
changed!
|
87
|
+
uri_string = @changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)
|
88
|
+
@changed_uri_string = self.class.format_data_uri(c, URI::Data.new(uri_string).data)
|
89
|
+
c
|
90
|
+
end
|
91
|
+
|
92
|
+
def data_uri
|
93
|
+
@changed_uri_string ? @changed_uri_string : Isomorfeus.store.dig(*@store_path)
|
94
|
+
end
|
95
|
+
|
96
|
+
def data_uri=(d)
|
97
|
+
changed!
|
98
|
+
@changed_uri_string = d
|
99
|
+
end
|
100
|
+
|
101
|
+
def data_uri_object
|
102
|
+
du = data_uri
|
103
|
+
URI::Data.new(du) if du
|
104
|
+
end
|
105
|
+
|
106
|
+
def data
|
107
|
+
data_uri_object&.data
|
108
|
+
end
|
109
|
+
|
110
|
+
def data=(d)
|
111
|
+
changed!
|
112
|
+
d = d.to_s unless d.is_a?(String)
|
113
|
+
if RUBY_ENGINE == 'opal'
|
114
|
+
ct = content_type
|
115
|
+
else
|
116
|
+
ct = Marcel::MimeType.for(d)
|
117
|
+
end
|
118
|
+
@changed_uri_string = self.class.format_data_uri(ct, d)
|
119
|
+
end
|
120
|
+
|
121
|
+
if RUBY_ENGINE != 'opal'
|
122
|
+
class << self
|
123
|
+
def inherited(base)
|
124
|
+
Isomorfeus.add_valid_data_class(base) unless 'LucidFile' == base.name
|
125
|
+
end
|
126
|
+
|
127
|
+
def file_accelerator
|
128
|
+
@file_accelerator ||= Isomorfeus::Data::FileAccelerator.new(self)
|
129
|
+
end
|
130
|
+
|
131
|
+
def exist?(key:)
|
132
|
+
raise "Not authorized!" unless current_user.authorized?(self, :load, key: key)
|
133
|
+
file_accelerator.exist?(sid: SID.new(self.name, key))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end # RUBY_ENGINE
|
137
|
+
end
|