message-db-temp (empty) → 0.0.1.0
raw patch · 123 files changed
+4009/−0 lines, 123 filesdep +basedep +bytestringdep +containers
Dependencies added: base, bytestring, containers, exceptions, postgres-options, postgresql-simple, retry, safe-exceptions, text, tmp-postgres, typed-process
Files
- ChangeLog.md +4/−0
- LICENSE +7/−0
- README.md +2/−0
- message-db-temp.cabal +104/−0
- official-message-db-upstream/database/benchmark.sh +62/−0
- official-message-db-upstream/database/benchmark_get.sql +24/−0
- official-message-db-upstream/database/benchmark_write.sql +24/−0
- official-message-db-upstream/database/clear-messages.sh +26/−0
- official-message-db-upstream/database/extensions/pgcrypto.sql +1/−0
- official-message-db-upstream/database/functions/acquire-lock.sql +24/−0
- official-message-db-upstream/database/functions/cardinal-id.sql +18/−0
- official-message-db-upstream/database/functions/category.sql +10/−0
- official-message-db-upstream/database/functions/get-category-messages.sql +133/−0
- official-message-db-upstream/database/functions/get-last-stream-message.sql +37/−0
- official-message-db-upstream/database/functions/get-stream-messages.sql +75/−0
- official-message-db-upstream/database/functions/hash-64.sql +13/−0
- official-message-db-upstream/database/functions/id.sql +18/−0
- official-message-db-upstream/database/functions/is-category.sql +14/−0
- official-message-db-upstream/database/functions/message-store-version.sql +8/−0
- official-message-db-upstream/database/functions/stream-version.sql +19/−0
- official-message-db-upstream/database/functions/write-message.sql +73/−0
- official-message-db-upstream/database/indexes/messages-category.sql +7/−0
- official-message-db-upstream/database/indexes/messages-id.sql +5/−0
- official-message-db-upstream/database/indexes/messages-stream.sql +6/−0
- official-message-db-upstream/database/install-functions.sh +79/−0
- official-message-db-upstream/database/install-indexes.sh +33/−0
- official-message-db-upstream/database/install-privileges.sh +39/−0
- official-message-db-upstream/database/install-views.sh +42/−0
- official-message-db-upstream/database/install.sh +117/−0
- official-message-db-upstream/database/print-category-type-summary.sh +44/−0
- official-message-db-upstream/database/print-message-store-version.sh +32/−0
- official-message-db-upstream/database/print-messages.sh +44/−0
- official-message-db-upstream/database/print-stream-summary.sh +44/−0
- official-message-db-upstream/database/print-stream-type-summary.sh +44/−0
- official-message-db-upstream/database/print-type-category-summary.sh +44/−0
- official-message-db-upstream/database/print-type-stream-summary.sh +44/−0
- official-message-db-upstream/database/print-type-summary.sh +44/−0
- official-message-db-upstream/database/privileges/functions.sql +14/−0
- official-message-db-upstream/database/privileges/schema.sql +1/−0
- official-message-db-upstream/database/privileges/sequence.sql +1/−0
- official-message-db-upstream/database/privileges/table.sql +1/−0
- official-message-db-upstream/database/privileges/views.sql +6/−0
- official-message-db-upstream/database/roles/message-store.sql +7/−0
- official-message-db-upstream/database/schema/message-store.sql +1/−0
- official-message-db-upstream/database/tables/messages.sql +12/−0
- official-message-db-upstream/database/types/message.sql +15/−0
- official-message-db-upstream/database/uninstall.sh +53/−0
- official-message-db-upstream/database/update.sh +18/−0
- official-message-db-upstream/database/update/1.0.0.sh +187/−0
- official-message-db-upstream/database/update/1.2.2.sh +65/−0
- official-message-db-upstream/database/views/category-type-summary.sql +32/−0
- official-message-db-upstream/database/views/stream-summary.sql +28/−0
- official-message-db-upstream/database/views/stream-type-summary.sql +32/−0
- official-message-db-upstream/database/views/type-category-summary.sql +32/−0
- official-message-db-upstream/database/views/type-stream-summary.sql +32/−0
- official-message-db-upstream/database/views/type-summary.sql +28/−0
- official-message-db-upstream/database/write-test-message.sh +63/−0
- official-message-db-upstream/recreate-database.sh +4/−0
- official-message-db-upstream/test.sh +75/−0
- official-message-db-upstream/test/_controls.sh +6/−0
- official-message-db-upstream/test/_controls/category.sh +6/−0
- official-message-db-upstream/test/_controls/compound-id-stream-name.sh +6/−0
- official-message-db-upstream/test/_controls/id.sh +4/−0
- official-message-db-upstream/test/_controls/stream-name.sh +5/−0
- official-message-db-upstream/test/_controls/write-message-correlated.sh +13/−0
- official-message-db-upstream/test/_controls/write-message.sh +5/−0
- official-message-db-upstream/test/_query-plan/get-category-messages-consumer-group-correlated.sh +49/−0
- official-message-db-upstream/test/_query-plan/get-category-messages-correlated.sh +49/−0
- official-message-db-upstream/test/_query-plan/get-category-messages.sh +41/−0
- official-message-db-upstream/test/_query-plan/get-stream-messages-correlated.sh +43/−0
- official-message-db-upstream/test/_query-plan/get-stream-messages.sh +36/−0
- official-message-db-upstream/test/acquire-lock.sh +21/−0
- official-message-db-upstream/test/cardinal-id/category.sh +21/−0
- official-message-db-upstream/test/cardinal-id/stream-name-with-compound-id.sh +21/−0
- official-message-db-upstream/test/cardinal-id/stream-name-with-single-id.sh +21/−0
- official-message-db-upstream/test/category/category.sh +21/−0
- official-message-db-upstream/test/category/stream-name.sh +21/−0
- official-message-db-upstream/test/get-category-messages/batch_size/limited.sh +36/−0
- official-message-db-upstream/test/get-category-messages/batch_size/unlimited.sh +36/−0
- official-message-db-upstream/test/get-category-messages/condition/condition-correlated.sh +44/−0
- official-message-db-upstream/test/get-category-messages/condition/condition.sh +36/−0
- official-message-db-upstream/test/get-category-messages/condition/error-deactivated.sh +31/−0
- official-message-db-upstream/test/get-category-messages/condition/error-not-activated.sh +31/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/consumer-group.sh +96/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/correlated.sh +95/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/error/group-member-equal-to-group-size.sh +25/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/error/group-member-greater-than-group-size.sh +25/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/error/group-member-too-small.sh +25/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/error/group-size-too-small.sh +25/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/error/missing-group-member.sh +25/−0
- official-message-db-upstream/test/get-category-messages/consumer-group/error/missing-group-size.sh +25/−0
- official-message-db-upstream/test/get-category-messages/correlated/correlated.sh +44/−0
- official-message-db-upstream/test/get-category-messages/correlated/error-stream-name.sh +36/−0
- official-message-db-upstream/test/get-category-messages/error-not-category.sh +27/−0
- official-message-db-upstream/test/get-category-messages/get-category-messages.sh +36/−0
- official-message-db-upstream/test/get-last-stream-message/category.sh +31/−0
- official-message-db-upstream/test/get-last-stream-message/stream-name.sh +31/−0
- official-message-db-upstream/test/get-stream-messages/batch_size/limited.sh +31/−0
- official-message-db-upstream/test/get-stream-messages/batch_size/unlimited.sh +31/−0
- official-message-db-upstream/test/get-stream-messages/condition/condition.sh +31/−0
- official-message-db-upstream/test/get-stream-messages/condition/error-deactivated.sh +31/−0
- official-message-db-upstream/test/get-stream-messages/condition/error-not-activated.sh +31/−0
- official-message-db-upstream/test/get-stream-messages/error-not-stream-name.sh +27/−0
- official-message-db-upstream/test/get-stream-messages/get-stream-messages.sh +31/−0
- official-message-db-upstream/test/hash-64.sh +21/−0
- official-message-db-upstream/test/id/category.sh +21/−0
- official-message-db-upstream/test/id/compound-id/stream-name.sh +21/−0
- official-message-db-upstream/test/id/stream-name.sh +21/−0
- official-message-db-upstream/test/is_category/category.sh +21/−0
- official-message-db-upstream/test/is_category/stream-name.sh +21/−0
- official-message-db-upstream/test/message-store-version.sh +14/−0
- official-message-db-upstream/test/reports/category-type-summary.sh +21/−0
- official-message-db-upstream/test/reports/messages.sh +24/−0
- official-message-db-upstream/test/reports/stream-summary.sh +26/−0
- official-message-db-upstream/test/reports/stream-type-summary.sh +27/−0
- official-message-db-upstream/test/reports/type-category-summary.sh +21/−0
- official-message-db-upstream/test/reports/type-stream-summary.sh +21/−0
- official-message-db-upstream/test/reports/type-summary.sh +21/−0
- official-message-db-upstream/test/stream-version/stream-version.sh +31/−0
- official-message-db-upstream/test/write-message/expected-version-error.sh +34/−0
- official-message-db-upstream/test/write-message/expected-version.sh +31/−0
- official-message-db-upstream/test/write-message/write-message.sh +30/−0
- src/MessageDb/Temp.hs +149/−0
+ ChangeLog.md view
@@ -0,0 +1,4 @@+# Changelog for message-db-temp++## 0.0.1.0+- Initial release
+ LICENSE view
@@ -0,0 +1,7 @@+Copyright © 2022 David Burkett++Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,2 @@+# message-db-temp +Library built on top of `tmp-postgres` that initializes the database with the message-db scripts found in this [repo](https://github.com/message-db/message-db).
+ message-db-temp.cabal view
@@ -0,0 +1,104 @@+cabal-version: 3.0++name: message-db-temp+version: 0.0.1.0++synopsis: Temporary message-db for integration testing+description: See the readme on github for me info: https://github.com/Disco-Dave/message-db/tree/main/message-db-temp#readme++build-type: Simple+category: database, eventsourcing, eventstore, testing+homepage: https://github.com/Disco-Dave/message-db+bug-reports:https://github.com/Disco-Dave/message-db/issues++author: David Burkett+maintainer: David Burkett++copyright: 2022 David Burkett+license: MIT+license-file: LICENSE++extra-source-files:+ README.md+ ChangeLog.md++data-files: + , official-message-db-upstream/**/*.sh+ , official-message-db-upstream/**/*.sql++source-repository head+ type: git+ location: https://github.com/Disco-Dave/message-db.git++common shared+ default-language: Haskell2010++ default-extensions:+ AllowAmbiguousTypes+ DeriveFunctor+ DeriveGeneric+ DerivingVia+ FlexibleContexts+ GeneralizedNewtypeDeriving+ LambdaCase+ NamedFieldPuns+ NumericUnderscores+ OverloadedStrings+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StrictData+ TypeApplications++ ghc-options:+ -Weverything + -Wno-all-missed-specialisations + -Wno-identities+ -Wno-implicit-prelude + -Wno-missed-specialisations + -Wno-missing-deriving-strategies+ -Wno-missing-exported-signatures + -Wno-missing-import-lists + -Wno-missing-local-signatures + -Wno-monomorphism-restriction + -Wno-safe + -Wno-unsafe ++ if impl(ghc >= 8.10)+ ghc-options:+ -Wno-missing-safe-haskell-mode+ -Wno-prepositive-qualified-module++ if impl(ghc >= 9.2)+ ghc-options:+ -Wno-missing-kind-signatures++ build-depends:+ , base >=4.7 && <5++ autogen-modules:+ Paths_message_db_temp+ + other-modules:+ Paths_message_db_temp+++library+ import: shared++ hs-source-dirs: src++ exposed-modules:+ MessageDb.Temp++ build-depends:+ , bytestring >=0.10 && <0.12+ , containers >=0.6 && <0.7+ , exceptions >=0.10 && <0.11+ , postgres-options >=0.2 && <0.3+ , postgresql-simple >=0.6 && <0.7+ , retry >=0.8 && <0.10+ , safe-exceptions >=0.1 && <0.2+ , text >=1.2 && <2.1+ , tmp-postgres >=1.34 && <1.35+ , typed-process >=0.2 && <0.3
+ official-message-db-upstream/database/benchmark.sh view
@@ -0,0 +1,62 @@+#!/usr/bin/env bash++set -u++uuid=$(echo $(uuidgen) | tr '[:upper:]' '[:lower:]')++stream_name="testStream-$uuid"+if [ ! -z ${STREAM_NAME+x} ]; then+ stream_name=$STREAM_NAME+fi++cycles=1000+if [ ! -z ${CYCLES+x} ]; then+ cycles=$CYCLES+fi++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++base=$(script_dir)++echo+echo "Benchmark $cycles cycles (Stream Name: $stream_name)"+echo "= = ="+echo++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=message_store+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"+echo++echo "Installing benchmark scripts"+echo++psql $database -q -f $base/benchmark_write.sql+psql $database -q -f $base/benchmark_get.sql++echo+echo "Benchmarking write"+echo "- - -"+echo++psql $database -U message_store -c "EXPLAIN ANALYZE SELECT benchmark_write('$stream_name'::varchar, $cycles::int);"++echo++echo+echo "Benchmarking get"+echo "- - -"+echo++psql $database -U message_store -c "EXPLAIN ANALYZE SELECT benchmark_get('$stream_name'::varchar, $cycles::int);"++echo "= = ="+echo "Done"+echo
+ official-message-db-upstream/database/benchmark_get.sql view
@@ -0,0 +1,24 @@+CREATE OR REPLACE FUNCTION benchmark_get(+ stream_name varchar,+ cycles int DEFAULT 1000+)+RETURNS void+AS $$+BEGIN+ RAISE NOTICE '» benchmark_get';+ RAISE NOTICE 'stream_name: %', benchmark_get.stream_name;+ RAISE NOTICE 'cycles: %', benchmark_get.cycles;++ FOR i IN 1..cycles LOOP+ IF current_setting('message_store.debug_benchmark', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '%', i;+ END IF;++ PERFORM get_stream_messages(stream_name, "position" => i - 1, batch_size => 1);+ END LOOP;+END;+$$ LANGUAGE plpgsql+VOLATILE;+++
+ official-message-db-upstream/database/benchmark_write.sql view
@@ -0,0 +1,24 @@+CREATE OR REPLACE FUNCTION benchmark_write(+ stream_name varchar,+ cycles int DEFAULT 1000+)+RETURNS void+AS $$+BEGIN+ RAISE NOTICE '» benchmark_write';+ RAISE NOTICE 'stream_name: %', benchmark_write.stream_name;+ RAISE NOTICE 'cycles: %', benchmark_write.cycles;++ FOR i IN 1..cycles LOOP+ IF current_setting('message_store.debug_benchmark', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '%', i;+ END IF;++ PERFORM write_message(gen_random_uuid()::varchar, stream_name::varchar, 'SomeType'::varchar, '{"attribute": "some value"}'::jsonb, '{"metaAttribute": "some meta value", "correlationStreamName": "someCorrelation-123"}'::jsonb);+ END LOOP;+END;+$$ LANGUAGE plpgsql+VOLATILE;+++
+ official-message-db-upstream/database/clear-messages.sh view
@@ -0,0 +1,26 @@+#!/usr/bin/env bash++set -e++echo+echo "Clearing Messages Table"+echo "= = ="+echo++default_name=message_store++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++echo++psql $database -q -c "TRUNCATE message_store.messages RESTART IDENTITY;"++echo "= = ="+echo "Done Clearing Messages Table"+echo
+ official-message-db-upstream/database/extensions/pgcrypto.sql view
@@ -0,0 +1,1 @@+CREATE EXTENSION IF NOT EXISTS pgcrypto;
+ official-message-db-upstream/database/functions/acquire-lock.sql view
@@ -0,0 +1,24 @@+CREATE OR REPLACE FUNCTION message_store.acquire_lock(+ stream_name varchar+)+RETURNS bigint+AS $$+DECLARE+ _category varchar;+ _category_name_hash bigint;+BEGIN+ _category := category(acquire_lock.stream_name);+ _category_name_hash := hash_64(_category);+ PERFORM pg_advisory_xact_lock(_category_name_hash);++ IF current_setting('message_store.debug_write', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '» acquire_lock';+ RAISE NOTICE 'stream_name: %', acquire_lock.stream_name;+ RAISE NOTICE '_category: %', _category;+ RAISE NOTICE '_category_name_hash: %', _category_name_hash;+ END IF;++ RETURN _category_name_hash;+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/functions/cardinal-id.sql view
@@ -0,0 +1,18 @@+CREATE OR REPLACE FUNCTION message_store.cardinal_id(+ stream_name varchar+)+RETURNS varchar+AS $$+DECLARE+ _id varchar;+BEGIN+ _id := id(cardinal_id.stream_name);++ IF _id IS NULL THEN+ RETURN NULL;+ END IF;++ RETURN SPLIT_PART(_id, '+', 1);+END;+$$ LANGUAGE plpgsql+IMMUTABLE;
+ official-message-db-upstream/database/functions/category.sql view
@@ -0,0 +1,10 @@+CREATE OR REPLACE FUNCTION message_store.category(+ stream_name varchar+)+RETURNS varchar+AS $$+BEGIN+ RETURN SPLIT_PART(category.stream_name, '-', 1);+END;+$$ LANGUAGE plpgsql+IMMUTABLE;
+ official-message-db-upstream/database/functions/get-category-messages.sql view
@@ -0,0 +1,133 @@+CREATE OR REPLACE FUNCTION message_store.get_category_messages(+ category varchar,+ "position" bigint DEFAULT 1,+ batch_size bigint DEFAULT 1000,+ correlation varchar DEFAULT NULL,+ consumer_group_member bigint DEFAULT NULL,+ consumer_group_size bigint DEFAULT NULL,+ condition varchar DEFAULT NULL+)+RETURNS SETOF message_store.message+AS $$+DECLARE+ _command text;+BEGIN+ IF NOT is_category(get_category_messages.category) THEN+ RAISE EXCEPTION+ 'Must be a category: %',+ get_category_messages.category;+ END IF;++ position := COALESCE(position, 1);+ batch_size := COALESCE(batch_size, 1000);++ _command := '+ SELECT+ id::varchar,+ stream_name::varchar,+ type::varchar,+ position::bigint,+ global_position::bigint,+ data::varchar,+ metadata::varchar,+ time::timestamp+ FROM+ messages+ WHERE+ category(stream_name) = $1 AND+ global_position >= $2';++ IF get_category_messages.correlation IS NOT NULL THEN+ IF position('-' IN get_category_messages.correlation) > 0 THEN+ RAISE EXCEPTION+ 'Correlation must be a category (Correlation: %)',+ get_category_messages.correlation;+ END IF;++ _command := _command || ' AND+ category(metadata->>''correlationStreamName'') = $4';+ END IF;++ IF (get_category_messages.consumer_group_member IS NOT NULL AND+ get_category_messages.consumer_group_size IS NULL) OR+ (get_category_messages.consumer_group_member IS NULL AND+ get_category_messages.consumer_group_size IS NOT NULL) THEN++ RAISE EXCEPTION+ 'Consumer group member and size must be specified (Consumer Group Member: %, Consumer Group Size: %)',+ get_category_messages.consumer_group_member,+ get_category_messages.consumer_group_size;+ END IF;++ IF get_category_messages.consumer_group_member IS NOT NULL AND+ get_category_messages.consumer_group_size IS NOT NULL THEN++ IF get_category_messages.consumer_group_size < 1 THEN+ RAISE EXCEPTION+ 'Consumer group size must not be less than 1 (Consumer Group Member: %, Consumer Group Size: %)',+ get_category_messages.consumer_group_member,+ get_category_messages.consumer_group_size;+ END IF;++ IF get_category_messages.consumer_group_member < 0 THEN+ RAISE EXCEPTION+ 'Consumer group member must not be less than 0 (Consumer Group Member: %, Consumer Group Size: %)',+ get_category_messages.consumer_group_member,+ get_category_messages.consumer_group_size;+ END IF;++ IF get_category_messages.consumer_group_member >= get_category_messages.consumer_group_size THEN+ RAISE EXCEPTION+ 'Consumer group member must be less than the group size (Consumer Group Member: %, Consumer Group Size: %)',+ get_category_messages.consumer_group_member,+ get_category_messages.consumer_group_size;+ END IF;++ _command := _command || ' AND+ MOD(@hash_64(cardinal_id(stream_name)), $6) = $5';+ END IF;++ IF get_category_messages.condition IS NOT NULL THEN+ IF current_setting('message_store.sql_condition', true) IS NULL OR+ current_setting('message_store.sql_condition', true) = 'off' THEN+ RAISE EXCEPTION+ 'Retrieval with SQL condition is not activated';+ END IF;++ _command := _command || ' AND+ (%s)';+ _command := format(_command, get_category_messages.condition);+ END IF;++ _command := _command || '+ ORDER BY+ global_position ASC';++ IF get_category_messages.batch_size != -1 THEN+ _command := _command || '+ LIMIT+ $3';+ END IF;++ IF current_setting('message_store.debug_get', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '» get_category_messages';+ RAISE NOTICE 'category ($1): %', get_category_messages.category;+ RAISE NOTICE 'position ($2): %', get_category_messages.position;+ RAISE NOTICE 'batch_size ($3): %', get_category_messages.batch_size;+ RAISE NOTICE 'correlation ($4): %', get_category_messages.correlation;+ RAISE NOTICE 'consumer_group_member ($5): %', get_category_messages.consumer_group_member;+ RAISE NOTICE 'consumer_group_size ($6): %', get_category_messages.consumer_group_size;+ RAISE NOTICE 'condition: %', get_category_messages.condition;+ RAISE NOTICE 'Generated Command: %', _command;+ END IF;++ RETURN QUERY EXECUTE _command USING+ get_category_messages.category,+ get_category_messages.position,+ get_category_messages.batch_size,+ get_category_messages.correlation,+ get_category_messages.consumer_group_member,+ get_category_messages.consumer_group_size::smallint;+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/functions/get-last-stream-message.sql view
@@ -0,0 +1,37 @@+CREATE OR REPLACE FUNCTION message_store.get_last_stream_message(+ stream_name varchar+)+RETURNS SETOF message_store.message+AS $$+DECLARE+ _command text;+BEGIN+ _command := '+ SELECT+ id::varchar,+ stream_name::varchar,+ type::varchar,+ position::bigint,+ global_position::bigint,+ data::varchar,+ metadata::varchar,+ time::timestamp+ FROM+ messages+ WHERE+ stream_name = $1+ ORDER BY+ position DESC+ LIMIT+ 1';++ IF current_setting('message_store.debug_get', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '» get_last_message';+ RAISE NOTICE 'stream_name ($1): %', get_last_stream_message.stream_name;+ RAISE NOTICE 'Generated Command: %', _command;+ END IF;++ RETURN QUERY EXECUTE _command USING get_last_stream_message.stream_name;+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/functions/get-stream-messages.sql view
@@ -0,0 +1,75 @@+CREATE OR REPLACE FUNCTION message_store.get_stream_messages(+ stream_name varchar,+ "position" bigint DEFAULT 0,+ batch_size bigint DEFAULT 1000,+ condition varchar DEFAULT NULL+)+RETURNS SETOF message_store.message+AS $$+DECLARE+ _command text;+ _setting text;+BEGIN+ IF is_category(get_stream_messages.stream_name) THEN+ RAISE EXCEPTION+ 'Must be a stream name: %',+ get_stream_messages.stream_name;+ END IF;++ position := COALESCE(position, 0);+ batch_size := COALESCE(batch_size, 1000);++ _command := '+ SELECT+ id::varchar,+ stream_name::varchar,+ type::varchar,+ position::bigint,+ global_position::bigint,+ data::varchar,+ metadata::varchar,+ time::timestamp+ FROM+ messages+ WHERE+ stream_name = $1 AND+ position >= $2';++ IF get_stream_messages.condition IS NOT NULL THEN+ IF current_setting('message_store.sql_condition', true) IS NULL OR+ current_setting('message_store.sql_condition', true) = 'off' THEN+ RAISE EXCEPTION+ 'Retrieval with SQL condition is not activated';+ END IF;++ _command := _command || ' AND+ (%s)';+ _command := format(_command, get_stream_messages.condition);+ END IF;++ _command := _command || '+ ORDER BY+ position ASC';++ IF get_stream_messages.batch_size != -1 THEN+ _command := _command || '+ LIMIT+ $3';+ END IF;++ IF current_setting('message_store.debug_get', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '» get_stream_messages';+ RAISE NOTICE 'stream_name ($1): %', get_stream_messages.stream_name;+ RAISE NOTICE 'position ($2): %', get_stream_messages.position;+ RAISE NOTICE 'batch_size ($3): %', get_stream_messages.batch_size;+ RAISE NOTICE 'condition ($4): %', get_stream_messages.condition;+ RAISE NOTICE 'Generated Command: %', _command;+ END IF;++ RETURN QUERY EXECUTE _command USING+ get_stream_messages.stream_name,+ get_stream_messages.position,+ get_stream_messages.batch_size;+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/functions/hash-64.sql view
@@ -0,0 +1,13 @@+CREATE OR REPLACE FUNCTION message_store.hash_64(+ value varchar+)+RETURNS bigint+AS $$+DECLARE+ _hash bigint;+BEGIN+ SELECT left('x' || md5(hash_64.value), 17)::bit(64)::bigint INTO _hash;+ return _hash;+END;+$$ LANGUAGE plpgsql+IMMUTABLE;
+ official-message-db-upstream/database/functions/id.sql view
@@ -0,0 +1,18 @@+CREATE OR REPLACE FUNCTION message_store.id(+ stream_name varchar+)+RETURNS varchar+AS $$+DECLARE+ _id_separator_position integer;+BEGIN+ _id_separator_position := STRPOS(id.stream_name, '-');++ IF _id_separator_position = 0 THEN+ RETURN NULL;+ END IF;++ RETURN SUBSTRING(id.stream_name, _id_separator_position + 1);+END;+$$ LANGUAGE plpgsql+IMMUTABLE;
+ official-message-db-upstream/database/functions/is-category.sql view
@@ -0,0 +1,14 @@+CREATE OR REPLACE FUNCTION message_store.is_category(+ stream_name varchar+)+RETURNS boolean+AS $$+BEGIN+ IF NOT STRPOS(is_category.stream_name, '-') = 0 THEN+ RETURN FALSE;+ END IF;++ RETURN TRUE;+END;+$$ LANGUAGE plpgsql+IMMUTABLE;
+ official-message-db-upstream/database/functions/message-store-version.sql view
@@ -0,0 +1,8 @@+CREATE OR REPLACE FUNCTION message_store.message_store_version()+RETURNS varchar+AS $$+BEGIN+ RETURN '1.2.6';+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/functions/stream-version.sql view
@@ -0,0 +1,19 @@+CREATE OR REPLACE FUNCTION message_store.stream_version(+ stream_name varchar+)+RETURNS bigint+AS $$+DECLARE+ _stream_version bigint;+BEGIN+ SELECT+ max(position) into _stream_version+ FROM+ messages+ WHERE+ messages.stream_name = stream_version.stream_name;++ RETURN _stream_version;+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/functions/write-message.sql view
@@ -0,0 +1,73 @@+CREATE OR REPLACE FUNCTION message_store.write_message(+ id varchar,+ stream_name varchar,+ "type" varchar,+ data jsonb,+ metadata jsonb DEFAULT NULL,+ expected_version bigint DEFAULT NULL+)+RETURNS bigint+AS $$+DECLARE+ _message_id uuid;+ _stream_version bigint;+ _next_position bigint;+BEGIN+ PERFORM acquire_lock(write_message.stream_name);++ _stream_version := stream_version(write_message.stream_name);++ IF _stream_version IS NULL THEN+ _stream_version := -1;+ END IF;++ IF write_message.expected_version IS NOT NULL THEN+ IF write_message.expected_version != _stream_version THEN+ RAISE EXCEPTION+ 'Wrong expected version: % (Stream: %, Stream Version: %)',+ write_message.expected_version,+ write_message.stream_name,+ _stream_version;+ END IF;+ END IF;++ _next_position := _stream_version + 1;++ _message_id = uuid(write_message.id);++ INSERT INTO messages+ (+ id,+ stream_name,+ position,+ type,+ data,+ metadata+ )+ VALUES+ (+ _message_id,+ write_message.stream_name,+ _next_position,+ write_message.type,+ write_message.data,+ write_message.metadata+ )+ ;++ IF current_setting('message_store.debug_write', true) = 'on' OR current_setting('message_store.debug', true) = 'on' THEN+ RAISE NOTICE '» write_message';+ RAISE NOTICE 'id ($1): %', write_message.id;+ RAISE NOTICE 'stream_name ($2): %', write_message.stream_name;+ RAISE NOTICE 'type ($3): %', write_message.type;+ RAISE NOTICE 'data ($4): %', write_message.data;+ RAISE NOTICE 'metadata ($5): %', write_message.metadata;+ RAISE NOTICE 'expected_version ($6): %', write_message.expected_version;+ RAISE NOTICE '_stream_version: %', _stream_version;+ RAISE NOTICE '_next_position: %', _next_position;+ END IF;++ RETURN _next_position;+END;+$$ LANGUAGE plpgsql+VOLATILE;
+ official-message-db-upstream/database/indexes/messages-category.sql view
@@ -0,0 +1,7 @@+DROP INDEX IF EXISTS message_store.messages_category;++CREATE INDEX messages_category ON message_store.messages (+ message_store.category(stream_name),+ global_position,+ message_store.category(metadata->>'correlationStreamName')+);
+ official-message-db-upstream/database/indexes/messages-id.sql view
@@ -0,0 +1,5 @@+DROP INDEX IF EXISTS message_store.messages_id;++CREATE UNIQUE INDEX messages_id ON message_store.messages (+ id+);
+ official-message-db-upstream/database/indexes/messages-stream.sql view
@@ -0,0 +1,6 @@+DROP INDEX IF EXISTS messages_stream;++CREATE UNIQUE INDEX messages_stream ON message_store.messages (+ stream_name,+ position+);
+ official-message-db-upstream/database/install-functions.sh view
@@ -0,0 +1,79 @@+#!/usr/bin/env bash++set -e++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++function create-types {+ if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "(DATABASE_NAME is not set. Using: $database.)"+ else+ database=$DATABASE_NAME+ fi++ base=$(script_dir)++ echo "» message type"+ psql $database -q -f $base/types/message.sql+}++function create-functions {+ if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "(DATABASE_NAME is not set. Using: $database.)"+ else+ database=$DATABASE_NAME+ fi++ base=$(script_dir)++ echo "» message_store_version function"+ psql $database -q -f $base/functions/message-store-version.sql++ echo "» hash_64 function"+ psql $database -q -f $base/functions/hash-64.sql++ echo "» acquire_lock function"+ psql $database -q -f $base/functions/acquire-lock.sql++ echo "» category function"+ psql $database -q -f $base/functions/category.sql++ echo "» is_category function"+ psql $database -q -f $base/functions/is-category.sql++ echo "» id function"+ psql $database -q -f $base/functions/id.sql++ echo "» cardinal_id function"+ psql $database -q -f $base/functions/cardinal-id.sql++ echo "» stream_version function"+ psql $database -q -f $base/functions/stream-version.sql++ echo "» write_message function"+ psql $database -q -f $base/functions/write-message.sql++ echo "» get_stream_messages function"+ psql $database -q -f $base/functions/get-stream-messages.sql++ echo "» get_category_messages function"+ psql $database -q -f $base/functions/get-category-messages.sql++ echo "» get_last_stream_message function"+ psql $database -q -f $base/functions/get-last-stream-message.sql+}++echo "Creating Types"+echo "- - -"+create-types+echo++echo "Creating Functions"+echo "- - -"+create-functions+echo
+ official-message-db-upstream/database/install-indexes.sh view
@@ -0,0 +1,33 @@+#!/usr/bin/env bash++set -e++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++function create-indexes {+ if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "(DATABASE_NAME is not set. Using: $database.)"+ else+ database=$DATABASE_NAME+ fi++ base=$(script_dir)++ echo "» messages_id index"+ psql $database -q -f $base/indexes/messages-id.sql++ echo "» messages_stream index"+ psql $database -q -f $base/indexes/messages-stream.sql++ echo "» messages_category index"+ psql $database -q -f $base/indexes/messages-category.sql+}++echo "Creating Indexes"+echo "- - -"+create-indexes+echo
+ official-message-db-upstream/database/install-privileges.sh view
@@ -0,0 +1,39 @@+#!/usr/bin/env bash++set -e++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++function grant-privileges {+ if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "(DATABASE_NAME is not set. Using: $database.)"+ else+ database=$DATABASE_NAME+ fi++ base=$(script_dir)++ echo "» schema privileges"+ psql $database -q -f $base/privileges/schema.sql++ echo "» messages table privileges"+ psql $database -q -f $base/privileges/table.sql++ echo "» sequence privileges"+ psql $database -q -f $base/privileges/sequence.sql++ echo "» functions privileges"+ psql $database -q -f $base/privileges/functions.sql++ echo "» views privileges"+ psql $database -q -f $base/privileges/views.sql+}++echo "Granting Privileges"+echo "- - -"+grant-privileges+echo
+ official-message-db-upstream/database/install-views.sh view
@@ -0,0 +1,42 @@+#!/usr/bin/env bash++set -e++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++function create-views {+ if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "(DATABASE_NAME is not set. Using: $database.)"+ else+ database=$DATABASE_NAME+ fi++ base=$(script_dir)++ echo "» stream_summary view"+ psql $database -q -f $base/views/stream-summary.sql++ echo "» type_summary view"+ psql $database -q -f $base/views/type-summary.sql++ echo "» stream_type_summary view"+ psql $database -q -f $base/views/stream-type-summary.sql++ echo "» type_stream_summary view"+ psql $database -q -f $base/views/type-stream-summary.sql++ echo "» category_type_summary view"+ psql $database -q -f $base/views/category-type-summary.sql++ echo "» type_category_summary view"+ psql $database -q -f $base/views/type-category-summary.sql+}++echo "Creating Views"+echo "- - -"+create-views+echo
+ official-message-db-upstream/database/install.sh view
@@ -0,0 +1,117 @@+#!/usr/bin/env bash++set -e++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++base=$(script_dir)++echo+echo "Installing Database"+echo "Version: $(cat $base/VERSION.txt)"+echo "= = ="++if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "DATABASE_NAME is not set. Using: $database."+ export DATABASE_NAME=$database+else+ database=$DATABASE_NAME+fi+++if [ -z ${CREATE_DATABASE+x} ]; then+ CREATE_DATABASE="on"+fi++create_database=true+if [ "$CREATE_DATABASE" = "off" ] ; then+ create_database=false+fi+++if [ -z ${PGOPTIONS+x} ]; then+ export PGOPTIONS='-c client_min_messages=warning'+fi++function create-user {+ base=$(script_dir)++ echo "» message_store role"+ psql postgres -q -f $base/roles/message-store.sql+}++function create-database {+ echo "» $database database"+ createdb $database+}++function create-schema {+ echo "» message_store schema"+ psql $database -q -f $base/schema/message-store.sql+}++function create-extensions {+ base=$(script_dir)++ echo "» pgcrypto extension"+ psql $database -q -f $base/extensions/pgcrypto.sql+}++function create-table {+ base=$(script_dir)++ echo "» messages table"+ psql $database -q -f $base/tables/messages.sql+}++echo++echo "Creating User"+echo "- - -"+create-user+echo++echo "Creating Database"+echo "- - -"+if [ "$create_database" = true ] ; then+ create-database+else+ echo "Database creation is deactivated. Not creating the database."+fi+echo++echo "Creating Schema"+echo "- - -"+create-schema+echo++echo "Creating Extensions"+echo "- - -"+create-extensions+echo++echo "Creating Table"+echo "- - -"+create-table+echo++# Install functions+source $base/install-functions.sh++# Install indexes+source $base/install-indexes.sh++# Install views+source $base/install-views.sh++# Install privileges+source $base/install-privileges.sh++echo "= = ="+echo "Done Installing Database"+echo "Version: $(cat $base/VERSION.txt)"+echo
+ official-message-db-upstream/database/print-category-type-summary.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++if [ -z ${CATEGORY+x} ]; then+ echo "(CATEGORY is not set)"+ category=''+else+ category=$CATEGORY+ echo "Category is: $CATEGORY"+fi++echo+echo "Category Type Summary"+echo "= = ="+echo++if [ -z $category ]; then+ psql $database -U $user -P pager=off -c "SELECT * FROM category_type_summary;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages;"+else+ psql $database -U $user -P pager=off -c "SELECT * FROM category_type_summary WHERE category LIKE '%$category%';"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages WHERE category(stream_name) LIKE '%$category%';"+fi
+ official-message-db-upstream/database/print-message-store-version.sh view
@@ -0,0 +1,32 @@+#!/usr/bin/env bash++set -e++echo+echo "Printing Message Store Version"+echo "= = ="+echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++default_table_name=messages++echo++psql $database -U $user -P pager=off -c "SELECT message_store_version();"
+ official-message-db-upstream/database/print-messages.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo+echo "Printing Messages"+echo "= = ="+echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++default_table_name=messages++if [ -z ${STREAM_NAME+x} ]; then+ echo "(STREAM_NAME is not set)"+ stream_name=''+else+ stream_name=$STREAM_NAME+ echo "Stream name is: $STREAM_NAME"+fi++echo++if [ -z $stream_name ]; then+ psql $database -U $user -x -P pager=off -c "SELECT * FROM messages ORDER BY global_position ASC"+else+ psql $database -U $user -x -P pager=off -c "SELECT * FROM messages WHERE stream_name = '$stream_name' ORDER BY global_position ASC"+fi
+ official-message-db-upstream/database/print-stream-summary.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++if [ -z ${STREAM_NAME+x} ]; then+ echo "(STREAM_NAME is not set)"+ stream_name=''+else+ stream_name=$STREAM_NAME+ echo "Stream name is: $STREAM_NAME"+fi++echo+echo "Stream Summary"+echo "= = ="+echo++if [ -z $stream_name ]; then+ psql $database -U $user -P pager=off -c "SELECT * FROM stream_summary ORDER BY message_count DESC;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages;"+else+ psql $database -U $user -P pager=off -c "SELECT * FROM stream_summary WHERE stream_name LIKE '%$stream_name%' ORDER BY message_count DESC;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages WHERE stream_name LIKE '%$stream_name%';"+fi
+ official-message-db-upstream/database/print-stream-type-summary.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++if [ -z ${STREAM_NAME+x} ]; then+ echo "(STREAM_NAME is not set)"+ stream_name=''+else+ stream_name=$STREAM_NAME+ echo "Stream name is: $STREAM_NAME"+fi++echo+echo "Stream Type Summary"+echo "= = ="+echo++if [ -z $stream_name ]; then+ psql $database -U $user -P pager=off -c "SELECT * FROM stream_type_summary ORDER BY stream_name, message_count DESC, type;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages;"+else+ psql $database -U $user -P pager=off -c "SELECT * FROM stream_type_summary WHERE stream_name LIKE '%$stream_name%' ORDER BY stream_name, message_count DESC;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages WHERE stream_name LIKE '%$stream_name%';"+fi
+ official-message-db-upstream/database/print-type-category-summary.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++if [ -z ${TYPE+x} ]; then+ echo "(TYPE is not set)"+ type=''+else+ type=$TYPE+ echo "Type is: $TYPE"+fi++echo+echo "Type Category Summary"+echo "= = ="+echo++if [ -z $type ]; then+ psql $database -U $user -P pager=off -c "SELECT * FROM type_category_summary;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages;"+else+ psql $database -U $user -P pager=off -c "SELECT * FROM type_category_summary WHERE type LIKE '%$type%';"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages WHERE type LIKE '%$type%';"+fi
+ official-message-db-upstream/database/print-type-stream-summary.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++if [ -z ${TYPE+x} ]; then+ echo "(TYPE is not set)"+ type=''+else+ type=$TYPE+ echo "Type is: $TYPE"+fi++echo+echo "Type Stream Summary"+echo "= = ="+echo++if [ -z $type ]; then+ psql $database -U $user -P pager=off -c "SELECT * FROM type_stream_summary ORDER BY type, message_count DESC, stream_name;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages;"+else+ psql $database -U $user -P pager=off -c "SELECT * FROM type_stream_summary WHERE type LIKE '%$type%' ORDER BY type, message_count DESC, stream_name;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages WHERE type LIKE '%$type%';"+fi
+ official-message-db-upstream/database/print-type-summary.sh view
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"++if [ -z ${TYPE+x} ]; then+ echo "(TYPE is not set)"+ type=''+else+ type=$TYPE+ echo "Type is: $TYPE"+fi++echo+echo "Type Summary"+echo "= = ="+echo++if [ -z $type ]; then+ psql $database -U $user -P pager=off -c "SELECT * FROM type_summary ORDER BY message_count DESC;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages;"+else+ psql $database -U $user -P pager=off -c "SELECT * FROM type_summary WHERE type LIKE '%$type%' ORDER BY message_count DESC;"+ psql $database -U $user -P pager=off -c "SELECT COUNT(*) AS total_count FROM messages WHERE type LIKE '%$type%';"+fi
+ official-message-db-upstream/database/privileges/functions.sql view
@@ -0,0 +1,14 @@+GRANT EXECUTE ON FUNCTION gen_random_uuid() TO message_store;++GRANT EXECUTE ON FUNCTION message_store.acquire_lock(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.cardinal_id(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.category(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.get_category_messages(varchar, bigint, bigint, varchar, bigint, bigint, varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.get_last_stream_message(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.get_stream_messages(varchar, bigint, bigint, varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.hash_64(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.id(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.is_category(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.message_store_version() TO message_store;+GRANT EXECUTE ON FUNCTION message_store.stream_version(varchar) TO message_store;+GRANT EXECUTE ON FUNCTION message_store.write_message(varchar, varchar, varchar, jsonb, jsonb, bigint) TO message_store;
+ official-message-db-upstream/database/privileges/schema.sql view
@@ -0,0 +1,1 @@+GRANT USAGE ON SCHEMA message_store TO message_store;
+ official-message-db-upstream/database/privileges/sequence.sql view
@@ -0,0 +1,1 @@+GRANT USAGE, SELECT ON SEQUENCE message_store.messages_global_position_seq TO message_store;
+ official-message-db-upstream/database/privileges/table.sql view
@@ -0,0 +1,1 @@+GRANT SELECT, INSERT ON message_store.messages TO message_store;
+ official-message-db-upstream/database/privileges/views.sql view
@@ -0,0 +1,6 @@+GRANT SELECT ON message_store.category_type_summary TO message_store;+GRANT SELECT ON message_store.stream_summary TO message_store;+GRANT SELECT ON message_store.stream_type_summary TO message_store;+GRANT SELECT ON message_store.type_category_summary TO message_store;+GRANT SELECT ON message_store.type_stream_summary TO message_store;+GRANT SELECT ON message_store.type_summary TO message_store;
+ official-message-db-upstream/database/roles/message-store.sql view
@@ -0,0 +1,7 @@+DO $$+BEGIN+ CREATE ROLE message_store WITH LOGIN;+EXCEPTION+ WHEN duplicate_object THEN+ RAISE NOTICE 'The message_store role already exists';+END$$;
+ official-message-db-upstream/database/schema/message-store.sql view
@@ -0,0 +1,1 @@+CREATE SCHEMA IF NOT EXISTS message_store;
+ official-message-db-upstream/database/tables/messages.sql view
@@ -0,0 +1,12 @@+CREATE TABLE IF NOT EXISTS message_store.messages (+ global_position bigserial NOT NULL,+ position bigint NOT NULL,+ time TIMESTAMP WITHOUT TIME ZONE DEFAULT (now() AT TIME ZONE 'utc') NOT NULL,+ stream_name text NOT NULL,+ type text NOT NULL,+ data jsonb,+ metadata jsonb,+ id UUID NOT NULL DEFAULT gen_random_uuid()+);++ALTER TABLE message_store.messages ADD PRIMARY KEY (global_position) NOT DEFERRABLE INITIALLY IMMEDIATE;
+ official-message-db-upstream/database/types/message.sql view
@@ -0,0 +1,15 @@+DO $$+BEGIN+ DROP TYPE IF EXISTS message_store.message CASCADE;++ CREATE TYPE message_store.message AS (+ id varchar,+ stream_name varchar,+ type varchar,+ position bigint,+ global_position bigint,+ data varchar,+ metadata varchar,+ time timestamp+ );+END$$;
+ official-message-db-upstream/database/uninstall.sh view
@@ -0,0 +1,53 @@+#!/usr/bin/env bash++set -e++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++base=$(script_dir)++echo+echo "Uninstalling Database"+echo "Version: $(cat $base/VERSION.txt)"+echo "= = ="++if [ -z ${DATABASE_NAME+x} ]; then+ database=message_store+ echo "DATABASE_NAME is not set. Using: $database."+else+ database=$DATABASE_NAME+fi+echo++if [ -z ${PGOPTIONS+x} ]; then+ export PGOPTIONS='-c client_min_messages=warning'+fi++function delete-user {+ echo "» message_store user"+ psql postgres -P pager=off -q -c "DROP ROLE IF EXISTS message_store;"+}++function delete-database {+ echo "» $database database"+ psql postgres -P pager=off -q -c "DROP DATABASE IF EXISTS \"$database\";"+}++echo "Deleting database"+echo "- - -"+delete-database+echo++echo "Deleting database user"+echo "- - -"+delete-user++echo++echo "= = ="+echo "Done Uninstalling Database"+echo "Version: $(cat $base/VERSION.txt)"+echo
+ official-message-db-upstream/database/update.sh view
@@ -0,0 +1,18 @@+#!/usr/bin/env bash++set -e++echo+echo "WARNING: OBSOLETE"+echo+echo "The ${BASH_SOURCE[0]} has been deprecated"+echo "See the database/update directory for current update scripts"+echo++current_directory="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+update_directory="$current_directory/update"++echo "Contents of $update_directory"+ls -1 $update_directory++echo
+ official-message-db-upstream/database/update/1.0.0.sh view
@@ -0,0 +1,187 @@+#!/usr/bin/env bash++set -e++echo+echo "Message DB"+echo+echo "Update the message_store database"+echo+echo "WARNING:"+echo "This script updates a pre-v1 message_store database to Message DB v1.x"+echo "Do not run this script on a Message DB v1 database"+echo+echo "Fore more information about the changes made to the message store by"+echo "this update, see: https://github.com/message-db/message-db/blob/master/database/update/1.0.0.md"+echo+echo "- Press CTRL+C to stop this script from running"+echo "- Press RETURN to allow the script to proceed"+echo+read++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++base="$(script_dir)/.."+echo $base++echo+echo "Updating Database"+echo "Version: $(cat $base/VERSION.txt)"+echo "= = ="++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set. Default will be used.)"+ database=message_store+ export DATABASE_NAME=$database+else+ database=$DATABASE_NAME+fi+echo++if [ -z ${PGOPTIONS+x} ]; then+ export PGOPTIONS='-c client_min_messages=warning'+fi++function delete-extensions {+ echo "» pgcrypto extension"+ psql $database -q -c "DROP EXTENSION IF EXISTS pgcrypto";+}++function delete-indexes {+ echo "» messages_id_uniq_idx index"+ psql $database -q -c "DROP INDEX IF EXISTS messages_id_uniq_idx CASCADE";++ echo "» messages_stream_name_position_uniq_idx index"+ psql $database -q -c "DROP INDEX IF EXISTS messages_stream_name_position_uniq_idx";++ echo "» messages_category_global_position_idx index"+ psql $database -q -c "DROP INDEX IF EXISTS messages_category_global_position_idx";+}++function delete-views {+ echo "» stream_summary view"+ psql $database -q -c "DROP VIEW IF EXISTS stream_summary CASCADE";++ echo "» type_summary view"+ psql $database -q -c "DROP VIEW IF EXISTS type_summary CASCADE";++ echo "» stream_type_summary view"+ psql $database -q -c "DROP VIEW IF EXISTS stream_type_summary CASCADE";++ echo "» type_stream_summary view"+ psql $database -q -c "DROP VIEW IF EXISTS type_stream_summary CASCADE";++ echo "» category_type_summary view"+ psql $database -q -c "DROP VIEW IF EXISTS category_type_summary CASCADE";++ echo "» type_category_summary view"+ psql $database -q -c "DROP VIEW IF EXISTS type_category_summary CASCADE";+}++function delete-functions {+ echo "» hash_64 function"+ psql $database -q -c "DROP FUNCTION IF EXISTS hash_64 CASCADE";++ echo "» category function"+ psql $database -q -c "DROP FUNCTION IF EXISTS category CASCADE";++ echo "» stream_version function"+ psql $database -q -c "DROP FUNCTION IF EXISTS stream_version CASCADE";++ echo "» write_message function"+ psql $database -q -c "DROP FUNCTION IF EXISTS write_message CASCADE";++ echo "» get_stream_messages function"+ psql $database -q -c "DROP FUNCTION IF EXISTS get_stream_messages CASCADE";++ echo "» get_category_messages function"+ psql $database -q -c "DROP FUNCTION IF EXISTS get_category_messages CASCADE";++ echo "» get_last_message function"+ psql $database -q -c "DROP FUNCTION IF EXISTS get_last_message CASCADE";+}++function delete-extensions {+ echo "» pgcrypto extension"+ psql $database -q -c "DROP EXTENSION IF EXISTS pgcrypto CASCADE";+}++function create-schema {+ echo "» message_store schema"+ psql $database -q -f $base/schema/message-store.sql+}++function add-table-to-schema {+ echo "» messages table"+ psql $database -q -c "ALTER TABLE messages SET SCHEMA message_store";+}++function create-extensions {+ echo "» pgcrypto extension"+ psql $database -q -f $base/extensions/pgcrypto.sql+}++function set-default-value {+ echo "» id column"+ psql $database -q -c "ALTER TABLE message_store.messages ALTER COLUMN id SET DEFAULT gen_random_uuid()";+}++echo "Deleting Views"+echo "- - -"+delete-views+echo++echo "Deleting Indexes"+echo "- - -"+delete-indexes+echo++echo "Deleting Functions"+echo "- - -"+delete-functions+echo++echo "Deleting Extensions"+echo "- - -"+delete-extensions+echo++echo "Creating Schema"+echo "- - -"+create-schema+echo++echo "Creating Extensions"+echo "- - -"+create-extensions+echo++echo "Adding Table to Schema"+echo "- - -"+add-table-to-schema+echo++echo "Set Default Value for ID Column"+echo "- - -"+set-default-value+echo++# Install functions+source $base/install-functions.sh++# Install indexes+source $base/install-indexes.sh++# Install views+source $base/install-views.sh++# Install privileges+source $base/install-privileges.sh++echo "= = ="+echo "Done Updating Database"+echo "Version: $(cat $base/VERSION.txt)"+echo
+ official-message-db-upstream/database/update/1.2.2.sh view
@@ -0,0 +1,65 @@+#!/usr/bin/env bash++set -e++echo+echo "Message DB"+echo+echo "Update the message_store database to v1.2.2"+echo+echo "WARNING:"+echo "This script updates a post-v1 message_store database to Message DB v1.2.2"+echo "Do not run this script on a Message DB pre-v1 database"+echo+echo "Fore more information about the changes made to the message store by"+echo "this update, see: https://github.com/message-db/message-db/blob/master/database/update/1.2.2.md"+echo+echo "- Press CTRL+C to stop this script from running"+echo "- Press RETURN to allow the script to proceed"+echo++read++function script_dir {+ val="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"+ echo "$val"+}++base="$(script_dir)/.."+echo $base++echo+echo "Updating Database"+echo "Version: $(cat $base/VERSION.txt)"+echo "= = ="++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set. Default will be used.)"+ database=message_store+ export DATABASE_NAME=$database+else+ database=$DATABASE_NAME+fi+echo++if [ -z ${PGOPTIONS+x} ]; then+ export PGOPTIONS='-c client_min_messages=warning'+fi++function install-functions {+ echo "» get_stream_messages function"+ psql $database -q -f $base/functions/get-stream-messages.sql++ echo "» get_category_messages function"+ psql $database -q -f $base/functions/get-category-messages.sql+}++echo "Installing Functions"+echo "- - -"+install-functions+echo++echo "= = ="+echo "Done Updating Database"+echo "Version: $(cat $base/VERSION.txt)"+echo
+ official-message-db-upstream/database/views/category-type-summary.sql view
@@ -0,0 +1,32 @@+CREATE OR REPLACE VIEW message_store.category_type_summary AS+ WITH+ type_count AS (+ SELECT+ message_store.category(stream_name) AS category,+ type,+ COUNT(id) AS message_count+ FROM+ message_store.messages+ GROUP BY+ category,+ type+ ),++ total_count AS (+ SELECT+ COUNT(id)::decimal AS total_count+ FROM+ message_store.messages+ )++ SELECT+ category,+ type,+ message_count,+ ROUND((message_count / total_count)::decimal * 100, 2) AS percent+ FROM+ type_count,+ total_count+ ORDER BY+ category,+ type;
+ official-message-db-upstream/database/views/stream-summary.sql view
@@ -0,0 +1,28 @@+CREATE OR REPLACE VIEW message_store.stream_summary AS+ WITH+ stream_count AS (+ SELECT+ stream_name,+ COUNT(id) AS message_count+ FROM+ message_store.messages+ GROUP BY+ stream_name+ ),++ total_count AS (+ SELECT+ COUNT(id)::decimal AS total_count+ FROM+ message_store.messages+ )++ SELECT+ stream_name,+ message_count,+ ROUND((message_count / total_count)::decimal * 100, 2) AS percent+ FROM+ stream_count,+ total_count+ ORDER BY+ stream_name;
+ official-message-db-upstream/database/views/stream-type-summary.sql view
@@ -0,0 +1,32 @@+CREATE OR REPLACE VIEW message_store.stream_type_summary AS+ WITH+ type_count AS (+ SELECT+ stream_name,+ type,+ COUNT(id) AS message_count+ FROM+ message_store.messages+ GROUP BY+ stream_name,+ type+ ),++ total_count AS (+ SELECT+ COUNT(id)::decimal AS total_count+ FROM+ message_store.messages+ )++ SELECT+ stream_name,+ type,+ message_count,+ ROUND((message_count / total_count)::decimal * 100, 2) AS percent+ FROM+ type_count,+ total_count+ ORDER BY+ stream_name,+ type;
+ official-message-db-upstream/database/views/type-category-summary.sql view
@@ -0,0 +1,32 @@+CREATE OR REPLACE VIEW message_store.type_category_summary AS+ WITH+ type_count AS (+ SELECT+ type,+ message_store.category(stream_name) AS category,+ COUNT(id) AS message_count+ FROM+ message_store.messages+ GROUP BY+ type,+ category+ ),++ total_count AS (+ SELECT+ COUNT(id)::decimal AS total_count+ FROM+ message_store.messages+ )++ SELECT+ type,+ category,+ message_count,+ ROUND((message_count / total_count)::decimal * 100, 2) AS percent+ FROM+ type_count,+ total_count+ ORDER BY+ type,+ category;
+ official-message-db-upstream/database/views/type-stream-summary.sql view
@@ -0,0 +1,32 @@+CREATE OR REPLACE VIEW message_store.type_stream_summary AS+ WITH+ type_count AS (+ SELECT+ type,+ stream_name,+ COUNT(id) AS message_count+ FROM+ message_store.messages+ GROUP BY+ type,+ stream_name+ ),++ total_count AS (+ SELECT+ COUNT(id)::decimal AS total_count+ FROM+ message_store.messages+ )++ SELECT+ type,+ stream_name,+ message_count,+ ROUND((message_count / total_count)::decimal * 100, 2) AS percent+ FROM+ type_count,+ total_count+ ORDER BY+ type,+ stream_name;
+ official-message-db-upstream/database/views/type-summary.sql view
@@ -0,0 +1,28 @@+CREATE OR REPLACE VIEW message_store.type_summary AS+ WITH+ type_count AS (+ SELECT+ type,+ COUNT(id) AS message_count+ FROM+ message_store.messages+ GROUP BY+ type+ ),++ total_count AS (+ SELECT+ COUNT(id)::decimal AS total_count+ FROM+ message_store.messages+ )++ SELECT+ type,+ message_count,+ ROUND((message_count / total_count)::decimal * 100, 2) AS percent+ FROM+ type_count,+ total_count+ ORDER BY+ type;
+ official-message-db-upstream/database/write-test-message.sh view
@@ -0,0 +1,63 @@+#!/usr/bin/env bash++set -u++instances=1+if [ ! -z ${INSTANCES+x} ]; then+ instances=$INSTANCES+fi++uuid=$(echo $(uuidgen) | tr '[:upper:]' '[:lower:]')+stream_name="testStream-$uuid"+if [ ! -z ${STREAM_NAME+x} ]; then+ stream_name=$STREAM_NAME+fi++title="Writing $instances Messages to Stream $stream_name"+if [ -z ${METADATA+x} ]; then+ metadata="'{\"metaAttribute\": \"some meta value\"}'"+else+ metadata="$METADATA"+ title="$title with Metadata $metadata"+fi++metadata="$metadata::jsonb"++echo+echo $title+echo "= = ="+echo++default_name=message_store++if [ -z ${DATABASE_USER+x} ]; then+ echo "(DATABASE_USER is not set)"+ user=$default_name+else+ user=$DATABASE_USER+fi+echo "Database user is: $user"++if [ -z ${DATABASE_NAME+x} ]; then+ echo "(DATABASE_NAME is not set)"+ database=$default_name+else+ database=$DATABASE_NAME+fi+echo "Database name is: $database"+echo+++for (( i=1; i<=instances; i++ )); do+ uuid=$(echo $(uuidgen) | tr '[:upper:]' '[:lower:]')++ echo "Instance: $i, Message ID: $uuid"++ psql $database -U $user -c "SELECT write_message('$uuid'::varchar, '$stream_name'::varchar, 'SomeType'::varchar, '{\"attribute\": \"some value\"}'::jsonb, $metadata);" > /dev/null+done+++echo+psql $database -U $user -P pager=off -x -c "SELECT * FROM messages WHERE stream_name = '$stream_name';"++echo
+ official-message-db-upstream/recreate-database.sh view
@@ -0,0 +1,4 @@+#!/usr/bin/env bash++database/uninstall.sh+database/install.sh
+ official-message-db-upstream/test.sh view
@@ -0,0 +1,75 @@+#!/usr/bin/env bash++set -e++test/hash-64.sh++test/category/stream-name.sh+test/category/category.sh++test/is_category/category.sh+test/is_category/stream-name.sh++test/id/stream-name.sh+test/id/category.sh+test/id/compound-id/stream-name.sh++test/cardinal-id/stream-name-with-compound-id.sh+test/cardinal-id/stream-name-with-single-id.sh+test/cardinal-id/category.sh++test/write-message/write-message.sh+test/write-message/expected-version.sh+test/write-message/expected-version-error.sh++test/get-stream-messages/get-stream-messages.sh+test/get-stream-messages/error-not-stream-name.sh++test/get-stream-messages/batch_size/limited.sh+test/get-stream-messages/batch_size/unlimited.sh++test/get-stream-messages/condition/condition.sh+test/get-stream-messages/condition/error-deactivated.sh+test/get-stream-messages/condition/error-not-activated.sh++test/get-category-messages/get-category-messages.sh+test/get-category-messages/error-not-category.sh++test/get-category-messages/batch_size/limited.sh+test/get-category-messages/batch_size/unlimited.sh++test/get-category-messages/correlated/correlated.sh+test/get-category-messages/correlated/error-stream-name.sh++test/get-category-messages/consumer-group/consumer-group.sh+test/get-category-messages/consumer-group/correlated.sh++test/get-category-messages/consumer-group/error/missing-group-member.sh+test/get-category-messages/consumer-group/error/missing-group-size.sh+test/get-category-messages/consumer-group/error/group-member-equal-to-group-size.sh+test/get-category-messages/consumer-group/error/group-member-greater-than-group-size.sh+test/get-category-messages/consumer-group/error/group-member-too-small.sh+test/get-category-messages/consumer-group/error/group-size-too-small.sh++test/get-category-messages/condition/condition.sh+test/get-category-messages/condition/error-deactivated.sh+test/get-category-messages/condition/error-not-activated.sh+test/get-category-messages/condition/condition-correlated.sh++test/get-last-stream-message/stream-name.sh+test/get-last-stream-message/category.sh++test/stream-version/stream-version.sh++test/message-store-version.sh++test/reports/messages.sh+test/reports/stream-summary.sh+test/reports/type-summary.sh+test/reports/stream-type-summary.sh+test/reports/type-stream-summary.sh+test/reports/category-type-summary.sh+test/reports/type-category-summary.sh++echo "Done"+echo
+ official-message-db-upstream/test/_controls.sh view
@@ -0,0 +1,6 @@+source test/_controls/category.sh+source test/_controls/id.sh+source test/_controls/stream-name.sh+source test/_controls/compound-id-stream-name.sh+source test/_controls/write-message.sh+source test/_controls/write-message-correlated.sh
+ official-message-db-upstream/test/_controls/category.sh view
@@ -0,0 +1,6 @@+function category {+ local uuid=$(echo $(uuidgen) | tr '[:upper:]' '[:lower:]')+ local category_suffix=${uuid:0:8}+ local category="${1:-testStream}X$category_suffix"+ echo $category+}
+ official-message-db-upstream/test/_controls/compound-id-stream-name.sh view
@@ -0,0 +1,6 @@+function compound-id-stream-name {+ local category=${1:-$(category)}+ local cardinal_id=${2:-$(id)}+ local stream_name="$category-$cardinal_id+$(id)"+ echo $stream_name+}
+ official-message-db-upstream/test/_controls/id.sh view
@@ -0,0 +1,4 @@+function id {+ local uuid=$(echo $(uuidgen) | tr '[:upper:]' '[:lower:]')+ echo $uuid+}
+ official-message-db-upstream/test/_controls/stream-name.sh view
@@ -0,0 +1,5 @@+function stream-name {+ local category=${1:-$(category)}+ local stream_name="$category-$(id)"+ echo $stream_name+}
@@ -0,0 +1,13 @@+function write-message-correlated {+ local stream_name=${1:-$(stream-name)}+ local instances=${2:-1}+ local correlation_stream_name=${3:-"someCorrelation"}++ if [ ! -z ${CORRELATION+x} ]; then+ correlation_stream_name=$CORRELATION+ fi++ metadata="'{\"correlationStreamName\": \"$correlation_stream_name\"}'"++ METADATA=$metadata STREAM_NAME=$stream_name INSTANCES=$instances database/write-test-message.sh > /dev/null+}
+ official-message-db-upstream/test/_controls/write-message.sh view
@@ -0,0 +1,5 @@+function write-message {+ local stream_name=${1:-$(stream-name)}+ local instances=${2:-1}+ STREAM_NAME=$stream_name INSTANCES=$instances database/write-test-message.sh > /dev/null+}
@@ -0,0 +1,49 @@+#!/usr/bin/env bash++set -e++echo+echo "QUERY PLAN - GET CATEGORY MESSAGES - CONSUMER GROUP - CORRELATED"+echo "================================================================"+echo "- Write 2 messages each to 5 entity streams in the same category"+echo "- Retrieve a batch of messages from the category, starting at global position 0 and matching the correlation category"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo++correlation=$(category)+correlation_stream_name=$(stream-name $correlation)+echo "Correlation:"+echo $correlation+echo++for i in {1..1000}; do+ stream_name=$(stream-name $category)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name 1+ write-message-correlated $stream_name 1 $correlation_stream_name+done+echo++cmd="+ LOAD 'auto_explain';+ SET auto_explain.log_min_duration = 0;+ SET auto_explain.log_nested_statements=on;+ EXPLAIN ANALYZE SELECT * FROM get_category_messages('$category', correlation => '$correlation', consumer_group_member => 0, consumer_group_size => 2);+"++echo "Command:"+echo "$cmd"+echo++psql message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
@@ -0,0 +1,49 @@+#!/usr/bin/env bash++set -e++echo+echo "QUERY PLAN - GET CATEGORY MESSAGES - CORRELATED"+echo "==============================================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of 2 messages from the category, starting at global position 0 and matching the correlation category"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo++correlation=$(category)+correlation_stream_name=$(stream-name $correlation)+echo "Correlation:"+echo $correlation+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name 1+ write-message-correlated $stream_name 1 $correlation_stream_name+done+echo++cmd="+ LOAD 'auto_explain';+ SET auto_explain.log_min_duration = 0;+ SET auto_explain.log_nested_statements=on;+ EXPLAIN ANALYZE SELECT * FROM get_category_messages('$category', 0, 2, correlation => '$correlation');+"++echo "Command:"+echo "$cmd"+echo++psql message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/_query-plan/get-category-messages.sh view
@@ -0,0 +1,41 @@+#!/usr/bin/env bash++set -e++echo+echo "QUERY PLAN - GET CATEGORY MESSAGES"+echo "=================================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of messages from the category"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)+ echo $stream_name+ write-message $stream_name 2+done+echo++cmd="+ LOAD 'auto_explain';+ SET auto_explain.log_min_duration = 0;+ SET auto_explain.log_nested_statements=on;+ EXPLAIN ANALYZE SELECT * FROM get_category_messages('$category');+"++echo "Command:"+echo "$cmd"+echo++psql message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
@@ -0,0 +1,43 @@+#!/usr/bin/env bash++set -e++echo+echo "ANALYZE QUERY PLAN - GET STREAM MESSAGES CORRELATED"+echo "==================================================="+echo "- Write 3 messages to an entity stream"+echo "- Retrieve a batch of messages from the stream matching the correlation category"+echo++source test/_controls.sh++correlation=$(category)+correlation_stream_name=$(stream-name $correlation)+echo "Correlation:"+echo $correlation+echo++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message-correlated $stream_name 1+write-message-correlated $stream_name 2 $correlation_stream_name++cmd="+ LOAD 'auto_explain';+ SET auto_explain.log_min_duration = 0;+ SET auto_explain.log_nested_statements=on;+ EXPLAIN ANALYZE SELECT * FROM get_stream_messages('$stream_name', correlation => '$correlation');+"++echo "Command:"+echo "$cmd"+echo++psql message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/_query-plan/get-stream-messages.sh view
@@ -0,0 +1,36 @@+#!/usr/bin/env bash++set -e++echo+echo "QUERY PLAN - GET STREAM MESSAGES"+echo "================================"+echo "- Write 3 messages to an entity stream"+echo "- Retrieve a batch of messages from the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name 3++cmd="+ LOAD 'auto_explain';+ SET auto_explain.log_min_duration = 0;+ SET auto_explain.log_nested_statements=on;+ EXPLAIN ANALYZE SELECT * FROM get_stream_messages('$stream_name');+"++echo "Command:"+echo "$cmd"+echo++psql message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/acquire-lock.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "ACQUIRE LOCK"+echo "============"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT acquire_lock('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/cardinal-id/category.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "CARDINAL ID - FROM CATEOGRY"+echo "==========================="+echo++source test/_controls.sh++stream_name=$(category)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT cardinal_id('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/cardinal-id/stream-name-with-compound-id.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "CARDINAL ID - FROM STREAM NAME WITH COMPOUND ID"+echo "==============================================="+echo++source test/_controls.sh++stream_name=$(compound-id-stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT cardinal_id('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/cardinal-id/stream-name-with-single-id.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "CARDINAL ID - FROM STREAM NAME WITH SINGLE ID"+echo "============================================="+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT cardinal_id('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/category/category.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "CATEGORY - FROM CATEGORY"+echo "========================"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++psql message_store -U message_store -x -c "SELECT category('$category');"++echo "= = ="+echo
+ official-message-db-upstream/test/category/stream-name.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "CATEGORY - FROM STREAM NAME"+echo "==========================="+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT category('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/batch_size/limited.sh view
@@ -0,0 +1,36 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - BATCH SIZE - LIMTED"+echo "==========================================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of 2 messages from the category"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)+ echo $stream_name+ write-message $stream_name 2+done+echo++cmd="SELECT * FROM get_category_messages('$category', batch_size => 2);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/batch_size/unlimited.sh view
@@ -0,0 +1,36 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - BATCH SIZE - UNLIMTED"+echo "============================================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve an unlimited batch of messages from the category"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)+ echo $stream_name+ write-message $stream_name 2+done+echo++cmd="SELECT * FROM get_category_messages('$category', batch_size => -1);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONDITION CORRELATED"+echo "============================================"+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of 2 messages from the category, starting at global position 0, where the position is greater than or equal to 1, and matching the correlation category"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo++correlation=$(category)+correlation_stream_name=$(stream-name $correlation)+echo "Correlation:"+echo $correlation+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name 1+ write-message-correlated $stream_name 1 $correlation_stream_name+done+echo++cmd="SELECT * FROM get_category_messages('$category', 0, 2, correlation => '$correlation', condition => 'position >= 1');"++echo "Command:"+echo "$cmd"+echo++PGOPTIONS='-c message_store.sql_condition=on' psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/condition/condition.sh view
@@ -0,0 +1,36 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONDITION"+echo "================================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of 2 messages from the category, starting at global position 0 where the position is greater than or equal to 1"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)+ echo $stream_name+ write-message $stream_name 2+done+echo++cmd="SELECT * FROM get_category_messages('$category', 0, 2, condition => 'position >= 1');"++echo "Command:"+echo "$cmd"+echo++PGOPTIONS='-c message_store.sql_condition=on' psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/condition/error-deactivated.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "ERROR - GET CATEGORY MESSAGES - CONDITION - FEATURE DEACTIVATED"+echo "==============================================================="+echo "- Retrieve a batch of messages from the category using the SQL condition when the SQL condition feature is deactivated"+echo "- Terminates with an error"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++cmd="SELECT * FROM get_category_messages('$category', condition => 'position >= 1');"++echo "Command:"+echo "$cmd"+echo++set +e+PGOPTIONS='-c message_store.sql_condition=off' psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/condition/error-not-activated.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "ERROR - GET CATEGORY MESSAGES - CONDITION - FEATURE NOT ACTIVATED"+echo "================================================================="+echo "- Retrieve a batch of messages from the category using the SQL condition when the SQL condition feature is deactivated"+echo "- Terminates with an error"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++cmd="SELECT * FROM get_category_messages('$category', condition => 'position >= 1');"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/consumer-group.sh view
@@ -0,0 +1,96 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP"+echo "======================================"+echo "- Write 10 messages to 2 entity streams in the same category but with different cardinal IDs"+echo "- Retrieve a batch of messages from the category that match the consumer group conditions"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo+++cardinal_id_1=$(id)+echo "Cardinal ID 1:"+echo $cardinal_id_1+echo++for i in {1..10}; do+ stream_name=$(compound-id-stream-name $category $cardinal_id_1)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name+done+echo+++cardinal_id_2=$(id)+echo "Cardinal ID 2:"+echo $cardinal_id_2+echo++for i in {1..10}; do+ stream_name=$(compound-id-stream-name $category $cardinal_id_2)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name+done+echo+++cmd="SELECT * FROM get_category_messages('$category');"+cmd_0="SELECT * FROM get_category_messages('$category', consumer_group_member => 0, consumer_group_size => 2);"+cmd_1="SELECT * FROM get_category_messages('$category', consumer_group_member => 1, consumer_group_size => 2);"++echo "Command:"+echo "$cmd"+echo++echo "Command 0:"+echo "$cmd_0"+echo++echo "Command 1:"+echo "$cmd_1"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"+echo+psql message_store -U message_store -P pager=off -x -c "$cmd_0"+echo+psql message_store -U message_store -P pager=off -x -c "$cmd_1"+++cmd_count="SELECT COUNT(*) AS total FROM get_category_messages('$category');"+cmd_count_0="SELECT COUNT(*) AS modulo_0 FROM get_category_messages('$category', consumer_group_member => 0, consumer_group_size => 2);"+cmd_count_1="SELECT COUNT(*) AS modulo_1 FROM get_category_messages('$category', consumer_group_member => 1, consumer_group_size => 2);"++echo "Command Count:"+echo "$cmd_count"+echo++echo "Command Count 0:"+echo "$cmd_count_0"+echo++echo "Command Count 1:"+echo "$cmd_count_1"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd_count"+echo+psql message_store -U message_store -P pager=off -x -c "$cmd_count_0"+echo+psql message_store -U message_store -P pager=off -x -c "$cmd_count_1"++echo "= = ="+echo
@@ -0,0 +1,95 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - CORRELATED"+echo "==================================================="+echo "- Write 2 messages each to 10 entity streams in the same category"+echo "- Half of the messages have a different cardinal ID that the other half"+echo "- Retrieve messages from the category that match the consumer group conditions"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo++correlation=$(category)+correlation_stream_name=$(stream-name $correlation)+echo "Correlation:"+echo $correlation+echo+++cardinal_id_1=$(id)+echo "Cardinal ID 1:"+echo $cardinal_id_1+echo++for i in {1..5}; do+ stream_name=$(compound-id-stream-name $category $cardinal_id_1)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name 1+ write-message-correlated $stream_name 1 $correlation_stream_name+done+echo+++cardinal_id_2=$(id)+echo "Cardinal ID 2:"+echo $cardinal_id_2+echo++for i in {1..5}; do+ stream_name=$(compound-id-stream-name $category $cardinal_id_2)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name 1+ write-message-correlated $stream_name 1 $correlation_stream_name+done+echo+++echo "All messages written to the category"+echo++cmd="SELECT * FROM get_category_messages('$category');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"+++echo "Correlated messages written to the category for consumer member 0"+echo++cmd="SELECT * FROM get_category_messages('$category', 0, 10, correlation => '$correlation', consumer_group_member => 0, consumer_group_size => 2);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"+++echo "A batch of 1 message written to the category for consumer member 0 greater than global position 2"+echo++cmd="SELECT * FROM get_category_messages('$category', 2, 1, correlation => '$correlation', consumer_group_member => 0, consumer_group_size => 2);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/error/group-member-equal-to-group-size.sh view
@@ -0,0 +1,25 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - ERROR - GROUP MEMBER EQUAL TO GROUP SIZE"+echo "================================================================================="+echo "- Retrieve a batch of messages from the category with a consumer group member equal to the group size"+echo "- Terminates with an error"+echo++source test/_controls.sh++cmd="SELECT * FROM get_category_messages('someCategory', consumer_group_member => 1, consumer_group_size => 1);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/error/group-member-greater-than-group-size.sh view
@@ -0,0 +1,25 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - ERROR - GROUP MEMBER GREATER THAN GROUP SIZE"+echo "====================================================================================="+echo "- Retrieve a batch of messages from the category with a consumer group member equals the group size"+echo "- Terminates with an error"+echo++source test/_controls.sh++cmd="SELECT * FROM get_category_messages('someCategory', consumer_group_member => 2, consumer_group_size => 1);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/error/group-member-too-small.sh view
@@ -0,0 +1,25 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - ERROR - GROUP MEMBER TOO SMALL"+echo "======================================================================="+echo "- Retrieve a batch of messages from the category with a consumer group member that is too small"+echo "- Terminates with an error"+echo++source test/_controls.sh++cmd="SELECT * FROM get_category_messages('someCategory', consumer_group_member => -1, consumer_group_size => 1);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/error/group-size-too-small.sh view
@@ -0,0 +1,25 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - ERROR - GROUP SIZE TOO SMALL"+echo "====================================================================="+echo "- Retrieve a batch of messages from the category with a consumer group size that is too small"+echo "- Terminates with an error"+echo++source test/_controls.sh++cmd="SELECT * FROM get_category_messages('someCategory', consumer_group_member => 0, consumer_group_size => 0);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/error/missing-group-member.sh view
@@ -0,0 +1,25 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - ERROR - MISSING GROUP MEMBER"+echo "====================================================================="+echo "- Retrieve a batch of messages from the category, omitting the consumer group member argument"+echo "- Terminates with an error"+echo++source test/_controls.sh++cmd="SELECT * FROM get_category_messages('someCategory', consumer_group_member => 1);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/consumer-group/error/missing-group-size.sh view
@@ -0,0 +1,25 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CONSUMER GROUP - ERROR - MISSING GROUP SIZE"+echo "==================================================================="+echo "- Retrieve a batch of messages from the category, omitting the consumer group size argument"+echo "- Terminates with an error"+echo++source test/_controls.sh++cmd="SELECT * FROM get_category_messages('someCategory', consumer_group_size => 1);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
@@ -0,0 +1,44 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CORRELATED"+echo "=================================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of 2 messages from the category, starting at global position 0 and matching the correlation category"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo++correlation=$(category)+correlation_stream_name=$(stream-name $correlation)+echo "Correlation:"+echo $correlation+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)++ echo "Stream Name: $stream_name"++ write-message-correlated $stream_name 1+ write-message-correlated $stream_name 1 $correlation_stream_name+done+echo++cmd="SELECT * FROM get_category_messages('$category', 0, 2, correlation => '$correlation');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
@@ -0,0 +1,36 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - CORRELATED STREAM NAME ERROR"+echo "===================================================="+echo "- Retrieve a messages using a stream name as the correlation value"+echo "- Terminates with an error"+echo++source test/_controls.sh++category=$(category)+echo "Category:"+echo $category+echo++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++cmd="SELECT * FROM get_category_messages('$category', correlation => '$stream_name');"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/error-not-category.sh view
@@ -0,0 +1,27 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES - ERROR - NOT CATEGORY"+echo "============================================"+echo "- Retrieve a batch of messages from the category using a stream name instead of a category"+echo "- Terminates with an error"+echo++source test/_controls.sh++stream_name=$(stream-name)++cmd="SELECT * FROM get_category_messages('$stream_name');"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-category-messages/get-category-messages.sh view
@@ -0,0 +1,36 @@+#!/usr/bin/env bash++set -e++echo+echo "GET CATEGORY MESSAGES"+echo "====================="+echo "- Write 2 messages each to 3 entity streams in the same category"+echo "- Retrieve a batch of messages from the category"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++for i in {1..3}; do+ stream_name=$(stream-name $category)+ echo $stream_name+ write-message $stream_name 2+done+echo++cmd="SELECT * FROM get_category_messages('$category');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-last-stream-message/category.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "GET LAST STREAM MESSAGE - CATEGORY"+echo "=================================="+echo "- Write 2 messages to a category stream"+echo "- Retrieve the last message in the stream"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++STREAM_NAME=$category INSTANCES=2 database/write-test-message.sh > /dev/null++cmd="SELECT * FROM get_last_stream_message('$category');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-last-stream-message/stream-name.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "GET LAST STREAM MESSAGE - STREAM NAME"+echo "====================================="+echo "- Write 2 messages to an entity stream"+echo "- Retrieve the last message in the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++STREAM_NAME=$stream_name INSTANCES=2 database/write-test-message.sh > /dev/null++cmd="SELECT * FROM get_last_stream_message('$stream_name');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/batch_size/limited.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "GET STREAM MESSAGES - BATCH SIZE - LIMTED"+echo "========================================="+echo "- Write 3 messages to an entity stream"+echo "- Retrieve a batch of 2 messages from the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name 3++cmd="SELECT * FROM get_stream_messages('$stream_name', batch_size => 2);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/batch_size/unlimited.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "GET STREAM MESSAGES - BATCH SIZE - UNLIMTED"+echo "==========================================="+echo "- Write 3 messages to an entity stream"+echo "- Retrieve an unlimited batch of messages from the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name 3++cmd="SELECT * FROM get_stream_messages('$stream_name', batch_size => -1);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/condition/condition.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "GET STREAM MESSAGES - CONDITION"+echo "==============================="+echo "- Write 3 messages to an entity stream"+echo "- Retrieve a batch of 2 messages from the stream, starting at position 0 where the global position is greater than or equal to 1"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name 3++cmd="SELECT * FROM get_stream_messages('$stream_name', 0, 2, condition => 'global_position >= 1');"++echo "Command:"+echo "$cmd"+echo++PGOPTIONS='-c message_store.sql_condition=on' psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/condition/error-deactivated.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "ERROR - GET STREAM MESSAGES - CONDITION - FEATURE DEACTIVATED"+echo "============================================================="+echo "- Retrieve a batch of messages from the stream using the SQL condition when the SQL condition feature is deactivated"+echo "- Terminates with an error"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++cmd="SELECT * FROM get_stream_messages('$stream_name', condition => 'position >= 1');"++echo "Command:"+echo "$cmd"+echo++set +e+PGOPTIONS='-c message_store.sql_condition=off' psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/condition/error-not-activated.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "ERROR - GET STREAM MESSAGES - CONDITION - FEATURE NOT ACTIVATED"+echo "==============================================================="+echo "- Retrieve a batch of messages from the stream using the SQL condition when the SQL condition feature is deactivated"+echo "- Terminates with an error"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++cmd="SELECT * FROM get_stream_messages('$stream_name', condition => 'position >= 1');"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/error-not-stream-name.sh view
@@ -0,0 +1,27 @@+#!/usr/bin/env bash++set -e++echo+echo "GET STREAM MESSAGES - ERROR - NOT STREAM NAME"+echo "============================================="+echo "- Retrieve a batch of messages from the stream using a category instead of a stream name"+echo "- Terminates with an error"+echo++source test/_controls.sh++category=$(category)++cmd="SELECT * FROM get_stream_messages('$category');"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -P pager=off -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/get-stream-messages/get-stream-messages.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "GET STREAM MESSAGES"+echo "==================="+echo "- Write 3 messages to an entity stream"+echo "- Retrieve a batch of messages from the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name 3++cmd="SELECT * FROM get_stream_messages('$stream_name');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/hash-64.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "GET HASH 64"+echo "==========="+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT hash_64('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/id/category.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "ID - FROM CATEGORY"+echo "=================="+echo++source test/_controls.sh++stream_name=$(category)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT id('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/id/compound-id/stream-name.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "GET ID FROM STREAM NAME WITH COMPOUND ID"+echo "========================================"+echo++source test/_controls.sh++stream_name=$(compound-id-stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT id('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/id/stream-name.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "ID - FROM STREAM NAME"+echo "====================="+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT id('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/is_category/category.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "IS CATEGORY - CATEGORY"+echo "======================"+echo++source test/_controls.sh++category=$(category)++echo "Category:"+echo $category+echo++psql message_store -U message_store -x -c "SELECT is_category('$category');"++echo "= = ="+echo
+ official-message-db-upstream/test/is_category/stream-name.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "IS CATEGORY - STREAM NAME"+echo "========================="+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++psql message_store -U message_store -x -c "SELECT is_category('$stream_name');"++echo "= = ="+echo
+ official-message-db-upstream/test/message-store-version.sh view
@@ -0,0 +1,14 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT MESSAGE STORE VERSION"+echo "==========================="+echo "- Retrieve message store database schema version from the message_store_version server function"+echo++database/print-message-store-version.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/category-type-summary.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT CATEGORY TYPE SUMMARY"+echo "==========================="+echo "- Write 3 messages to 3 entity streams"+echo "- Print the category type summary"+echo++source test/_controls.sh++write-message+write-message+write-message++database/print-category-type-summary.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/messages.sh view
@@ -0,0 +1,24 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT MESSAGES"+echo "=============="+echo "- Write 3 messages to an entity stream"+echo "- Print the messages in the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name++write-message $stream_name 3++STREAM_NAME=$stream_name database/print-messages.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/stream-summary.sh view
@@ -0,0 +1,26 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT STREAM SUMMARY"+echo "===================="+echo "- Write 3 messages to an entity stream"+echo "- Write a messages to another entity stream"+echo "- Print the message summary for the stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name++write-message $stream_name 3+write-message++STREAM_NAME=$stream_name database/print-stream-summary.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/stream-type-summary.sh view
@@ -0,0 +1,27 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT STREAM TYPE SUMMARY"+echo "========================="+echo "- Write 3 messages to an entity streams"+echo "- Write a messages to 2 other entity streams"+echo "- Print the stream type summary"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name++write-message $stream_name 3+write-message+write-message++STREAM_NAME=$stream_name database/print-stream-type-summary.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/type-category-summary.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT TYPE CATEGORY SUMMARY"+echo "==========================="+echo "- Write 3 messages to 3 entity streams"+echo "- Print the type category summary"+echo++source test/_controls.sh++write-message+write-message+write-message++database/print-type-category-summary.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/type-stream-summary.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT TYPE STREAM SUMMARY"+echo "========================="+echo "- Write 3 messages to 3 entity streams"+echo "- Print the type stream summary"+echo++source test/_controls.sh++write-message+write-message+write-message++database/print-type-stream-summary.sh++echo "= = ="+echo
+ official-message-db-upstream/test/reports/type-summary.sh view
@@ -0,0 +1,21 @@+#!/usr/bin/env bash++set -e++echo+echo "PRINT TYPE SUMMARY"+echo "=================="+echo "- Write 3 messages to 3 entity streams"+echo "- Print the type summary"+echo++source test/_controls.sh++write-message+write-message+write-message++database/print-type-summary.sh++echo "= = ="+echo
+ official-message-db-upstream/test/stream-version/stream-version.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "STREAM VERSION"+echo "=============="+echo "- Write 2 messages to an entity stream"+echo "- Retrieve stream version"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name 2++cmd="SELECT * FROM stream_version('$stream_name');"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -P pager=off -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/write-message/expected-version-error.sh view
@@ -0,0 +1,34 @@+#!/usr/bin/env bash++set -e++echo+echo "WRITE MESSAGE - EXPECTED VERSION ERROR"+echo "======================================"+echo "- Write a single message to an entity stream"+echo "- Write another message with the expected version of 1 that does not match a stream with one message"+echo "- Terminates with an error"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name++cmd="SELECT write_message(gen_random_uuid()::varchar, '$stream_name'::varchar, 'SomeType'::varchar, '{\"attribute\": \"some value\"}'::jsonb, '{\"metaAttribute\": \"some meta value\"}'::jsonb, 1::bigint);"++echo "Command:"+echo "$cmd"+echo++set +e+psql message_store -U message_store -x -c "$cmd"+set -e++echo "= = ="+echo
+ official-message-db-upstream/test/write-message/expected-version.sh view
@@ -0,0 +1,31 @@+#!/usr/bin/env bash++set -e++echo+echo "WRITE MESSAGE - EXPECTED VERSION"+echo "================================"+echo "- Write a single message to an entity stream"+echo "- Write another message with the expected version of 0 that matches a stream with one message"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++write-message $stream_name++cmd="SELECT write_message(gen_random_uuid()::varchar, '$stream_name'::varchar, 'SomeType'::varchar, '{\"attribute\": \"some value\"}'::jsonb, '{\"metaAttribute\": \"some meta value\"}'::jsonb, 0::bigint);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -x -c "$cmd"++echo "= = ="+echo
+ official-message-db-upstream/test/write-message/write-message.sh view
@@ -0,0 +1,30 @@+#!/usr/bin/env bash++set -e++echo+echo "WRITE MESSAGE"+echo "============="+echo "Write a single message to an entity stream"+echo++source test/_controls.sh++stream_name=$(stream-name)++echo "Stream Name:"+echo $stream_name+echo++cmd="SELECT write_message(gen_random_uuid()::varchar, '$stream_name'::varchar, 'SomeType'::varchar, '{\"attribute\": \"some value\"}'::jsonb, '{\"metaAttribute\": \"some meta value\"}'::jsonb);"++echo "Command:"+echo "$cmd"+echo++psql message_store -U message_store -x -c "$cmd"++psql message_store -U message_store -P pager=off -x -c "SELECT * FROM messages WHERE stream_name = '$stream_name';"++echo "= = ="+echo
+ src/MessageDb/Temp.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE QuasiQuotes #-}++module MessageDb.Temp+ ( ConnectionStrings (..),+ withConnectionStrings,+ )+where++import Control.Exception (Exception, IOException)+import Control.Exception.Safe (bracket, throwIO)+import Control.Monad (void)+import Control.Monad.Catch (Handler (Handler))+import qualified Control.Retry as Retry+import Data.ByteString (ByteString)+import qualified Data.Map.Strict as Map+import Data.Maybe (fromMaybe)+import Data.Monoid (getLast)+import qualified Database.PostgreSQL.Simple as Postgres+import Database.PostgreSQL.Simple.Options (Options)+import qualified Database.PostgreSQL.Simple.Options as PostgresOptions+import Database.PostgreSQL.Simple.SqlQQ (sql)+import Database.Postgres.Temp (Accum (Merge))+import qualified Database.Postgres.Temp as PostgresTemp+import qualified Paths_message_db_temp+import System.Environment (getEnvironment)+import qualified System.Process.Typed as Process+++-- | Connection strings used to connect to your temporary message-db.+data ConnectionStrings = ConnectionStrings+ { privilegedConnectionString :: ByteString+ -- ^ Connection string used to connect to the database as a privileged user.+ , normalConnectionString :: ByteString+ -- ^ Connection string used to connect to the database as a user that only has the 'message_store' role.+ }+++migrate :: Options -> IO ()+migrate options = do+ hostEnv <- getEnvironment++ installScriptPath <-+ Paths_message_db_temp.getDataFileName "official-message-db-upstream/database/install.sh"++ let fromLast =+ fromMaybe "" . getLast++ processEnv =+ hostEnv+ <> [+ ( "PGHOST"+ , fromLast $ PostgresOptions.host options+ )+ ,+ ( "PGDATABASE"+ , fromLast $ PostgresOptions.dbname options+ )+ ,+ ( "PGPORT"+ , fromLast . fmap show $ PostgresOptions.port options+ )+ ,+ ( "PGUSER"+ , fromLast $ PostgresOptions.user options+ )+ ]+ command = Process.proc "bash" [installScriptPath]+ in void . Process.readProcess_ $ Process.setEnv processEnv command++ let url = PostgresOptions.toConnectionString options+ in bracket (Postgres.connectPostgreSQL url) Postgres.close $ \connection -> do+ let query =+ [sql|+ CREATE ROLE normal_user + WITH LOGIN PASSWORD 'password' + IN ROLE message_store;+ |]+ in void $ Postgres.execute_ connection query++ let query =+ [sql|+ ALTER ROLE normal_user + SET search_path TO message_store,public;+ |]+ in void $ Postgres.execute_ connection query++ let query =+ [sql|+ ALTER ROLE privileged_user+ SET search_path TO message_store,public;+ |]+ in void $ Postgres.execute_ connection query+++-- | Create and use a temporary message-db for testing.+withConnectionStrings :: (ConnectionStrings -> IO a) -> IO a+withConnectionStrings use = do+ let tempConfig =+ mempty+ { PostgresTemp.connectionOptions =+ mempty+ { PostgresOptions.user = pure "privileged_user"+ }+ , PostgresTemp.initDbConfig =+ Merge $+ mempty+ { PostgresTemp.commandLine =+ mempty{PostgresTemp.keyBased = Map.fromList [("--username=", Just "privileged_user")]}+ }+ , PostgresTemp.postgresConfigFile =+ [ ("message_store.sql_condition", "on")+ ]+ }++ let retryPolicy =+ Retry.limitRetries 10++ exceptionHandlers =+ let restartFor :: forall e a. Exception e => a -> Handler IO Bool+ restartFor _ = Handler @_ @_ @e $ \_ -> pure True+ in [ restartFor @PostgresTemp.StartError+ , restartFor @IOException+ ]++ Retry.recovering retryPolicy exceptionHandlers $ \_ -> do+ result <- PostgresTemp.withConfig tempConfig $ \db -> do+ let options =+ PostgresTemp.toConnectionOptions db++ tempMessageDb =+ let privilegedConnectionString =+ PostgresOptions.toConnectionString $+ options+ { PostgresOptions.dbname = pure "message_store"+ }++ normalConnectionString =+ PostgresOptions.toConnectionString $+ options+ { PostgresOptions.user = pure "normal_user"+ , PostgresOptions.password = pure "password"+ , PostgresOptions.dbname = pure "message_store"+ }+ in ConnectionStrings{..}+ migrate options *> use tempMessageDb++ case result of+ Left err -> throwIO err+ Right value -> pure value