Class: Lich::Common::SessionDatabaseAdapter

Inherits:
Object
  • Object
show all
Defined in:
documented/common/settings/session_database_adapter.rb

Overview

Row-oriented adapter for session summary state. This intentionally differs from blob-backed script_auto_settings storage.

Constant Summary collapse

DEFAULT_TABLE_NAME =
'session_summary_state'

Instance Method Summary collapse

Constructor Details

#initialize(db: nil, data_dir: DATA_DIR, table_name: DEFAULT_TABLE_NAME) ⇒ SessionDatabaseAdapter

Builds an adapter bound to a row-oriented session summary table.

Parameters:

  • db (SQLite3::Database, nil) (defaults to: nil)

    optional injected database connection

  • data_dir (String) (defaults to: DATA_DIR)

    directory containing lich.db3 when db is not injected

  • table_name (String) (defaults to: DEFAULT_TABLE_NAME)

    session summary table name



19
20
21
22
# File 'documented/common/settings/session_database_adapter.rb', line 19

def initialize(db: nil, data_dir: DATA_DIR, table_name: DEFAULT_TABLE_NAME)
  @db = db || open_database(File.join(data_dir, 'lich.db3'))
  @table_name = table_name
end

Instance Method Details

#active_sessionsArray<Hash>

Returns all rows currently tracked in the session summary table.

Returns:

  • (Array<Hash>)

    rows sorted by pid



57
58
59
60
61
# File 'documented/common/settings/session_database_adapter.rb', line 57

def active_sessions
  with_retry do
    rows_as_hashes("SELECT * FROM #{@table_name} ORDER BY pid ASC;")
  end
end

#delete_session(pid:) ⇒ void

This method returns an undefined value.

Deletes a row for the provided pid.

Parameters:

  • pid (Integer)


67
68
69
70
71
# File 'documented/common/settings/session_database_adapter.rb', line 67

def delete_session(pid:)
  with_retry do
    @db.execute("DELETE FROM #{@table_name} WHERE pid = ?;", [pid])
  end
end

#duplicate_active_session_namesArray<Hash>

Returns names that currently appear more than once. Duplicate names are treated as data points, not enforcement failures.

Returns:

  • (Array<Hash>)

    rows containing session_name and duplicate_count



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'documented/common/settings/session_database_adapter.rb', line 87

def duplicate_active_session_names
  with_retry do
    rows_as_hashes(<<~SQL)
      SELECT session_name, COUNT(*) AS duplicate_count
      FROM #{@table_name}
      WHERE session_name IS NOT NULL
        AND session_name != ''
        AND COALESCE(state, '') != 'exited'
      GROUP BY session_name
      HAVING COUNT(*) > 1
      ORDER BY session_name ASC;
    SQL
  end
end

#find_session(pid:) ⇒ Hash?

Finds one row by pid.

Parameters:

  • pid (Integer)

Returns:



77
78
79
80
81
# File 'documented/common/settings/session_database_adapter.rb', line 77

def find_session(pid:)
  with_retry do
    rows_as_hashes("SELECT * FROM #{@table_name} WHERE pid = ? LIMIT 1;", [pid.to_i]).first
  end
end

#tracked_live_candidatesArray<Hash>

Returns rows that still appear active in storage and may need a liveness sweep against the current OS process table.

Returns:

  • (Array<Hash>)

    non-exited rows sorted by pid



106
107
108
109
110
111
112
113
114
# File 'documented/common/settings/session_database_adapter.rb', line 106

def tracked_live_candidates
  with_retry do
    rows_as_hashes(<<~SQL)
      SELECT * FROM #{@table_name}
      WHERE COALESCE(state, '') != 'exited'
      ORDER BY pid ASC;
    SQL
  end
end

#upsert_session(payload) ⇒ void

This method returns an undefined value.

Inserts or updates a session row by pid.

Parameters:

  • payload (Hash)

    row fields for insert/update



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'documented/common/settings/session_database_adapter.rb', line 28

def upsert_session(payload)
  with_retry do
    @db.execute(<<~SQL, bind_params(payload))
      INSERT INTO #{@table_name} (
        pid, session_name, role, state, frontend, game_code, hidden,
        started_at, last_heartbeat_at, os_seen_at, os_seen, os_name, last_utilization_at, metadata_json
      )
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
      ON CONFLICT(pid) DO UPDATE SET
        session_name = COALESCE(excluded.session_name, #{@table_name}.session_name),
        role = COALESCE(excluded.role, #{@table_name}.role),
        state = COALESCE(excluded.state, #{@table_name}.state),
        frontend = COALESCE(excluded.frontend, #{@table_name}.frontend),
        game_code = COALESCE(excluded.game_code, #{@table_name}.game_code),
        hidden = COALESCE(excluded.hidden, #{@table_name}.hidden),
        started_at = COALESCE(excluded.started_at, #{@table_name}.started_at),
        last_heartbeat_at = COALESCE(excluded.last_heartbeat_at, #{@table_name}.last_heartbeat_at),
        os_seen_at = COALESCE(excluded.os_seen_at, #{@table_name}.os_seen_at),
        os_seen = COALESCE(excluded.os_seen, #{@table_name}.os_seen),
        os_name = COALESCE(excluded.os_name, #{@table_name}.os_name),
        last_utilization_at = COALESCE(excluded.last_utilization_at, #{@table_name}.last_utilization_at),
        metadata_json = COALESCE(excluded.metadata_json, #{@table_name}.metadata_json);
    SQL
  end
end