nexia_event_store 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 115b1bb8a9f14f799f97b9038cf9ae1ed8a9aacd
4
- data.tar.gz: b1e31142a7fda060e2f4b2cd1a81a3c0cc8dc652
3
+ metadata.gz: 810f954e899ec5777b6f4b57431d9739734f8519
4
+ data.tar.gz: b0fc4fae467b95e007d317894206618d9ada5899
5
5
  SHA512:
6
- metadata.gz: 46eac58f16227a98364a52a33c0c9d8f91c1dcbfd8047c52373e4a0d0ea131a6f16324a5ccd54b7c21d2781f6903b2c312dbba32ad951b55bdb1fe4cf2d72671
7
- data.tar.gz: 1f6c50f1f137024ac13b1a683b68815ea34e7f833555a66624b9bb885f2917b96708d8f06749af111164756bd0822da0c16de56269703e914f7ea937a92f3385
6
+ metadata.gz: 74d45ebf5fe97fdb52e067b17885be10159e2a94200671b1fa106a75e90e6428e33a362ded5a481c92d762981c5e9cba56f60126960bc34216845ccea3306045
7
+ data.tar.gz: 58ed1ef36e12724c2ee1ea689af1eeb3d85164677c800aadac21a2ac11b20d92b09e590a05162595b1f44cc35afb2c2d95b71dacd2689e5dd3ed1c7587e60170
data/db/database.yml CHANGED
@@ -35,8 +35,8 @@ test:
35
35
  postgres:
36
36
  <<: *postgres
37
37
  database: history_store
38
- schema: event_store_gem_test
38
+ schema: es_test
39
39
  vertica:
40
40
  <<: *vertica
41
41
  database: history_store
42
- schema: event_store_gem_test
42
+ schema: es_test
@@ -0,0 +1,10 @@
1
+ require 'event_store'
2
+ Sequel.migration do
3
+ no_transaction
4
+ change do
5
+ idx_name = "#{EventStore.schema}_#{EventStore.table_name}_aggregate_id_occurred_at_name_idx"
6
+ alter_table((EventStore.schema + "__" + EventStore.table_name).to_sym) do
7
+ add_index([:aggregate_id, :occurred_at, :fully_qualified_name], name: idx_name, concurrently: true)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,68 @@
1
+ require 'event_store'
2
+ Sequel.migration do
3
+ no_transaction
4
+
5
+ event_store_table = (EventStore.schema + "__" + EventStore.table_name).to_sym
6
+ lookup_table = (EventStore.schema + "__" + EventStore.lookup_table_name).to_sym
7
+
8
+ event_store_table_name = event_store_table.to_s.gsub(/__/, '.')
9
+ lookup_table_name = lookup_table.to_s.gsub(/__/, '.')
10
+
11
+ up do
12
+ create_table(lookup_table) do
13
+ primary_key :id
14
+ String :fully_qualified_name, null: false, unique: true
15
+ index :fully_qualified_name
16
+ end
17
+
18
+ run <<-"EOSQL"
19
+ INSERT INTO #{lookup_table_name} (fully_qualified_name)
20
+ SELECT DISTINCT fully_qualified_name FROM #{event_store_table_name}
21
+ EOSQL
22
+
23
+ alter_table(event_store_table) do
24
+ idx_name = "aggregate_id_occurred_at_fqn_id_idx"
25
+ add_foreign_key :fully_qualified_name_id, lookup_table, key: :id, null: false
26
+ add_index([:aggregate_id, :occurred_at, :fully_qualified_name_id], name: idx_name)
27
+ end
28
+
29
+ run <<-"EOSQL"
30
+ UPDATE #{event_store_table_name} AS event_store
31
+ SET fully_qualified_name_id = lookup.id
32
+ FROM #{lookup_table_name} AS lookup
33
+ WHERE lookup.fully_qualified_name = event_store.fully_qualified_name
34
+ EOSQL
35
+
36
+ alter_table(event_store_table) do
37
+ old_idx_name = "#{EventStore.schema}_#{EventStore.table_name}_aggregate_id_occurred_at_name_idx"
38
+ drop_index [:aggregate_id, :occurred_at, :fully_qualified_name], name: old_idx_name
39
+ drop_index :fully_qualified_name
40
+ drop_column :fully_qualified_name
41
+ end
42
+ end
43
+
44
+ down do
45
+ alter_table(event_store_table) do
46
+ idx_name = "#{EventStore.schema}_#{EventStore.table_name}_aggregate_id_occurred_at_name_idx"
47
+ old_idx_name = "aggregate_id_occurred_at_fqn_id_idx"
48
+
49
+ add_column :fully_qualified_name, String
50
+ add_index :fully_qualified_name
51
+ add_index([:aggregate_id, :occurred_at, :fully_qualified_name], name: idx_name)
52
+ drop_index old_idx_name
53
+ end
54
+
55
+ run <<-"EOSQL"
56
+ UPDATE #{event_store_table_name} AS event_store
57
+ SET fully_qualified_name = lookup.fully_qualified_name
58
+ FROM #{lookup_table_name} AS lookup
59
+ WHERE lookup.id = event_store.fully_qualified_name_id
60
+ EOSQL
61
+
62
+ alter_table(event_store_table) do
63
+ drop_foreign_key :fully_qualified_name_id
64
+ end
65
+
66
+ drop_table(lookup_table)
67
+ end
68
+ end
@@ -7,7 +7,10 @@ module EventStore
7
7
  def initialize aggregate
8
8
  @aggregate = aggregate
9
9
  @id = @aggregate.id
10
- @event_table = EventStore.fully_qualified_table
10
+ @event_table_alias = "events"
11
+ @event_table = "#{EventStore.schema}__#{EventStore.table_name}".to_sym
12
+ @aliased_event_table = "#{event_table}___#{@event_table_alias}".to_sym
13
+ @names_table = EventStore.fully_qualified_names_table
11
14
  end
12
15
 
13
16
  def append(raw_events)
@@ -17,20 +20,38 @@ module EventStore
17
20
  event
18
21
  end
19
22
 
20
- inserted_ids = events.multi_insert(prepared_events, return: :primary_key)
21
- prepared_events.each_with_index do |event, idx|
22
- event[:id] = inserted_ids[idx]
23
+ event_table = EventStore.db.from(@event_table)
24
+ prepared_events.each do |event|
25
+ event_hash = event.dup.reject! { |k,v| k == :fully_qualified_name }
26
+
27
+ begin
28
+ id = event_table.insert(event_hash)
29
+ rescue Sequel::NotNullConstraintViolation
30
+ fully_qualified_names.insert(fully_qualified_name: event[:fully_qualified_name])
31
+ id = event_table.insert(event_hash)
32
+ end
33
+
34
+ event[:id] = id
23
35
  end
24
36
 
25
37
  yield(prepared_events) if block_given?
26
38
  end
27
39
 
40
+ def fully_qualified_names
41
+ @fully_qualified_name_query ||= EventStore.db.from(@names_table)
42
+ end
43
+
28
44
  def events
29
- @events_query ||= EventStore.db.from(@event_table).where(:aggregate_id => @id.to_s).order(:id)
45
+ @events_query ||= EventStore.db.from(@aliased_event_table) \
46
+ .where(:aggregate_id => @id.to_s) \
47
+ .join(@names_table, id: :fully_qualified_name_id) \
48
+ .order("#{@event_table_alias}__id".to_sym) \
49
+ .select_all(:events).select_append(:fully_qualified_name)
30
50
  end
31
51
 
32
52
  def events_from(event_id, max = nil)
33
- events.limit(max).where{ id >= event_id.to_i }.all.map do |event|
53
+ # note: this depends on the events table being aliased to "events" above.
54
+ events.limit(max).where{events__id >= event_id.to_i }.all.map do |event|
34
55
  event[:serialized_event] = EventStore.unescape_bytea(event[:serialized_event])
35
56
  event
36
57
  end
@@ -69,18 +90,19 @@ module EventStore
69
90
  end
70
91
 
71
92
  def delete_events!
72
- events.delete
93
+ EventStore.db.from(@event_table).where(:aggregate_id => @id.to_s).delete
73
94
  end
74
95
 
75
96
  private
76
97
 
77
98
  def prepare_event(raw_event)
78
99
  raise ArgumentError.new("Cannot Append a Nil Event") unless raw_event
79
- { :aggregate_id => raw_event.aggregate_id,
80
- :occurred_at => Time.parse(raw_event.occurred_at.to_s).utc, #to_s truncates microseconds, which brake Time equality
81
- :serialized_event => EventStore.escape_bytea(raw_event.serialized_event),
82
- :fully_qualified_name => raw_event.fully_qualified_name,
83
- :sub_key => raw_event.sub_key
100
+ { :aggregate_id => raw_event.aggregate_id,
101
+ :occurred_at => Time.parse(raw_event.occurred_at.to_s).utc, #to_s truncates microseconds, which brake Time equality
102
+ :serialized_event => EventStore.escape_bytea(raw_event.serialized_event),
103
+ :fully_qualified_name_id => EventStore.db.from(@names_table).where(fully_qualified_name: raw_event.fully_qualified_name).select(:id),
104
+ :fully_qualified_name => raw_event.fully_qualified_name,
105
+ :sub_key => raw_event.sub_key
84
106
  }
85
107
  end
86
108
 
@@ -1,3 +1,3 @@
1
1
  module EventStore
2
- VERSION = '0.6.1'
2
+ VERSION = '0.7.0'
3
3
  end
data/lib/event_store.rb CHANGED
@@ -64,10 +64,18 @@ module EventStore
64
64
  @table_name ||= raw_db_config['table_name']
65
65
  end
66
66
 
67
+ def self.lookup_table_name
68
+ @lookup_table_name ||= raw_db_config['lookup_table_name'] || "fully_qualified_names"
69
+ end
70
+
67
71
  def self.fully_qualified_table
68
72
  @fully_qualified_table ||= Sequel.lit "#{schema}.#{table_name}"
69
73
  end
70
74
 
75
+ def self.fully_qualified_names_table
76
+ @fully_qualified_names_table ||= Sequel.lit "#{schema}.#{lookup_table_name}"
77
+ end
78
+
71
79
  def self.connected?
72
80
  !!EventStore.db
73
81
  end
@@ -52,7 +52,7 @@ describe EventStore::Client do
52
52
  raw_stream = es_client.new(AGGREGATE_ID_ONE, :device).raw_event_stream
53
53
  raw_event = raw_stream.first
54
54
  expect(raw_event.class).to eq(Hash)
55
- expect(raw_event.keys).to eq([:id, :version, :aggregate_id, :fully_qualified_name, :occurred_at, :serialized_event, :sub_key])
55
+ expect(raw_event.keys.to_set).to eq(Set.new([:id, :version, :aggregate_id, :fully_qualified_name, :fully_qualified_name_id, :occurred_at, :serialized_event, :sub_key]))
56
56
  end
57
57
 
58
58
  it 'should be empty for aggregates without events' do
@@ -108,14 +108,14 @@ describe EventStore::Client do
108
108
  client = es_client.new("any_device", :device)
109
109
  serialized_event = serialized_event_data_terminated_by_null
110
110
  event = EventStore::Event.new("any_device", @event_time, 'terminated_by_null_event', "zone_number", serialized_event)
111
- client.append([event])
112
- hex_from_db = EventStore.db.from(EventStore.fully_qualified_table).where(fully_qualified_name: 'terminated_by_null_event').first[:serialized_event]
111
+ retval = client.append([event])
112
+ hex_from_db = EventStore.db.from(EventStore.fully_qualified_table).order(:id).last[:serialized_event]
113
+
113
114
  expect(hex_from_db).to eql(EventStore.escape_bytea(serialized_event))
114
115
  end
115
116
  end
116
117
  end
117
118
 
118
-
119
119
  describe '#raw_event_streams_from_event_id' do
120
120
  subject { es_client.new(AGGREGATE_ID_ONE, :device) }
121
121
  let(:raw_stream) { subject.raw_event_stream }
@@ -243,7 +243,7 @@ describe EventStore::Client do
243
243
  let(:client) { es_client.new(AGGREGATE_ID_ONE, :device) }
244
244
 
245
245
  it 'should return the last event in the event stream' do
246
- last_event = EventStore.db.from(client.event_table).where(aggregate_id: AGGREGATE_ID_ONE).order(:id).last
246
+ last_event = client.raw_event_stream.last
247
247
  peek = client.peek
248
248
  expect(peek.fully_qualified_name).to eq(last_event[:fully_qualified_name])
249
249
  expect(peek.event_id).to eq(last_event[:id])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexia_event_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Saieg, John Colvin
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-04-29 00:00:00.000000000 Z
12
+ date: 2015-05-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -231,6 +231,8 @@ files:
231
231
  - db/migrations/001_create_event_store_events.rb
232
232
  - db/pg_migrations/001_create_event_store_events.rb
233
233
  - db/pg_migrations/002_create_event_store_events.rb
234
+ - db/pg_migrations/003_add_agg_id_occurred_fqn_idx_to_event_store.rb
235
+ - db/pg_migrations/004_add_fqn_lookup_table_to_event_store.rb
234
236
  - db/setup_db_user.sql
235
237
  - event_store.gemspec
236
238
  - lib/event_store.rb