terret-store-sqlite 0.1.0
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/terret/store/sqlite.rb +78 -0
- metadata +75 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: deca4043ba1082b662376023c97027ae2f4f2a917c45cdc9561b7ab6cd68eb9c
|
|
4
|
+
data.tar.gz: f9e3b51ee478574126bf02e7e1338a64fd7eeeabf5fdf7c7fbe8aba363ccbf03
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b8a023c93e4c19877279820949f8f7e0f75ecc62a58347bf77300c4a503af8e08ae51838034ebcd6beaec72c6c30980b3b8ed9cc63eb6e2233d354773cb9b52a
|
|
7
|
+
data.tar.gz: 87910a8fa2db133ea0a25d7e2c864303cea11a694649a0ea041c2d5a5a891e2c26bfd8c046d5f366693a8ce1aba53fb59b233da08a43c6e07f22f6b9dcda1973
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "terret"
|
|
5
|
+
rescue LoadError
|
|
6
|
+
require_relative "../../../../terret-core/lib/terret" # monorepo path source
|
|
7
|
+
end
|
|
8
|
+
require "sqlite3"
|
|
9
|
+
require "json"
|
|
10
|
+
require "time"
|
|
11
|
+
require "fileutils"
|
|
12
|
+
|
|
13
|
+
module Terret
|
|
14
|
+
module Store
|
|
15
|
+
# SQLite provider: the durable default for long-lived processes. WAL for
|
|
16
|
+
# concurrent readers, busy_timeout instead of hand-rolled retries, one
|
|
17
|
+
# row per event keyed (session_id, seq). Appends are synchronous; the
|
|
18
|
+
# per-session writer task from plan §8 is deferred until many-agent
|
|
19
|
+
# load exists.
|
|
20
|
+
class SQLite < Hames::Service
|
|
21
|
+
service_key :session_store
|
|
22
|
+
config_schema path: { type: String, required: true,
|
|
23
|
+
doc: "SQLite database file for the append-only session log" }
|
|
24
|
+
|
|
25
|
+
SCHEMA = <<~SQL
|
|
26
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
27
|
+
session_id TEXT NOT NULL,
|
|
28
|
+
seq INTEGER NOT NULL,
|
|
29
|
+
id TEXT NOT NULL,
|
|
30
|
+
at TEXT NOT NULL,
|
|
31
|
+
type TEXT NOT NULL,
|
|
32
|
+
payload TEXT NOT NULL,
|
|
33
|
+
PRIMARY KEY (session_id, seq)
|
|
34
|
+
)
|
|
35
|
+
SQL
|
|
36
|
+
|
|
37
|
+
def start(_ctx)
|
|
38
|
+
@db ||= begin
|
|
39
|
+
path = config.fetch(:path)
|
|
40
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
41
|
+
db = SQLite3::Database.new(path)
|
|
42
|
+
db.busy_timeout = 5_000
|
|
43
|
+
db.execute("PRAGMA journal_mode=WAL")
|
|
44
|
+
db.execute(SCHEMA)
|
|
45
|
+
db
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def stop(_ctx)
|
|
50
|
+
@db&.close
|
|
51
|
+
@db = nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def append(event)
|
|
55
|
+
@db.execute(
|
|
56
|
+
"INSERT INTO events (session_id, seq, id, at, type, payload) VALUES (?, ?, ?, ?, ?, ?)",
|
|
57
|
+
[event.session_id, event.seq, event.id, event.at.iso8601(6),
|
|
58
|
+
event.type, JSON.generate(event.payload)]
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def read(session_id, from_seq: 0)
|
|
63
|
+
rows = @db.execute(
|
|
64
|
+
"SELECT id, seq, at, type, payload FROM events WHERE session_id = ? AND seq >= ? ORDER BY seq",
|
|
65
|
+
[session_id, from_seq]
|
|
66
|
+
)
|
|
67
|
+
rows.map do |id, seq, at, type, payload|
|
|
68
|
+
SessionEvent.new(id:, session_id:, seq:, at: Time.iso8601(at), type: type,
|
|
69
|
+
payload: JSON.parse(payload, symbolize_names: true))
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def session_ids
|
|
74
|
+
@db.execute("SELECT DISTINCT session_id FROM events ORDER BY session_id").flatten
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: terret-store-sqlite
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Obie Fernandez
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: terret-core
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: sqlite3
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.9'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.9'
|
|
40
|
+
description: 'Durable session persistence for Terret: the append-only session log
|
|
41
|
+
stored one event per row in SQLite (WAL mode), behind the ctx[:session_store] seam,
|
|
42
|
+
so sessions survive process restarts with byte-identical derived context.'
|
|
43
|
+
email:
|
|
44
|
+
- obiefernandez@gmail.com
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- lib/terret/store/sqlite.rb
|
|
50
|
+
homepage: https://terret.org
|
|
51
|
+
licenses:
|
|
52
|
+
- MIT
|
|
53
|
+
metadata:
|
|
54
|
+
homepage_uri: https://terret.org
|
|
55
|
+
source_code_uri: https://github.com/terret-org/terret
|
|
56
|
+
bug_tracker_uri: https://github.com/terret-org/terret/issues
|
|
57
|
+
rubygems_mfa_required: 'true'
|
|
58
|
+
rdoc_options: []
|
|
59
|
+
require_paths:
|
|
60
|
+
- lib
|
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '4.0'
|
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0'
|
|
71
|
+
requirements: []
|
|
72
|
+
rubygems_version: 4.0.16
|
|
73
|
+
specification_version: 4
|
|
74
|
+
summary: SQLite session store for the Terret agent harness
|
|
75
|
+
test_files: []
|