panda-core 0.1.11 → 0.1.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a61ca18a8280d264ca0f81f403fbedd427872848bfd73334c350205e7f9aa60
4
- data.tar.gz: e637501064e17fedd6f287acd78a50e718737e39aa63138073b780dd4643546f
3
+ metadata.gz: cc545a266b233a065a0ad1400d61566033d676509364cbb0b3264cfebf1f937c
4
+ data.tar.gz: 1328107817e05bf72dd11dd0b3b27a3d39813b792ef2cd19b7e3d545d12a9df8
5
5
  SHA512:
6
- metadata.gz: 2053ea6d1b6d8aeb58ce3ad4ee86b76add70f9c9cbc082acd208a1344f9048c1ea19e60ccb57de14c9ceb911f30b8b599ddeb3be59d5e4104c57705cc757acc6
7
- data.tar.gz: 469d3de7cb13945f47402163b46d4c0f014235a5263e18ec525e6a08b4d7634f1170ac67ebc8f8496074ca8f0b07537515e68ad19006967e82d91ab3cc696f9f
6
+ metadata.gz: 221e370f59805011182520d1846637996517b080639dae1273814b8d44409bcc21b5af9b60f668acae9519a849407bb47f590f8c5ec29be35c67d743ad87dff5
7
+ data.tar.gz: 07bf703d37be3e11224154713566817eebe59e99660a902d52c2c7b77f050049fb8334ea501ba939e71537e12d33c6dc38130f02f7dbd6c9dd17713fcf4bbc9c
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+ load "rails/tasks/statistics.rake"
6
+
2
7
  require "bundler/gem_tasks"
@@ -0,0 +1,577 @@
1
+ class LogidzeInstall < ActiveRecord::Migration[8.0]
2
+ def up
3
+ execute <<~SQL
4
+ CREATE OR REPLACE FUNCTION logidze_capture_exception(error_data jsonb) RETURNS boolean AS $body$
5
+ -- version: 1
6
+ BEGIN
7
+ -- Feel free to change this function to change Logidze behavior on exception.
8
+ --
9
+ -- Return `false` to raise exception or `true` to commit record changes.
10
+ --
11
+ -- `error_data` contains:
12
+ -- - returned_sqlstate
13
+ -- - message_text
14
+ -- - pg_exception_detail
15
+ -- - pg_exception_hint
16
+ -- - pg_exception_context
17
+ -- - schema_name
18
+ -- - table_name
19
+ -- Learn more about available keys:
20
+ -- https://www.postgresql.org/docs/9.6/plpgsql-control-structures.html#PLPGSQL-EXCEPTION-DIAGNOSTICS-VALUES
21
+ --
22
+
23
+ return false;
24
+ END;
25
+ $body$
26
+ LANGUAGE plpgsql;
27
+
28
+ CREATE OR REPLACE FUNCTION logidze_compact_history(log_data jsonb, cutoff integer DEFAULT 1) RETURNS jsonb AS $body$
29
+ -- version: 1
30
+ DECLARE
31
+ merged jsonb;
32
+ BEGIN
33
+ LOOP
34
+ merged := jsonb_build_object(
35
+ 'ts',
36
+ log_data#>'{h,1,ts}',
37
+ 'v',
38
+ log_data#>'{h,1,v}',
39
+ 'c',
40
+ (log_data#>'{h,0,c}') || (log_data#>'{h,1,c}')
41
+ );
42
+
43
+ IF (log_data#>'{h,1}' ? 'm') THEN
44
+ merged := jsonb_set(merged, ARRAY['m'], log_data#>'{h,1,m}');
45
+ END IF;
46
+
47
+ log_data := jsonb_set(
48
+ log_data,
49
+ '{h}',
50
+ jsonb_set(
51
+ log_data->'h',
52
+ '{1}',
53
+ merged
54
+ ) - 0
55
+ );
56
+
57
+ cutoff := cutoff - 1;
58
+
59
+ EXIT WHEN cutoff <= 0;
60
+ END LOOP;
61
+
62
+ return log_data;
63
+ END;
64
+ $body$
65
+ LANGUAGE plpgsql;
66
+
67
+ CREATE OR REPLACE FUNCTION logidze_filter_keys(obj jsonb, keys text[], include_columns boolean DEFAULT false) RETURNS jsonb AS $body$
68
+ -- version: 1
69
+ DECLARE
70
+ res jsonb;
71
+ key text;
72
+ BEGIN
73
+ res := '{}';
74
+
75
+ IF include_columns THEN
76
+ FOREACH key IN ARRAY keys
77
+ LOOP
78
+ IF obj ? key THEN
79
+ res = jsonb_insert(res, ARRAY[key], obj->key);
80
+ END IF;
81
+ END LOOP;
82
+ ELSE
83
+ res = obj;
84
+ FOREACH key IN ARRAY keys
85
+ LOOP
86
+ res = res - key;
87
+ END LOOP;
88
+ END IF;
89
+
90
+ RETURN res;
91
+ END;
92
+ $body$
93
+ LANGUAGE plpgsql;
94
+
95
+ CREATE OR REPLACE FUNCTION logidze_logger() RETURNS TRIGGER AS $body$
96
+ -- version: 4
97
+ DECLARE
98
+ changes jsonb;
99
+ version jsonb;
100
+ full_snapshot boolean;
101
+ log_data jsonb;
102
+ new_v integer;
103
+ size integer;
104
+ history_limit integer;
105
+ debounce_time integer;
106
+ current_version integer;
107
+ k text;
108
+ iterator integer;
109
+ item record;
110
+ columns text[];
111
+ include_columns boolean;
112
+ ts timestamp with time zone;
113
+ ts_column text;
114
+ err_sqlstate text;
115
+ err_message text;
116
+ err_detail text;
117
+ err_hint text;
118
+ err_context text;
119
+ err_table_name text;
120
+ err_schema_name text;
121
+ err_jsonb jsonb;
122
+ err_captured boolean;
123
+ BEGIN
124
+ ts_column := NULLIF(TG_ARGV[1], 'null');
125
+ columns := NULLIF(TG_ARGV[2], 'null');
126
+ include_columns := NULLIF(TG_ARGV[3], 'null');
127
+
128
+ IF NEW.log_data is NULL OR NEW.log_data = '{}'::jsonb
129
+ THEN
130
+ IF columns IS NOT NULL THEN
131
+ log_data = logidze_snapshot(to_jsonb(NEW.*), ts_column, columns, include_columns);
132
+ ELSE
133
+ log_data = logidze_snapshot(to_jsonb(NEW.*), ts_column);
134
+ END IF;
135
+
136
+ IF log_data#>>'{h, -1, c}' != '{}' THEN
137
+ NEW.log_data := log_data;
138
+ END IF;
139
+
140
+ ELSE
141
+
142
+ IF TG_OP = 'UPDATE' AND (to_jsonb(NEW.*) = to_jsonb(OLD.*)) THEN
143
+ RETURN NEW; -- pass
144
+ END IF;
145
+
146
+ history_limit := NULLIF(TG_ARGV[0], 'null');
147
+ debounce_time := NULLIF(TG_ARGV[4], 'null');
148
+
149
+ log_data := NEW.log_data;
150
+
151
+ current_version := (log_data->>'v')::int;
152
+
153
+ IF ts_column IS NULL THEN
154
+ ts := statement_timestamp();
155
+ ELSEIF TG_OP = 'UPDATE' THEN
156
+ ts := (to_jsonb(NEW.*) ->> ts_column)::timestamp with time zone;
157
+ IF ts IS NULL OR ts = (to_jsonb(OLD.*) ->> ts_column)::timestamp with time zone THEN
158
+ ts := statement_timestamp();
159
+ END IF;
160
+ ELSEIF TG_OP = 'INSERT' THEN
161
+ ts := (to_jsonb(NEW.*) ->> ts_column)::timestamp with time zone;
162
+ IF ts IS NULL OR (extract(epoch from ts) * 1000)::bigint = (NEW.log_data #>> '{h,-1,ts}')::bigint THEN
163
+ ts := statement_timestamp();
164
+ END IF;
165
+ END IF;
166
+
167
+ full_snapshot := (coalesce(current_setting('logidze.full_snapshot', true), '') = 'on') OR (TG_OP = 'INSERT');
168
+
169
+ IF current_version < (log_data#>>'{h,-1,v}')::int THEN
170
+ iterator := 0;
171
+ FOR item in SELECT * FROM jsonb_array_elements(log_data->'h')
172
+ LOOP
173
+ IF (item.value->>'v')::int > current_version THEN
174
+ log_data := jsonb_set(
175
+ log_data,
176
+ '{h}',
177
+ (log_data->'h') - iterator
178
+ );
179
+ END IF;
180
+ iterator := iterator + 1;
181
+ END LOOP;
182
+ END IF;
183
+
184
+ changes := '{}';
185
+
186
+ IF full_snapshot THEN
187
+ BEGIN
188
+ changes = hstore_to_jsonb_loose(hstore(NEW.*));
189
+ EXCEPTION
190
+ WHEN NUMERIC_VALUE_OUT_OF_RANGE THEN
191
+ changes = row_to_json(NEW.*)::jsonb;
192
+ FOR k IN (SELECT key FROM jsonb_each(changes))
193
+ LOOP
194
+ IF jsonb_typeof(changes->k) = 'object' THEN
195
+ changes = jsonb_set(changes, ARRAY[k], to_jsonb(changes->>k));
196
+ END IF;
197
+ END LOOP;
198
+ END;
199
+ ELSE
200
+ BEGIN
201
+ changes = hstore_to_jsonb_loose(
202
+ hstore(NEW.*) - hstore(OLD.*)
203
+ );
204
+ EXCEPTION
205
+ WHEN NUMERIC_VALUE_OUT_OF_RANGE THEN
206
+ changes = (SELECT
207
+ COALESCE(json_object_agg(key, value), '{}')::jsonb
208
+ FROM
209
+ jsonb_each(row_to_json(NEW.*)::jsonb)
210
+ WHERE NOT jsonb_build_object(key, value) <@ row_to_json(OLD.*)::jsonb);
211
+ FOR k IN (SELECT key FROM jsonb_each(changes))
212
+ LOOP
213
+ IF jsonb_typeof(changes->k) = 'object' THEN
214
+ changes = jsonb_set(changes, ARRAY[k], to_jsonb(changes->>k));
215
+ END IF;
216
+ END LOOP;
217
+ END;
218
+ END IF;
219
+
220
+ changes = changes - 'log_data';
221
+
222
+ IF columns IS NOT NULL THEN
223
+ changes = logidze_filter_keys(changes, columns, include_columns);
224
+ END IF;
225
+
226
+ IF changes = '{}' THEN
227
+ RETURN NEW; -- pass
228
+ END IF;
229
+
230
+ new_v := (log_data#>>'{h,-1,v}')::int + 1;
231
+
232
+ size := jsonb_array_length(log_data->'h');
233
+ version := logidze_version(new_v, changes, ts);
234
+
235
+ IF (
236
+ debounce_time IS NOT NULL AND
237
+ (version->>'ts')::bigint - (log_data#>'{h,-1,ts}')::text::bigint <= debounce_time
238
+ ) THEN
239
+ -- merge new version with the previous one
240
+ new_v := (log_data#>>'{h,-1,v}')::int;
241
+ version := logidze_version(new_v, (log_data#>'{h,-1,c}')::jsonb || changes, ts);
242
+ -- remove the previous version from log
243
+ log_data := jsonb_set(
244
+ log_data,
245
+ '{h}',
246
+ (log_data->'h') - (size - 1)
247
+ );
248
+ END IF;
249
+
250
+ log_data := jsonb_set(
251
+ log_data,
252
+ ARRAY['h', size::text],
253
+ version,
254
+ true
255
+ );
256
+
257
+ log_data := jsonb_set(
258
+ log_data,
259
+ '{v}',
260
+ to_jsonb(new_v)
261
+ );
262
+
263
+ IF history_limit IS NOT NULL AND history_limit <= size THEN
264
+ log_data := logidze_compact_history(log_data, size - history_limit + 1);
265
+ END IF;
266
+
267
+ NEW.log_data := log_data;
268
+ END IF;
269
+
270
+ RETURN NEW; -- result
271
+ EXCEPTION
272
+ WHEN OTHERS THEN
273
+ GET STACKED DIAGNOSTICS err_sqlstate = RETURNED_SQLSTATE,
274
+ err_message = MESSAGE_TEXT,
275
+ err_detail = PG_EXCEPTION_DETAIL,
276
+ err_hint = PG_EXCEPTION_HINT,
277
+ err_context = PG_EXCEPTION_CONTEXT,
278
+ err_schema_name = SCHEMA_NAME,
279
+ err_table_name = TABLE_NAME;
280
+ err_jsonb := jsonb_build_object(
281
+ 'returned_sqlstate', err_sqlstate,
282
+ 'message_text', err_message,
283
+ 'pg_exception_detail', err_detail,
284
+ 'pg_exception_hint', err_hint,
285
+ 'pg_exception_context', err_context,
286
+ 'schema_name', err_schema_name,
287
+ 'table_name', err_table_name
288
+ );
289
+ err_captured = logidze_capture_exception(err_jsonb);
290
+ IF err_captured THEN
291
+ return NEW;
292
+ ELSE
293
+ RAISE;
294
+ END IF;
295
+ END;
296
+ $body$
297
+ LANGUAGE plpgsql;
298
+
299
+ CREATE OR REPLACE FUNCTION logidze_logger_after() RETURNS TRIGGER AS $body$
300
+ -- version: 4
301
+
302
+
303
+ DECLARE
304
+ changes jsonb;
305
+ version jsonb;
306
+ full_snapshot boolean;
307
+ log_data jsonb;
308
+ new_v integer;
309
+ size integer;
310
+ history_limit integer;
311
+ debounce_time integer;
312
+ current_version integer;
313
+ k text;
314
+ iterator integer;
315
+ item record;
316
+ columns text[];
317
+ include_columns boolean;
318
+ ts timestamp with time zone;
319
+ ts_column text;
320
+ err_sqlstate text;
321
+ err_message text;
322
+ err_detail text;
323
+ err_hint text;
324
+ err_context text;
325
+ err_table_name text;
326
+ err_schema_name text;
327
+ err_jsonb jsonb;
328
+ err_captured boolean;
329
+ BEGIN
330
+ ts_column := NULLIF(TG_ARGV[1], 'null');
331
+ columns := NULLIF(TG_ARGV[2], 'null');
332
+ include_columns := NULLIF(TG_ARGV[3], 'null');
333
+
334
+ IF NEW.log_data is NULL OR NEW.log_data = '{}'::jsonb
335
+ THEN
336
+ IF columns IS NOT NULL THEN
337
+ log_data = logidze_snapshot(to_jsonb(NEW.*), ts_column, columns, include_columns);
338
+ ELSE
339
+ log_data = logidze_snapshot(to_jsonb(NEW.*), ts_column);
340
+ END IF;
341
+
342
+ IF log_data#>>'{h, -1, c}' != '{}' THEN
343
+ NEW.log_data := log_data;
344
+ END IF;
345
+
346
+ ELSE
347
+
348
+ IF TG_OP = 'UPDATE' AND (to_jsonb(NEW.*) = to_jsonb(OLD.*)) THEN
349
+ RETURN NULL;
350
+ END IF;
351
+
352
+ history_limit := NULLIF(TG_ARGV[0], 'null');
353
+ debounce_time := NULLIF(TG_ARGV[4], 'null');
354
+
355
+ log_data := NEW.log_data;
356
+
357
+ current_version := (log_data->>'v')::int;
358
+
359
+ IF ts_column IS NULL THEN
360
+ ts := statement_timestamp();
361
+ ELSEIF TG_OP = 'UPDATE' THEN
362
+ ts := (to_jsonb(NEW.*) ->> ts_column)::timestamp with time zone;
363
+ IF ts IS NULL OR ts = (to_jsonb(OLD.*) ->> ts_column)::timestamp with time zone THEN
364
+ ts := statement_timestamp();
365
+ END IF;
366
+ ELSEIF TG_OP = 'INSERT' THEN
367
+ ts := (to_jsonb(NEW.*) ->> ts_column)::timestamp with time zone;
368
+ IF ts IS NULL OR (extract(epoch from ts) * 1000)::bigint = (NEW.log_data #>> '{h,-1,ts}')::bigint THEN
369
+ ts := statement_timestamp();
370
+ END IF;
371
+ END IF;
372
+
373
+ full_snapshot := (coalesce(current_setting('logidze.full_snapshot', true), '') = 'on') OR (TG_OP = 'INSERT');
374
+
375
+ IF current_version < (log_data#>>'{h,-1,v}')::int THEN
376
+ iterator := 0;
377
+ FOR item in SELECT * FROM jsonb_array_elements(log_data->'h')
378
+ LOOP
379
+ IF (item.value->>'v')::int > current_version THEN
380
+ log_data := jsonb_set(
381
+ log_data,
382
+ '{h}',
383
+ (log_data->'h') - iterator
384
+ );
385
+ END IF;
386
+ iterator := iterator + 1;
387
+ END LOOP;
388
+ END IF;
389
+
390
+ changes := '{}';
391
+
392
+ IF full_snapshot THEN
393
+ BEGIN
394
+ changes = hstore_to_jsonb_loose(hstore(NEW.*));
395
+ EXCEPTION
396
+ WHEN NUMERIC_VALUE_OUT_OF_RANGE THEN
397
+ changes = row_to_json(NEW.*)::jsonb;
398
+ FOR k IN (SELECT key FROM jsonb_each(changes))
399
+ LOOP
400
+ IF jsonb_typeof(changes->k) = 'object' THEN
401
+ changes = jsonb_set(changes, ARRAY[k], to_jsonb(changes->>k));
402
+ END IF;
403
+ END LOOP;
404
+ END;
405
+ ELSE
406
+ BEGIN
407
+ changes = hstore_to_jsonb_loose(
408
+ hstore(NEW.*) - hstore(OLD.*)
409
+ );
410
+ EXCEPTION
411
+ WHEN NUMERIC_VALUE_OUT_OF_RANGE THEN
412
+ changes = (SELECT
413
+ COALESCE(json_object_agg(key, value), '{}')::jsonb
414
+ FROM
415
+ jsonb_each(row_to_json(NEW.*)::jsonb)
416
+ WHERE NOT jsonb_build_object(key, value) <@ row_to_json(OLD.*)::jsonb);
417
+ FOR k IN (SELECT key FROM jsonb_each(changes))
418
+ LOOP
419
+ IF jsonb_typeof(changes->k) = 'object' THEN
420
+ changes = jsonb_set(changes, ARRAY[k], to_jsonb(changes->>k));
421
+ END IF;
422
+ END LOOP;
423
+ END;
424
+ END IF;
425
+
426
+ changes = changes - 'log_data';
427
+
428
+ IF columns IS NOT NULL THEN
429
+ changes = logidze_filter_keys(changes, columns, include_columns);
430
+ END IF;
431
+
432
+ IF changes = '{}' THEN
433
+ RETURN NULL;
434
+ END IF;
435
+
436
+ new_v := (log_data#>>'{h,-1,v}')::int + 1;
437
+
438
+ size := jsonb_array_length(log_data->'h');
439
+ version := logidze_version(new_v, changes, ts);
440
+
441
+ IF (
442
+ debounce_time IS NOT NULL AND
443
+ (version->>'ts')::bigint - (log_data#>'{h,-1,ts}')::text::bigint <= debounce_time
444
+ ) THEN
445
+ -- merge new version with the previous one
446
+ new_v := (log_data#>>'{h,-1,v}')::int;
447
+ version := logidze_version(new_v, (log_data#>'{h,-1,c}')::jsonb || changes, ts);
448
+ -- remove the previous version from log
449
+ log_data := jsonb_set(
450
+ log_data,
451
+ '{h}',
452
+ (log_data->'h') - (size - 1)
453
+ );
454
+ END IF;
455
+
456
+ log_data := jsonb_set(
457
+ log_data,
458
+ ARRAY['h', size::text],
459
+ version,
460
+ true
461
+ );
462
+
463
+ log_data := jsonb_set(
464
+ log_data,
465
+ '{v}',
466
+ to_jsonb(new_v)
467
+ );
468
+
469
+ IF history_limit IS NOT NULL AND history_limit <= size THEN
470
+ log_data := logidze_compact_history(log_data, size - history_limit + 1);
471
+ END IF;
472
+
473
+ NEW.log_data := log_data;
474
+ END IF;
475
+
476
+ EXECUTE format('UPDATE %I.%I SET "log_data" = $1 WHERE ctid = %L', TG_TABLE_SCHEMA, TG_TABLE_NAME, NEW.CTID) USING NEW.log_data;
477
+ RETURN NULL;
478
+ EXCEPTION
479
+ WHEN OTHERS THEN
480
+ GET STACKED DIAGNOSTICS err_sqlstate = RETURNED_SQLSTATE,
481
+ err_message = MESSAGE_TEXT,
482
+ err_detail = PG_EXCEPTION_DETAIL,
483
+ err_hint = PG_EXCEPTION_HINT,
484
+ err_context = PG_EXCEPTION_CONTEXT,
485
+ err_schema_name = SCHEMA_NAME,
486
+ err_table_name = TABLE_NAME;
487
+ err_jsonb := jsonb_build_object(
488
+ 'returned_sqlstate', err_sqlstate,
489
+ 'message_text', err_message,
490
+ 'pg_exception_detail', err_detail,
491
+ 'pg_exception_hint', err_hint,
492
+ 'pg_exception_context', err_context,
493
+ 'schema_name', err_schema_name,
494
+ 'table_name', err_table_name
495
+ );
496
+ err_captured = logidze_capture_exception(err_jsonb);
497
+ IF err_captured THEN
498
+ return NEW;
499
+ ELSE
500
+ RAISE;
501
+ END IF;
502
+ END;
503
+ $body$
504
+ LANGUAGE plpgsql;
505
+
506
+
507
+ CREATE OR REPLACE FUNCTION logidze_snapshot(item jsonb, ts_column text DEFAULT NULL, columns text[] DEFAULT NULL, include_columns boolean DEFAULT false) RETURNS jsonb AS $body$
508
+ -- version: 3
509
+ DECLARE
510
+ ts timestamp with time zone;
511
+ k text;
512
+ BEGIN
513
+ item = item - 'log_data';
514
+ IF ts_column IS NULL THEN
515
+ ts := statement_timestamp();
516
+ ELSE
517
+ ts := coalesce((item->>ts_column)::timestamp with time zone, statement_timestamp());
518
+ END IF;
519
+
520
+ IF columns IS NOT NULL THEN
521
+ item := logidze_filter_keys(item, columns, include_columns);
522
+ END IF;
523
+
524
+ FOR k IN (SELECT key FROM jsonb_each(item))
525
+ LOOP
526
+ IF jsonb_typeof(item->k) = 'object' THEN
527
+ item := jsonb_set(item, ARRAY[k], to_jsonb(item->>k));
528
+ END IF;
529
+ END LOOP;
530
+
531
+ return json_build_object(
532
+ 'v', 1,
533
+ 'h', jsonb_build_array(
534
+ logidze_version(1, item, ts)
535
+ )
536
+ );
537
+ END;
538
+ $body$
539
+ LANGUAGE plpgsql;
540
+
541
+ CREATE OR REPLACE FUNCTION logidze_version(v bigint, data jsonb, ts timestamp with time zone) RETURNS jsonb AS $body$
542
+ -- version: 2
543
+ DECLARE
544
+ buf jsonb;
545
+ BEGIN
546
+ data = data - 'log_data';
547
+ buf := jsonb_build_object(
548
+ 'ts',
549
+ (extract(epoch from ts) * 1000)::bigint,
550
+ 'v',
551
+ v,
552
+ 'c',
553
+ data
554
+ );
555
+ IF coalesce(current_setting('logidze.meta', true), '') <> '' THEN
556
+ buf := jsonb_insert(buf, '{m}', current_setting('logidze.meta')::jsonb);
557
+ END IF;
558
+ RETURN buf;
559
+ END;
560
+ $body$
561
+ LANGUAGE plpgsql;
562
+
563
+ SQL
564
+ end
565
+ end
566
+
567
+ def down
568
+ execute <<~SQL
569
+ DROP FUNCTION IF EXISTS logidze_capture_exception(jsonb) CASCADE;
570
+ DROP FUNCTION IF EXISTS logidze_compact_history(jsonb, integer) CASCADE;
571
+ DROP FUNCTION IF EXISTS logidze_filter_keys(jsonb, text[], boolean) CASCADE;
572
+ DROP FUNCTION IF EXISTS logidze_logger() CASCADE;
573
+ DROP FUNCTION IF EXISTS logidze_logger_after() CASCADE;
574
+ DROP FUNCTION IF EXISTS logidze_snapshot(jsonb, text, text[], boolean) CASCADE;
575
+ DROP FUNCTION IF EXISTS logidze_version(bigint, jsonb, timestamp with time zone) CASCADE;
576
+ SQL
577
+ end
@@ -0,0 +1,5 @@
1
+ class EnableHstore < ActiveRecord::Migration[8.0]
2
+ def change
3
+ enable_extension :hstore
4
+ end
5
+ end
@@ -2,6 +2,7 @@ module Panda
2
2
  module Core
3
3
  class Configuration
4
4
  attr_accessor :user_class,
5
+ :user_identity_class,
5
6
  :storage_provider,
6
7
  :cache_store,
7
8
  :parent_controller,
@@ -11,13 +12,15 @@ module Panda
11
12
  :session_token_cookie
12
13
 
13
14
  def initialize
15
+ @user_class = "Panda::Core::User"
16
+ @user_identity_class = "Panda::Core::UserIdentity"
14
17
  @storage_provider = :active_storage
15
18
  @cache_store = :memory_store
16
19
  @parent_controller = "ActionController::API"
17
20
  @parent_mailer = "ActionMailer::Base"
18
21
  @mailer_sender = "support@example.com"
19
22
  @mailer_default_url_options = {host: "localhost:3000"}
20
- @session_token_cookie = :session_token
23
+ @session_token_cookie = :panda_session
21
24
  end
22
25
  end
23
26
 
@@ -7,10 +7,13 @@ require "dry-configurable"
7
7
  require "faraday"
8
8
  require "faraday/multipart"
9
9
  require "faraday/retry"
10
+ require "fx"
10
11
  require "image_processing"
11
12
  require "importmap-rails"
13
+ require "logidze"
12
14
  require "lookbook"
13
15
  require "omniauth"
16
+ require "omniauth/rails_csrf_protection"
14
17
  require "propshaft"
15
18
  require "redis"
16
19
  require "silencer"
@@ -2,5 +2,7 @@ require "rails/railtie"
2
2
 
3
3
  module Panda
4
4
  module Core
5
+ class Railtie < Rails::Railtie
6
+ end
5
7
  end
6
8
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Panda
4
4
  module Core
5
- VERSION = "0.1.11"
5
+ VERSION = "0.1.12"
6
6
  end
7
7
  end