legion-data 1.10.17 → 1.11.7

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/AGENTS.md +35 -2
  4. data/CHANGELOG.md +109 -0
  5. data/CLAUDE.md +1 -30
  6. data/Gemfile +3 -0
  7. data/README.md +134 -17
  8. data/legion-data.gemspec +1 -1
  9. data/lib/legion/data/archival/policy.rb +1 -16
  10. data/lib/legion/data/archival.rb +49 -50
  11. data/lib/legion/data/archiver.rb +2 -1
  12. data/lib/legion/data/audit_log_hash_chain.rb +3 -1
  13. data/lib/legion/data/audit_record.rb +25 -31
  14. data/lib/legion/data/connection.rb +13 -46
  15. data/lib/legion/data/database_lock.rb +23 -0
  16. data/lib/legion/data/event_store.rb +14 -14
  17. data/lib/legion/data/extract.rb +5 -7
  18. data/lib/legion/data/helper.rb +1 -1
  19. data/lib/legion/data/local.rb +9 -21
  20. data/lib/legion/data/migration.rb +24 -0
  21. data/lib/legion/data/migrations/137_preserve_task_archive_fields.rb +37 -0
  22. data/lib/legion/data/migrations/138_add_append_claims.rb +11 -0
  23. data/lib/legion/data/migrations/139_create_task_logs.rb +27 -0
  24. data/lib/legion/data/model.rb +2 -2
  25. data/lib/legion/data/models/append_claim.rb +10 -0
  26. data/lib/legion/data/models/audit_log.rb +34 -2
  27. data/lib/legion/data/models/data_archive.rb +10 -0
  28. data/lib/legion/data/models/governance_event.rb +10 -0
  29. data/lib/legion/data/models/task.rb +5 -5
  30. data/lib/legion/data/models/task_log.rb +16 -0
  31. data/lib/legion/data/retention.rb +42 -11
  32. data/lib/legion/data/settings.rb +6 -9
  33. data/lib/legion/data/spool.rb +36 -16
  34. data/lib/legion/data/storage_tiers.rb +26 -20
  35. data/lib/legion/data/task/status.rb +36 -0
  36. data/lib/legion/data/version.rb +1 -1
  37. data/lib/legion/data.rb +47 -23
  38. metadata +11 -3
data/lib/legion/data.rb CHANGED
@@ -17,6 +17,7 @@ require_relative 'data/rls'
17
17
  require_relative 'data/extract'
18
18
  require_relative 'data/audit_record'
19
19
  require_relative 'data/audit_log_hash_chain'
20
+ require_relative 'data/task/status'
20
21
 
21
22
  unless Legion::Logging::Helper.method_defined?(:handle_exception)
22
23
  module Legion
@@ -83,6 +84,8 @@ module Legion
83
84
  end
84
85
 
85
86
  def setup_cache
87
+ return unless Legion::Settings[:data][:models][:loaded]
88
+
86
89
  cache_settings = Legion::Settings[:data][:cache]
87
90
  setup_static_cache if cache_settings[:static_cache]
88
91
  setup_external_cache if cache_settings[:auto_enable] && defined?(::Legion::Cache)
@@ -133,36 +136,56 @@ module Legion
133
136
  def can_write?(table_name)
134
137
  return false unless connected?
135
138
 
136
- adapter = Legion::Settings[:data][:adapter]&.to_s
137
- return true if adapter == 'sqlite'
138
-
139
- @write_privileges ||= {}
140
- return @write_privileges[table_name] unless @write_privileges[table_name].nil?
141
-
142
- @write_privileges[table_name] = connection
143
- .fetch("SELECT has_table_privilege(current_user, ?, 'INSERT') AS can", table_name.to_s)
144
- .first[:can] == true
139
+ database = connection
140
+ return false unless database
141
+ return true if database.database_type == :sqlite
142
+
143
+ cache = @write_privileges ||= ObjectSpace::WeakKeyMap.new
144
+ database.synchronize do |session|
145
+ privileges = cache[session] ||= {}
146
+ return privileges[table_name] if privileges.key?(table_name)
147
+
148
+ privileges[table_name] = case database.database_type
149
+ when :postgres
150
+ database.fetch("SELECT has_table_privilege(current_user, ?, 'INSERT') AS can", table_name.to_s)
151
+ .server(:default).first[:can] == true
152
+ when :mysql
153
+ database.fetch('EXPLAIN INSERT INTO ? () VALUES ()', Sequel.identifier(table_name)).server(:default).all
154
+ true
155
+ else
156
+ raise Sequel::Error, "Unsupported privilege adapter: #{database.database_type}"
157
+ end
158
+ end
145
159
  rescue StandardError => e
146
160
  handle_exception(e, level: :warn, handled: true, operation: :can_write?, table: table_name)
147
- @write_privileges[table_name] = false if @write_privileges
148
161
  false
149
162
  end
150
163
 
151
164
  def can_read?(table_name)
152
165
  return false unless connected?
153
166
 
154
- adapter = Legion::Settings[:data][:adapter]&.to_s
155
- return true if adapter == 'sqlite'
156
-
157
- @read_privileges ||= {}
158
- return @read_privileges[table_name] unless @read_privileges[table_name].nil?
159
-
160
- @read_privileges[table_name] = connection
161
- .fetch("SELECT has_table_privilege(current_user, ?, 'SELECT') AS can", table_name.to_s)
162
- .first[:can] == true
167
+ database = connection
168
+ return false unless database
169
+ return true if database.database_type == :sqlite
170
+
171
+ cache = @read_privileges ||= ObjectSpace::WeakKeyMap.new
172
+ database.synchronize do |session|
173
+ privileges = cache[session] ||= {}
174
+ return privileges[table_name] if privileges.key?(table_name)
175
+
176
+ privileges[table_name] = case database.database_type
177
+ when :postgres
178
+ database.fetch("SELECT has_table_privilege(current_user, ?, 'SELECT') AS can", table_name.to_s)
179
+ .server(:default).first[:can] == true
180
+ when :mysql
181
+ database.fetch('SELECT * FROM ? LIMIT 0', Sequel.identifier(table_name)).server(:default).all
182
+ true
183
+ else
184
+ raise Sequel::Error, "Unsupported privilege adapter: #{database.database_type}"
185
+ end
186
+ end
163
187
  rescue StandardError => e
164
188
  handle_exception(e, level: :warn, handled: true, operation: :can_read?, table: table_name)
165
- @read_privileges[table_name] = false if @read_privileges
166
189
  false
167
190
  end
168
191
 
@@ -189,7 +212,7 @@ module Legion
189
212
  end
190
213
 
191
214
  def setup_external_cache
192
- ttl = Legion::Settings[:data][:cache][:ttl] || 60
215
+ ttl = Legion::Settings[:data][:cache][:ttl]
193
216
  {
194
217
  Model::Relationship => 10,
195
218
  Model::Node => 10,
@@ -205,8 +228,9 @@ module Legion
205
228
 
206
229
  def shutdown
207
230
  Legion::Data::Local.shutdown if defined?(Legion::Data::Local) && Legion::Data::Local.connected?
208
- Legion::Data::Connection.shutdown
209
- log.info 'Legion::Data shutdown complete'
231
+ closed = Legion::Data::Connection.shutdown
232
+ log.info 'Legion::Data shutdown complete' if closed
233
+ closed
210
234
  end
211
235
 
212
236
  private
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.17
4
+ version: 1.11.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -57,14 +57,14 @@ dependencies:
57
57
  requirements:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: 1.3.26
60
+ version: 1.4.5
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 1.3.26
67
+ version: 1.4.5
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: sequel
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -126,6 +126,7 @@ files:
126
126
  - lib/legion/data/audit_record.rb
127
127
  - lib/legion/data/auth_failure_handler.rb
128
128
  - lib/legion/data/connection.rb
129
+ - lib/legion/data/database_lock.rb
129
130
  - lib/legion/data/encryption/cipher.rb
130
131
  - lib/legion/data/encryption/key_provider.rb
131
132
  - lib/legion/data/encryption/sequel_plugin.rb
@@ -284,6 +285,9 @@ files:
284
285
  - lib/legion/data/migrations/134_add_route_attempt_columns.rb
285
286
  - lib/legion/data/migrations/135_add_llm_context_token_accounting.rb
286
287
  - lib/legion/data/migrations/136_drop_llm_messages_seq_unique.rb
288
+ - lib/legion/data/migrations/137_preserve_task_archive_fields.rb
289
+ - lib/legion/data/migrations/138_add_append_claims.rb
290
+ - lib/legion/data/migrations/139_create_task_logs.rb
287
291
  - lib/legion/data/model.rb
288
292
  - lib/legion/data/models/apollo/access_log.rb
289
293
  - lib/legion/data/models/apollo/entries.rb
@@ -295,13 +299,16 @@ files:
295
299
  - lib/legion/data/models/apollo_entry.rb
296
300
  - lib/legion/data/models/apollo_expertise.rb
297
301
  - lib/legion/data/models/apollo_relation.rb
302
+ - lib/legion/data/models/append_claim.rb
298
303
  - lib/legion/data/models/audit_log.rb
299
304
  - lib/legion/data/models/audit_record.rb
300
305
  - lib/legion/data/models/chain.rb
306
+ - lib/legion/data/models/data_archive.rb
301
307
  - lib/legion/data/models/digital_worker.rb
302
308
  - lib/legion/data/models/extension.rb
303
309
  - lib/legion/data/models/extract_step_timing.rb
304
310
  - lib/legion/data/models/function.rb
311
+ - lib/legion/data/models/governance_event.rb
305
312
  - lib/legion/data/models/identity/audit_log.rb
306
313
  - lib/legion/data/models/identity/group.rb
307
314
  - lib/legion/data/models/identity/group_memberships.rb
@@ -342,6 +349,7 @@ files:
342
349
  - lib/legion/data/settings.rb
343
350
  - lib/legion/data/spool.rb
344
351
  - lib/legion/data/storage_tiers.rb
352
+ - lib/legion/data/task/status.rb
345
353
  - lib/legion/data/vector.rb
346
354
  - lib/legion/data/version.rb
347
355
  - scripts/pre-commit-rubocop.sh