evt-message_store-postgres 0.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []