evt-message_store-postgres 0.1.0.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/database/clear-events-table.sh +40 -0
  3. data/database/extensions.sql +1 -0
  4. data/database/functions/category.sql +10 -0
  5. data/database/functions/stream-version.sql +13 -0
  6. data/database/functions/write-event.sql +55 -0
  7. data/database/indexes/events-category-global-position.sql +1 -0
  8. data/database/indexes/events-category.sql +1 -0
  9. data/database/indexes/events-id.sql +1 -0
  10. data/database/indexes/events-stream-name-position-uniq.sql +1 -0
  11. data/database/indexes/events-stream-name.sql +1 -0
  12. data/database/install.sh +103 -0
  13. data/database/list-events.sh +52 -0
  14. data/database/table/events-table.sql +19 -0
  15. data/database/test/write-event-expected-version.sql +1 -0
  16. data/database/test/write-event.sql +1 -0
  17. data/database/uninstall.sh +60 -0
  18. data/lib/message_store/postgres.rb +24 -0
  19. data/lib/message_store/postgres/controls.rb +6 -0
  20. data/lib/message_store/postgres/controls/category.rb +34 -0
  21. data/lib/message_store/postgres/controls/message_data.rb +7 -0
  22. data/lib/message_store/postgres/controls/put.rb +26 -0
  23. data/lib/message_store/postgres/controls/stream_name.rb +22 -0
  24. data/lib/message_store/postgres/get.rb +91 -0
  25. data/lib/message_store/postgres/get/last.rb +111 -0
  26. data/lib/message_store/postgres/get/last/select_statement.rb +47 -0
  27. data/lib/message_store/postgres/get/select_statement.rb +88 -0
  28. data/lib/message_store/postgres/log.rb +11 -0
  29. data/lib/message_store/postgres/put.rb +145 -0
  30. data/lib/message_store/postgres/read.rb +12 -0
  31. data/lib/message_store/postgres/read/iterator.rb +17 -0
  32. data/lib/message_store/postgres/session.rb +128 -0
  33. data/lib/message_store/postgres/settings.rb +30 -0
  34. data/lib/message_store/postgres/stream_name.rb +52 -0
  35. data/lib/message_store/postgres/write.rb +46 -0
  36. data/scripts/evt-pg-create-db +7 -0
  37. data/scripts/evt-pg-delete-db +7 -0
  38. data/scripts/evt-pg-list-events +7 -0
  39. data/scripts/evt-pg-recreate-db +11 -0
  40. data/scripts/scripts_init.rb +12 -0
  41. metadata +156 -0
@@ -0,0 +1,12 @@
1
+ module MessageStore
2
+ module Postgres
3
+ class Read
4
+ include MessageStore::Read
5
+
6
+ def configure(session: nil)
7
+ Iterator.configure(self, stream_name, position: position)
8
+ Get.configure(self.iterator, batch_size: batch_size, session: session)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module MessageStore
2
+ module Postgres
3
+ class Read
4
+ class Iterator
5
+ include MessageStore::Read::Iterator
6
+
7
+ def last_position
8
+ unless MessageStore::Postgres::StreamName.category?(stream_name)
9
+ batch.last.position
10
+ else
11
+ batch.last.global_position
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,128 @@
1
+ module MessageStore
2
+ module Postgres
3
+ class Session
4
+ include Log::Dependency
5
+
6
+ def self.settings
7
+ Settings.names
8
+ end
9
+
10
+ settings.each do |s|
11
+ setting s
12
+ end
13
+
14
+ attr_accessor :connection
15
+
16
+ def self.build(settings: nil)
17
+ new.tap do |instance|
18
+ settings ||= Settings.instance
19
+ settings.set(instance)
20
+ end
21
+ end
22
+
23
+ def self.configure(receiver, session: nil, attr_name: nil)
24
+ attr_name ||= :session
25
+
26
+ instance = session || build
27
+ receiver.public_send "#{attr_name}=", instance
28
+ instance
29
+ end
30
+
31
+ def connect
32
+ logger.trace { "Connecting to database" }
33
+
34
+ if connected?
35
+ logger.debug { "Already connected. A new connection will not be built." }
36
+ return
37
+ end
38
+
39
+ logger.debug { "Not connected. A new connection will be built." }
40
+ connection = self.class.build_connection(self)
41
+ self.connection = connection
42
+
43
+ logger.debug { "Connected to database" }
44
+
45
+ connection
46
+ end
47
+
48
+ def self.build_connection(instance)
49
+ settings = instance.settings
50
+ logger.trace { "Building new connection to database (Settings: #{LogText.settings(settings).inspect})" }
51
+
52
+ connection = PG::Connection.open(settings)
53
+ connection.type_map_for_results = PG::BasicTypeMapForResults.new(connection)
54
+
55
+ logger.trace { "Built new connection to database (Settings: #{LogText.settings(settings).inspect})" }
56
+
57
+ connection
58
+ end
59
+
60
+ def connected?
61
+ !connection.nil? && connection.status == PG::CONNECTION_OK
62
+ end
63
+ alias :open? :connected?
64
+
65
+ def close
66
+ connection.close
67
+ connection = nil
68
+ end
69
+
70
+ def reset
71
+ connection.reset
72
+ end
73
+
74
+ def settings
75
+ settings = {}
76
+ self.class.settings.each do |s|
77
+ val = public_send(s)
78
+ settings[s] = val unless val.nil?
79
+ end
80
+ settings
81
+ end
82
+
83
+ def execute(statement, params=nil)
84
+ logger.trace { "Executing statement" }
85
+ logger.trace(tag: :data) { statement }
86
+ logger.trace(tag: :data) { params.pretty_inspect }
87
+
88
+ unless connected?
89
+ connect
90
+ end
91
+
92
+ if params.nil?
93
+ connection.exec(statement).tap do
94
+ logger.debug { "Executed statement" }
95
+ end
96
+ else
97
+ connection.exec_params(statement, params).tap do
98
+ logger.debug { "Executed statement with params" }
99
+ end
100
+ end
101
+ end
102
+
103
+ def transaction(&blk)
104
+ unless connected?
105
+ connect
106
+ end
107
+
108
+ connection.transaction(&blk)
109
+ end
110
+
111
+ def self.logger
112
+ @logger ||= Log.get self
113
+ end
114
+
115
+ module LogText
116
+ def self.settings(settings)
117
+ s = settings.dup
118
+
119
+ if s.has_key?(:password)
120
+ s[:password] = '(hidden)'
121
+ end
122
+
123
+ s
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,30 @@
1
+ module MessageStore
2
+ module Postgres
3
+ class Settings < ::Settings
4
+ def self.instance
5
+ @instance ||= build
6
+ end
7
+
8
+ def self.data_source
9
+ 'settings/message_store_postgres.json'
10
+ end
11
+
12
+ def self.names
13
+ [
14
+ :dbname,
15
+ :host,
16
+ :hostaddr,
17
+ :port,
18
+ :user,
19
+ :password,
20
+ :connect_timeout,
21
+ :options,
22
+ :sslmode,
23
+ :krbsrvname,
24
+ :gsslib,
25
+ :service
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,52 @@
1
+ module MessageStore
2
+ module Postgres
3
+ module StreamName
4
+ def self.stream_name(category_name, id=nil, type: nil, types: nil)
5
+ types = Array(types)
6
+ types.unshift(type) unless type.nil?
7
+
8
+ type_list = nil
9
+ type_list = types.join('+') unless types.empty?
10
+
11
+ stream_name = category_name
12
+ stream_name = "#{stream_name}:#{type_list}" unless type_list.nil?
13
+ stream_name = "#{stream_name}-#{id}" unless id.nil?
14
+
15
+ stream_name
16
+ end
17
+
18
+ def self.get_id(stream_name)
19
+ id = stream_name.partition('-').last
20
+ id.empty? ? nil : id
21
+ end
22
+
23
+ def self.get_category(stream_name)
24
+ stream_name.split('-').first
25
+ end
26
+
27
+ def self.category?(stream_name)
28
+ !stream_name.include?('-')
29
+ end
30
+
31
+ def self.get_type_list(stream_name)
32
+ type = stream_name.split(':').last.split('-').first
33
+
34
+ return nil if stream_name.start_with?(type)
35
+
36
+ type
37
+ end
38
+
39
+ def self.get_types(stream_name)
40
+ type_list = get_type_list(stream_name)
41
+
42
+ return [] if type_list.nil?
43
+
44
+ type_list.split('+')
45
+ end
46
+
47
+ def self.get_entity_name(stream_name)
48
+ get_category(stream_name).split(':').first
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,46 @@
1
+ module MessageStore
2
+ module Postgres
3
+ class Write
4
+ include MessageStore::Write
5
+
6
+ dependency :put
7
+
8
+ def configure(session: nil)
9
+ Put.configure(self, session: session)
10
+ end
11
+
12
+ def write(batch, stream_name, expected_version: nil)
13
+ logger.trace(tag: :write) { "Writing batch (Stream Name: #{stream_name}, Number of Messages: #{batch.length}, Expected Version: #{expected_version.inspect})" }
14
+
15
+ unless expected_version.nil?
16
+ expected_version = ExpectedVersion.canonize(expected_version)
17
+ end
18
+
19
+ last_position = nil
20
+ put.session.transaction do
21
+ batch.each do |message_data|
22
+ last_position = write_message_data(message_data, stream_name, expected_version: expected_version)
23
+
24
+ unless expected_version.nil?
25
+ expected_version += 1
26
+ end
27
+ end
28
+ end
29
+
30
+ logger.debug(tag: :write) { "Wrote batch (Stream Name: #{stream_name}, Number of Messages: #{batch.length}, Expected Version: #{expected_version.inspect})" }
31
+
32
+ last_position
33
+ end
34
+
35
+ def write_message_data(message_data, stream_name, expected_version: nil)
36
+ logger.trace(tag: :write) { "Writing message data (Stream Name: #{stream_name}, Type: #{message_data.type}, Expected Version: #{expected_version.inspect})" }
37
+ logger.trace(tags: [:data, :message_data, :write]) { message_data.pretty_inspect }
38
+
39
+ put.(message_data, stream_name, expected_version: expected_version).tap do
40
+ logger.debug(tag: :write) { "Wrote message data (Stream Name: #{stream_name}, Type: #{message_data.type}, Expected Version: #{expected_version.inspect})" }
41
+ logger.debug(tags: [:data, :message_data, :write]) { message_data.pretty_inspect }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path '../database', __dir__
4
+ script_filename = 'install.sh'
5
+ script_filepath = File.join root, script_filename
6
+
7
+ system script_filepath
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path '../database', __dir__
4
+ script_filename = 'uninstall.sh'
5
+ script_filepath = File.join root, script_filename
6
+
7
+ system script_filepath
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path '../database', __dir__
4
+ script_filename = 'list-events.sh'
5
+ script_filepath = File.join root, script_filename
6
+
7
+ system script_filepath
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path '../database', __dir__
4
+
5
+ script_filename = 'uninstall.sh'
6
+ script_filepath = File.join root, script_filename
7
+ system script_filepath
8
+
9
+ script_filename = 'install.sh'
10
+ script_filepath = File.join root, script_filename
11
+ system script_filepath
@@ -0,0 +1,12 @@
1
+ ENV['CONSOLE_DEVICE'] ||= 'stdout'
2
+ ENV['LOG_LEVEL'] ||= '_min'
3
+
4
+ puts RUBY_DESCRIPTION
5
+
6
+ init_file = File.expand_path('../init.rb', __dir__)
7
+ if File.exist?(init_file)
8
+ require_relative '../init'
9
+ end
10
+
11
+ require 'event_source/postgres'
12
+ require 'event_source/postgres/database'
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evt-message_store-postgres
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - The Eventide Project
8
+ autorequire:
9
+ bindir: scripts
10
+ cert_chain: []
11
+ date: 2017-05-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: evt-message_store
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: evt-log
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: evt-settings
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: test_bench
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: " "
84
+ email: opensource@eventide-project.org
85
+ executables:
86
+ - evt-pg-create-db
87
+ - evt-pg-delete-db
88
+ - evt-pg-list-events
89
+ - evt-pg-recreate-db
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - database/clear-events-table.sh
94
+ - database/extensions.sql
95
+ - database/functions/category.sql
96
+ - database/functions/stream-version.sql
97
+ - database/functions/write-event.sql
98
+ - database/indexes/events-category-global-position.sql
99
+ - database/indexes/events-category.sql
100
+ - database/indexes/events-id.sql
101
+ - database/indexes/events-stream-name-position-uniq.sql
102
+ - database/indexes/events-stream-name.sql
103
+ - database/install.sh
104
+ - database/list-events.sh
105
+ - database/table/events-table.sql
106
+ - database/test/write-event-expected-version.sql
107
+ - database/test/write-event.sql
108
+ - database/uninstall.sh
109
+ - lib/message_store/postgres.rb
110
+ - lib/message_store/postgres/controls.rb
111
+ - lib/message_store/postgres/controls/category.rb
112
+ - lib/message_store/postgres/controls/message_data.rb
113
+ - lib/message_store/postgres/controls/put.rb
114
+ - lib/message_store/postgres/controls/stream_name.rb
115
+ - lib/message_store/postgres/get.rb
116
+ - lib/message_store/postgres/get/last.rb
117
+ - lib/message_store/postgres/get/last/select_statement.rb
118
+ - lib/message_store/postgres/get/select_statement.rb
119
+ - lib/message_store/postgres/log.rb
120
+ - lib/message_store/postgres/put.rb
121
+ - lib/message_store/postgres/read.rb
122
+ - lib/message_store/postgres/read/iterator.rb
123
+ - lib/message_store/postgres/session.rb
124
+ - lib/message_store/postgres/settings.rb
125
+ - lib/message_store/postgres/stream_name.rb
126
+ - lib/message_store/postgres/write.rb
127
+ - scripts/evt-pg-create-db
128
+ - scripts/evt-pg-delete-db
129
+ - scripts/evt-pg-list-events
130
+ - scripts/evt-pg-recreate-db
131
+ - scripts/scripts_init.rb
132
+ homepage: https://github.com/eventide-project/message-store-postgres
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 2.4.0
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.6.11
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Event source client for PostgreSQL
156
+ test_files: []