Module: Whodunit::Chronicles::Persistence

Included in:
Processor
Defined in:
lib/whodunit/chronicles/persistence.rb

Overview

Handles record persistence for different database adapters

Provides adapter-specific SQL for inserting chronicle records

Instance Method Summary collapse

Instance Method Details

#build_record_params(record) ⇒ Object (private)



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/whodunit/chronicles/persistence.rb', line 109

def build_record_params(record)
  [
    record[:table_name],
    record[:schema_name],
    record[:record_id].to_json,
    record[:action],
    record[:old_data]&.to_json,
    record[:new_data]&.to_json,
    record[:changes].to_json,
    record[:user_id],
    record[:user_type],
    record[:transaction_id],
    record[:sequence_number],
    record[:occurred_at],
    record[:created_at],
    record[:metadata].to_json,
  ]
end

#persist_record(record) ⇒ Object (private)



11
12
13
14
15
16
17
18
19
20
# File 'lib/whodunit/chronicles/persistence.rb', line 11

def persist_record(record)
  db_type = detect_database_type(@audit_database_url || Chronicles.config.database_url)

  case db_type
  when :postgresql
    persist_record_postgresql(record)
  when :mysql
    persist_record_mysql(record)
  end
end

#persist_record_mysql(record) ⇒ Object (private)



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/whodunit/chronicles/persistence.rb', line 39

def persist_record_mysql(record)
  sql = "    INSERT INTO whodunit_chronicles_audits (\n      table_name, schema_name, record_id, action, old_data, new_data, changes,\n      user_id, user_type, transaction_id, sequence_number, occurred_at, created_at, metadata\n    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n  SQL\n\n  params = build_record_params(record)\n  @connection.execute(sql, *params)\n  record[:id] = @connection.last_insert_id\n\n  record\nend\n"

#persist_record_postgresql(record) ⇒ Object (private)



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/whodunit/chronicles/persistence.rb', line 22

def persist_record_postgresql(record)
  sql = "    INSERT INTO whodunit_chronicles_audits (\n      table_name, schema_name, record_id, action, old_data, new_data, changes,\n      user_id, user_type, transaction_id, sequence_number, occurred_at, created_at, metadata\n    ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)\n    RETURNING id\n  SQL\n\n  params = build_record_params(record)\n  result = @connection.exec_params(sql, params)\n  record[:id] = result.first['id'].to_i\n  result.clear\n\n  record\nend\n"

#persist_records_batch(records) ⇒ Object (private)



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/whodunit/chronicles/persistence.rb', line 54

def persist_records_batch(records)
  return records if records.empty?

  db_type = detect_database_type(@audit_database_url || Chronicles.config.database_url)

  case db_type
  when :postgresql
    persist_records_batch_postgresql(records)
  when :mysql
    persist_records_batch_mysql(records)
  end
end

#persist_records_batch_mysql(records) ⇒ Object (private)



99
100
101
102
103
104
105
106
107
# File 'lib/whodunit/chronicles/persistence.rb', line 99

def persist_records_batch_mysql(records)
  # For MySQL, we'll use individual inserts in a transaction for simplicity
  # A more optimized version could use VALUES() with multiple rows
  records.each do |record|
    persist_record_mysql(record)
  end

  records
end

#persist_records_batch_postgresql(records) ⇒ Object (private)



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/whodunit/chronicles/persistence.rb', line 67

def persist_records_batch_postgresql(records)
  # Use multi-row INSERT for better performance
  values_clauses = []
  all_params = []
  param_index = 1

  records.each do |record|
    param_positions = (param_index..(param_index + 13)).map { |i| "$#{i}" }.join(', ')
    values_clauses << "(#{param_positions})"
    all_params.concat(build_record_params(record))
    param_index += 14
  end

  sql = "    INSERT INTO whodunit_chronicles_audits (\n      table_name, schema_name, record_id, action, old_data, new_data, changes,\n      user_id, user_type, transaction_id, sequence_number, occurred_at, created_at, metadata\n    ) VALUES \#{values_clauses.join(', ')}\n    RETURNING id\n  SQL\n\n  result = @connection.exec_params(sql, all_params)\n\n  # Set IDs on the records\n  result.each_with_index do |row, index|\n    records[index][:id] = row['id'].to_i\n  end\n\n  result.clear\n  records\nend\n"