├── .editorconfig ├── .gitignore ├── .travis.deploy.artifacts.sh ├── .travis.maven.settings.xml ├── .travis.yml ├── 100µs-latency.png ├── 1ms-latency.png ├── BENCHMARK.md ├── Dockerfile ├── LICENSE.txt ├── README.adoc ├── RELEASES.adoc ├── docker ├── postgres │ ├── README.md │ ├── docker-compose.yml │ ├── resources │ │ ├── create-postgres.sql │ │ ├── server.crt │ │ └── server.key │ └── ssl.sh └── postgres_tc │ ├── Dockerfile │ ├── README.md │ └── create-postgres.sql ├── docs ├── README.md ├── _config.yml ├── apidocs │ ├── allclasses-frame.html │ ├── allclasses-noframe.html │ ├── constant-values.html │ ├── deprecated-list.html │ ├── help-doc.html │ ├── index-all.html │ ├── index.html │ ├── io │ │ └── reactiverse │ │ │ ├── pgclient │ │ │ ├── Json.html │ │ │ ├── JsonImpl.html │ │ │ ├── Numeric.html │ │ │ ├── PgClient.html │ │ │ ├── PgConnectOptions.html │ │ │ ├── PgConnectOptionsConverter.html │ │ │ ├── PgConnection.html │ │ │ ├── PgCursor.html │ │ │ ├── PgException.html │ │ │ ├── PgIterator.html │ │ │ ├── PgNotification.html │ │ │ ├── PgNotificationConverter.html │ │ │ ├── PgPool.html │ │ │ ├── PgPoolOptions.html │ │ │ ├── PgPoolOptionsConverter.html │ │ │ ├── PgPreparedQuery.html │ │ │ ├── PgResult.html │ │ │ ├── PgRowSet.html │ │ │ ├── PgStream.html │ │ │ ├── PgTransaction.html │ │ │ ├── Row.html │ │ │ ├── SslMode.html │ │ │ ├── Tuple.html │ │ │ ├── class-use │ │ │ │ ├── Json.html │ │ │ │ ├── JsonImpl.html │ │ │ │ ├── Numeric.html │ │ │ │ ├── PgClient.html │ │ │ │ ├── PgConnectOptions.html │ │ │ │ ├── PgConnectOptionsConverter.html │ │ │ │ ├── PgConnection.html │ │ │ │ ├── PgCursor.html │ │ │ │ ├── PgException.html │ │ │ │ ├── PgIterator.html │ │ │ │ ├── PgNotification.html │ │ │ │ ├── PgNotificationConverter.html │ │ │ │ ├── PgPool.html │ │ │ │ ├── PgPoolOptions.html │ │ │ │ ├── PgPoolOptionsConverter.html │ │ │ │ ├── PgPreparedQuery.html │ │ │ │ ├── PgResult.html │ │ │ │ ├── PgRowSet.html │ │ │ │ ├── PgStream.html │ │ │ │ ├── PgTransaction.html │ │ │ │ ├── Row.html │ │ │ │ ├── SslMode.html │ │ │ │ └── Tuple.html │ │ │ ├── data │ │ │ │ ├── Box.html │ │ │ │ ├── BoxConverter.html │ │ │ │ ├── Circle.html │ │ │ │ ├── CircleConverter.html │ │ │ │ ├── Interval.html │ │ │ │ ├── IntervalConverter.html │ │ │ │ ├── Json.html │ │ │ │ ├── Line.html │ │ │ │ ├── LineConverter.html │ │ │ │ ├── LineSegment.html │ │ │ │ ├── LineSegmentConverter.html │ │ │ │ ├── Numeric.html │ │ │ │ ├── Path.html │ │ │ │ ├── PathConverter.html │ │ │ │ ├── Point.html │ │ │ │ ├── PointConverter.html │ │ │ │ ├── Polygon.html │ │ │ │ ├── PolygonConverter.html │ │ │ │ ├── class-use │ │ │ │ │ ├── Box.html │ │ │ │ │ ├── BoxConverter.html │ │ │ │ │ ├── Circle.html │ │ │ │ │ ├── CircleConverter.html │ │ │ │ │ ├── Interval.html │ │ │ │ │ ├── IntervalConverter.html │ │ │ │ │ ├── Json.html │ │ │ │ │ ├── Line.html │ │ │ │ │ ├── LineConverter.html │ │ │ │ │ ├── LineSegment.html │ │ │ │ │ ├── LineSegmentConverter.html │ │ │ │ │ ├── Numeric.html │ │ │ │ │ ├── Path.html │ │ │ │ │ ├── PathConverter.html │ │ │ │ │ ├── Point.html │ │ │ │ │ ├── PointConverter.html │ │ │ │ │ ├── Polygon.html │ │ │ │ │ └── PolygonConverter.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ ├── package-use.html │ │ │ └── pubsub │ │ │ │ ├── PgChannel.html │ │ │ │ ├── PgSubscriber.html │ │ │ │ ├── class-use │ │ │ │ ├── PgChannel.html │ │ │ │ └── PgSubscriber.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ ├── reactivex │ │ │ └── pgclient │ │ │ │ ├── Json.html │ │ │ │ ├── PgClient.html │ │ │ │ ├── PgConnection.html │ │ │ │ ├── PgCursor.html │ │ │ │ ├── PgIterator.html │ │ │ │ ├── PgPool.html │ │ │ │ ├── PgPreparedQuery.html │ │ │ │ ├── PgResult.html │ │ │ │ ├── PgRowSet.html │ │ │ │ ├── PgStream.html │ │ │ │ ├── PgTransaction.html │ │ │ │ ├── Row.html │ │ │ │ ├── Tuple.html │ │ │ │ ├── class-use │ │ │ │ ├── Json.html │ │ │ │ ├── PgClient.html │ │ │ │ ├── PgConnection.html │ │ │ │ ├── PgCursor.html │ │ │ │ ├── PgIterator.html │ │ │ │ ├── PgPool.html │ │ │ │ ├── PgPreparedQuery.html │ │ │ │ ├── PgResult.html │ │ │ │ ├── PgRowSet.html │ │ │ │ ├── PgStream.html │ │ │ │ ├── PgTransaction.html │ │ │ │ ├── Row.html │ │ │ │ └── Tuple.html │ │ │ │ ├── data │ │ │ │ ├── Json.html │ │ │ │ ├── class-use │ │ │ │ │ └── Json.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ ├── package-use.html │ │ │ │ └── pubsub │ │ │ │ ├── PgChannel.html │ │ │ │ ├── PgSubscriber.html │ │ │ │ ├── class-use │ │ │ │ ├── PgChannel.html │ │ │ │ └── PgSubscriber.html │ │ │ │ ├── package-frame.html │ │ │ │ ├── package-summary.html │ │ │ │ ├── package-tree.html │ │ │ │ └── package-use.html │ │ │ └── rxjava │ │ │ └── pgclient │ │ │ ├── Json.html │ │ │ ├── PgClient.html │ │ │ ├── PgConnection.html │ │ │ ├── PgCursor.html │ │ │ ├── PgIterator.html │ │ │ ├── PgPool.html │ │ │ ├── PgPreparedQuery.html │ │ │ ├── PgResult.html │ │ │ ├── PgRowSet.html │ │ │ ├── PgStream.html │ │ │ ├── PgTransaction.html │ │ │ ├── Row.html │ │ │ ├── Tuple.html │ │ │ ├── class-use │ │ │ ├── Json.html │ │ │ ├── PgClient.html │ │ │ ├── PgConnection.html │ │ │ ├── PgCursor.html │ │ │ ├── PgIterator.html │ │ │ ├── PgPool.html │ │ │ ├── PgPreparedQuery.html │ │ │ ├── PgResult.html │ │ │ ├── PgRowSet.html │ │ │ ├── PgStream.html │ │ │ ├── PgTransaction.html │ │ │ ├── Row.html │ │ │ └── Tuple.html │ │ │ ├── data │ │ │ ├── Json.html │ │ │ ├── class-use │ │ │ │ └── Json.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ ├── package-use.html │ │ │ └── pubsub │ │ │ ├── PgChannel.html │ │ │ ├── PgSubscriber.html │ │ │ ├── class-use │ │ │ ├── PgChannel.html │ │ │ └── PgSubscriber.html │ │ │ ├── package-frame.html │ │ │ ├── package-summary.html │ │ │ ├── package-tree.html │ │ │ └── package-use.html │ ├── overview-frame.html │ ├── overview-summary.html │ ├── overview-tree.html │ ├── package-list │ ├── script.js │ ├── serialized-form.html │ └── stylesheet.css ├── guide │ ├── groovy │ │ └── index.md │ ├── java │ │ └── index.md │ ├── js │ │ └── index.md │ ├── kotlin │ │ └── index.md │ └── ruby │ │ └── index.md ├── jsdoc │ ├── fonts │ │ ├── OpenSans-Bold-webfont.eot │ │ ├── OpenSans-Bold-webfont.svg │ │ ├── OpenSans-Bold-webfont.woff │ │ ├── OpenSans-BoldItalic-webfont.eot │ │ ├── OpenSans-BoldItalic-webfont.svg │ │ ├── OpenSans-BoldItalic-webfont.woff │ │ ├── OpenSans-Italic-webfont.eot │ │ ├── OpenSans-Italic-webfont.svg │ │ ├── OpenSans-Italic-webfont.woff │ │ ├── OpenSans-Light-webfont.eot │ │ ├── OpenSans-Light-webfont.svg │ │ ├── OpenSans-Light-webfont.woff │ │ ├── OpenSans-LightItalic-webfont.eot │ │ ├── OpenSans-LightItalic-webfont.svg │ │ ├── OpenSans-LightItalic-webfont.woff │ │ ├── OpenSans-Regular-webfont.eot │ │ ├── OpenSans-Regular-webfont.svg │ │ └── OpenSans-Regular-webfont.woff │ ├── index.html │ ├── json.js.html │ ├── module-reactive-pg-client-js_json-Json.html │ ├── module-reactive-pg-client-js_json.html │ ├── module-reactive-pg-client-js_pg_channel-PgChannel.html │ ├── module-reactive-pg-client-js_pg_channel.html │ ├── module-reactive-pg-client-js_pg_client-PgClient.html │ ├── module-reactive-pg-client-js_pg_client.html │ ├── module-reactive-pg-client-js_pg_connection-PgConnection.html │ ├── module-reactive-pg-client-js_pg_connection.html │ ├── module-reactive-pg-client-js_pg_cursor-PgCursor.html │ ├── module-reactive-pg-client-js_pg_cursor.html │ ├── module-reactive-pg-client-js_pg_iterator-PgIterator.html │ ├── module-reactive-pg-client-js_pg_iterator.html │ ├── module-reactive-pg-client-js_pg_pool-PgPool.html │ ├── module-reactive-pg-client-js_pg_pool.html │ ├── module-reactive-pg-client-js_pg_prepared_query-PgPreparedQuery.html │ ├── module-reactive-pg-client-js_pg_prepared_query.html │ ├── module-reactive-pg-client-js_pg_result-PgResult.html │ ├── module-reactive-pg-client-js_pg_result.html │ ├── module-reactive-pg-client-js_pg_row_set-PgRowSet.html │ ├── module-reactive-pg-client-js_pg_row_set.html │ ├── module-reactive-pg-client-js_pg_stream-PgStream.html │ ├── module-reactive-pg-client-js_pg_stream.html │ ├── module-reactive-pg-client-js_pg_subscriber-PgSubscriber.html │ ├── module-reactive-pg-client-js_pg_subscriber.html │ ├── module-reactive-pg-client-js_pg_transaction-PgTransaction.html │ ├── module-reactive-pg-client-js_pg_transaction.html │ ├── module-reactive-pg-client-js_row-Row.html │ ├── module-reactive-pg-client-js_row.html │ ├── module-reactive-pg-client-js_tuple-Tuple.html │ ├── module-reactive-pg-client-js_tuple.html │ ├── pg_channel.js.html │ ├── pg_client.js.html │ ├── pg_connection.js.html │ ├── pg_cursor.js.html │ ├── pg_iterator.js.html │ ├── pg_pool.js.html │ ├── pg_prepared_query.js.html │ ├── pg_result.js.html │ ├── pg_row_set.js.html │ ├── pg_stream.js.html │ ├── pg_subscriber.js.html │ ├── pg_transaction.js.html │ ├── row.js.html │ ├── scripts │ │ ├── linenumber.js │ │ └── prettify │ │ │ ├── Apache-License-2.0.txt │ │ │ ├── lang-css.js │ │ │ └── prettify.js │ ├── styles │ │ ├── jsdoc-default.css │ │ ├── prettify-jsdoc.css │ │ └── prettify-tomorrow.css │ └── tuple.js.html └── yardoc │ ├── ReactivePgClient.html │ ├── ReactivePgClient │ ├── Json.html │ ├── PgChannel.html │ ├── PgClient.html │ ├── PgConnection.html │ ├── PgCursor.html │ ├── PgIterator.html │ ├── PgPool.html │ ├── PgPreparedQuery.html │ ├── PgResult.html │ ├── PgRowSet.html │ ├── PgStream.html │ ├── PgSubscriber.html │ ├── PgTransaction.html │ ├── Row.html │ └── Tuple.html │ ├── _index.html │ ├── class_list.html │ ├── css │ ├── common.css │ ├── full_list.css │ └── style.css │ ├── file.README.html │ ├── file_list.html │ ├── frames.html │ ├── index.html │ ├── js │ ├── app.js │ ├── full_list.js │ └── jquery.js │ ├── method_list.html │ └── top-level-namespace.html ├── jekyll ├── README.md ├── _config.yml └── docker-compose.yml ├── jitwatch.properties ├── jitwatch.sh ├── pom.xml └── src ├── assembly ├── benchmark.xml └── sources.xml ├── benchmark └── java │ └── io │ └── reactiverse │ └── pgclient │ ├── BenchmarkBase.java │ ├── LargeSelectBenchmark.java │ ├── Main.java │ ├── PgBenchmarkBase.java │ ├── PipelineBenchmark.java │ ├── RawBenchmark.java │ ├── SingleSelectBenchmark.java │ └── UpdateBenchmark.java ├── main ├── asciidoc │ └── dataobjects.adoc ├── docs │ └── index.md ├── java │ ├── examples │ │ ├── Examples.java │ │ └── RxExamples.java │ └── io │ │ └── reactiverse │ │ └── pgclient │ │ ├── PgClient.java │ │ ├── PgConnectOptions.java │ │ ├── PgConnection.java │ │ ├── PgCursor.java │ │ ├── PgException.java │ │ ├── PgIterator.java │ │ ├── PgNotification.java │ │ ├── PgPool.java │ │ ├── PgPoolOptions.java │ │ ├── PgPreparedQuery.java │ │ ├── PgResult.java │ │ ├── PgRowSet.java │ │ ├── PgStream.java │ │ ├── PgTransaction.java │ │ ├── Row.java │ │ ├── SslMode.java │ │ ├── Tuple.java │ │ ├── data │ │ ├── Box.java │ │ ├── Circle.java │ │ ├── Interval.java │ │ ├── Json.java │ │ ├── Line.java │ │ ├── LineSegment.java │ │ ├── Numeric.java │ │ ├── Path.java │ │ ├── Point.java │ │ └── Polygon.java │ │ ├── impl │ │ ├── ArrayTuple.java │ │ ├── CloseConnectionCommand.java │ │ ├── ClosePortalCommand.java │ │ ├── CloseStatementCommand.java │ │ ├── CommandBase.java │ │ ├── CommandResponse.java │ │ ├── CommandScheduler.java │ │ ├── Connection.java │ │ ├── ConnectionPool.java │ │ ├── ExtendedBatchQueryCommand.java │ │ ├── ExtendedQueryCommand.java │ │ ├── ExtendedQueryCommandBase.java │ │ ├── InitCommand.java │ │ ├── PgClientBase.java │ │ ├── PgConnectionBase.java │ │ ├── PgConnectionFactory.java │ │ ├── PgConnectionImpl.java │ │ ├── PgConnectionUriParser.java │ │ ├── PgCursorImpl.java │ │ ├── PgPoolImpl.java │ │ ├── PgPreparedQueryImpl.java │ │ ├── PgResultBase.java │ │ ├── PgResultBuilder.java │ │ ├── PgResultImpl.java │ │ ├── PgRowSetImpl.java │ │ ├── PgStreamImpl.java │ │ ├── PrepareStatementCommand.java │ │ ├── PreparedStatement.java │ │ ├── QueryCommandBase.java │ │ ├── QueryResultHandler.java │ │ ├── RowImpl.java │ │ ├── RowResultDecoder.java │ │ ├── SimpleQueryCommand.java │ │ ├── SocketConnection.java │ │ ├── StringLongSequence.java │ │ ├── Transaction.java │ │ ├── codec │ │ │ ├── ColumnDesc.java │ │ │ ├── DataFormat.java │ │ │ ├── DataType.java │ │ │ ├── DataTypeCodec.java │ │ │ ├── TxStatus.java │ │ │ ├── decoder │ │ │ │ ├── ErrorResponse.java │ │ │ │ ├── InboundMessage.java │ │ │ │ ├── InitiateSslHandler.java │ │ │ │ ├── MessageDecoder.java │ │ │ │ ├── NoticeResponse.java │ │ │ │ ├── NotificationResponse.java │ │ │ │ ├── ParameterDescription.java │ │ │ │ ├── Response.java │ │ │ │ ├── RowDecoder.java │ │ │ │ ├── RowDescription.java │ │ │ │ └── type │ │ │ │ │ ├── AuthenticationType.java │ │ │ │ │ ├── CommandCompleteType.java │ │ │ │ │ ├── ErrorOrNoticeType.java │ │ │ │ │ └── MessageType.java │ │ │ ├── encoder │ │ │ │ ├── Bind.java │ │ │ │ ├── Describe.java │ │ │ │ ├── MessageEncoder.java │ │ │ │ ├── Parse.java │ │ │ │ ├── PasswordMessage.java │ │ │ │ ├── Query.java │ │ │ │ └── StartupMessage.java │ │ │ ├── formatter │ │ │ │ ├── DateTimeFormatter.java │ │ │ │ └── TimeFormatter.java │ │ │ └── util │ │ │ │ ├── MD5Authentication.java │ │ │ │ ├── UTF8StringEndDetector.java │ │ │ │ └── Util.java │ │ ├── data │ │ │ └── JsonImpl.java │ │ └── pubsub │ │ │ └── PgSubscriberImpl.java │ │ ├── package-info.java │ │ └── pubsub │ │ ├── PgChannel.java │ │ └── PgSubscriber.java └── kotlin │ └── io │ └── reactiverse │ └── kotlin │ └── pgclient │ ├── PgClient.kt │ ├── PgConnectOptions.kt │ ├── PgConnection.kt │ ├── PgCursor.kt │ ├── PgNotification.kt │ ├── PgPool.kt │ ├── PgPoolOptions.kt │ ├── PgPreparedQuery.kt │ ├── PgStream.kt │ ├── PgTransaction.kt │ ├── data │ ├── Box.kt │ ├── Circle.kt │ ├── Interval.kt │ ├── Line.kt │ ├── LineSegment.kt │ ├── Path.kt │ ├── Point.kt │ └── Polygon.kt │ └── pubsub │ ├── PgChannel.kt │ └── PgSubscriber.kt └── test └── java └── io └── reactiverse └── pgclient ├── ErrorCodes.java ├── JdbcTest.java ├── JdbcTestBase.java ├── NumericTest.java ├── PgClientTestBase.java ├── PgConnectOptionsProviderTest.java ├── PgConnectionTest.java ├── PgConnectionTestBase.java ├── PgConnectionUriParserTest.java ├── PgPoolTest.java ├── PgPoolTestBase.java ├── PgPooledConnectionTest.java ├── PgTestBase.java ├── PgTransactionTest.java ├── PreparedBatchTest.java ├── PreparedStatementCachedTest.java ├── PreparedStatementTest.java ├── PreparedStatementTestBase.java ├── ProxyServer.java ├── PubSubTest.java ├── RowTest.java ├── RxTest.java ├── StringLongSequenceTest.java ├── TLSTest.java ├── TupleTest.java ├── UnixDomainSocketTest.java ├── UtilTest.java ├── data ├── BinaryDataTypesExtendedCodecTest.java ├── BinaryDataTypesSimpleCodecTest.java ├── BooleanTypeExtendedCodecTest.java ├── BooleanTypeSimpleCodecTest.java ├── CharacterTypesExtendedCodecTest.java ├── CharacterTypesSimpleCodecTest.java ├── ColumnChecker.java ├── CustomTypesExtendedCodecTest.java ├── CustomTypesSimpleCodecTest.java ├── DataTypeTestBase.java ├── DateTimeTypesExtendedCodecTest.java ├── DateTimeTypesSimpleCodecTest.java ├── EnumeratedTypesExtendedCodecTest.java ├── EnumeratedTypesSimpleCodecTest.java ├── ExtendedQueryDataTypeCodecTestBase.java ├── GeometricTypesExtendedCodecTest.java ├── GeometricTypesSimpleCodecTest.java ├── JsonTypesExtendedCodecTest.java ├── JsonTypesSimpleCodecTest.java ├── NullSimpleCodecTest.java ├── NumericTypesExtendedCodecTest.java ├── NumericTypesSimpleCodecTest.java ├── PreparedStatementParamCoercionTest.java ├── SimpleQueryDataTypeCodecTestBase.java ├── UUIDTypeExtendedCodecTest.java └── UUIDTypeSimpleCodecTest.java ├── impl └── codec │ └── util │ └── MD5AuthenticationTest.java ├── it └── EnvTest.java └── pool ├── ConnectionPoolTest.java ├── ConnectionQueue.java ├── SimpleConnection.java └── SimpleHolder.java /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | trim_trailing_whitespace = true 8 | end_of_line = lf 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | jitwatch.out 2 | jekyll/apidocs 3 | jekyll/yardoc 4 | jekyll/guide 5 | jekyll/.* 6 | jekyll/_site 7 | jekyll/jsdoc 8 | *.log 9 | .vertx 10 | .DS_Store 11 | .gradle 12 | .idea 13 | .classpath 14 | .project 15 | .settings 16 | .yardoc 17 | .yardopts 18 | build 19 | target 20 | out 21 | *.iml 22 | *.ipr 23 | *.iws 24 | *.jfr 25 | test-output 26 | Scratch.java 27 | ScratchTest.java 28 | test-results 29 | test-tmp 30 | *.class 31 | ScratchPad.java 32 | src/main/resources/ext-js/*.js 33 | src/main/java/io/vertx/java/**/*.java 34 | *.swp 35 | -------------------------------------------------------------------------------- /.travis.deploy.artifacts.sh: -------------------------------------------------------------------------------- 1 | PROJECT_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -B | grep -v '\[') 2 | if [[ "$PROJECT_VERSION" =~ .*SNAPSHOT ]] && [[ "${TRAVIS_BRANCH}" =~ ^master$|^[0-9]+\.[0-9]+$ ]] && [[ "${TRAVIS_PULL_REQUEST}" = "false" ]]; 3 | then 4 | mvn deploy -s .travis.maven.settings.xml -DskipTests -B; 5 | fi 6 | -------------------------------------------------------------------------------- /.travis.maven.settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | false 7 | 8 | 9 | 10 | sonatype-nexus-snapshots 11 | ${env.SONATYPE_NEXUS_USERNAME} 12 | ${env.SONATYPE_NEXUS_PASSWORD} 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | branches: 3 | only: 4 | - master 5 | - /^\d+\.\d+$/ 6 | jobs: 7 | include: 8 | - stage: test 9 | name: "Postgres 9" 10 | jdk: oraclejdk8 11 | script: mvn -q clean verify -B -Dembedded.postgres.version=9.6 12 | - stage: test 13 | name: "Postgres 10" 14 | jdk: oraclejdk8 15 | script: mvn -q clean verify -B -Dembedded.postgres.version=10.6 16 | - stage: deploy 17 | name: "Deploy to Sonatype's snapshots repository" 18 | if: type != pull_request AND env(SONATYPE_NEXUS_USERNAME) IS present 19 | script: bash .travis.deploy.artifacts.sh 20 | notifications: 21 | email: 22 | recipients: 23 | - secure: "Auz9no9ZKVvY7rtA+CI6fNxXoTHR8xQZRWPWkx3GgBTFOiPlt6NWVmdUnGVdYaBQAV8M5kQ8ldv6Zo1gKWBRIZ9mdrElHPaImP15RqlUhqGdu6EByAHUCx0An3qla2Chsrs9QQAARQHjheWv6mRmRQFeNWVU/X0qSciiK0r40EzRAKuY3zwuNiNIDza12QrCrlQnGvdBf6qnfNrV03Rkxk+AzZHeNP0vjGB57zQCwClZQNIDWwyCdHJDHiMwKC16qQxRJ09RY4EJi0qDTzTFgQ3tL28G7zR8M563ELTVU7ojrAq8AvlZcpiLivjP/RR99owyzm+r9ZHMiPHqJ3cbbisBqtRQSWP8yCKJ9h2GKGlzX9JDZJ+/3smvoPLgUg7yiwjDeX+yFDFL7F5pfzHh0DXxRqRCAGPs4dOho023C6kqiWk94SzzUX8FCKuIm+N5Y9M2KAWvA0s6/KtpIhdi+rpdIImaDwf7LoAFzwvaZnFMS5wB6/wVz/AEiSKOiu05uzaDymRWnupugN6XZd4KY95vB9JCvaLOmjJHvSF8fFGqMVSLopU2ZAZTjWSceOn4/lU/qDThnTuhY9qHCqEcbYWSJ1Jl6cD5ddX++qk+lmhTbvcbIAZ8L+ZKxvanfFl5TtTdYc9vpOFrfMTeOWBo9Oq5/TgZTeDaXCSH1gaM4sQ=" 24 | - secure: "KdmtQ62Cge7jmyj40XVJ/rW6sXuWdwtHIMsaGEg4pc17tMIl2bGI/pnpVt5UVbjq7xYHFwA9DaIh5oyq9hizdDEAx46pGmuDIsATn9TTaWJK35dht6Ri/So2B2mAhDJrz3s7HDFb4IYI72Cgp2ukw/q6R6pHDt/xHyT4h+/YmTzXPUhyrduO0nQHvTCyUqUsyOTL4uC/HyBnAID9UtCgEJBCWAnATQc3sMRw9VqgQmLQeEPmIaor9UNxrS4sNpnHCPrsjNfGN4sSfAbRcNENsh7iyM6b+aPKm6hh/KPlYQ59FHqXXAxeYrdXAoObN8heg5TFH6v20g3n2mLeVvJFgCF8Dq6dJCPAqgMsENcB2OdunRop1bUEzLRQicKscZ7vd+9FOXX8cYP7zKLiEWJs/bU1sTQ3vbHqtReC8yWlQTKYeNMlw9cFJvSZLZ+GqetNgcoH4DiCrOiDpqWCgHGZ+98E1U5CEwpBcqRo9hfwtS8vSQjy08t/LvEIZqGTuD+nmsgN7tPhh9qrfLGk76pzF4QzYVManXd1WDIInWuOKbDjUdRuGHDc1TSwqBVjGoe9w0VI25fT1H/osTWgXon/I/vSTnFrJOYmZvthL+OUR3ptuYXUcGZQZtiVSQs71dAoTChBlf9dNJhLqLk7VK304XQL7peYn4PuofEYW+SFAB8=" 25 | on_success: always 26 | on_failure: always 27 | -------------------------------------------------------------------------------- /100µs-latency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/100µs-latency.png -------------------------------------------------------------------------------- /1ms-latency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/1ms-latency.png -------------------------------------------------------------------------------- /BENCHMARK.md: -------------------------------------------------------------------------------- 1 | ## Client Benchmarking 2 | 3 | ### Running the query benchmark 4 | 5 | Runs query operations with 8 threads 6 | 7 | ``` 8 | > mvn clean package -Pbenchmark 9 | > java -jar target/vertx-pg-client-0.3.1-SNAPSHOT-benchmark.jar 10 | ``` 11 | 12 | You can profile the benchmark 13 | 14 | ``` 15 | > java -jar target/vertx-pg-client-0.3.1-SNAPSHOT-benchmark.jar SingleSelectBenchmark.poolPreparedQuery -jvmArgsAppend "-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=./profiling-data.jfr,name=profile,settings=profile" 16 | ``` 17 | 18 | just make sure to run one benchmark at a time. 19 | 20 | ## Client performance 21 | 22 | ### Outbound message size estimation 23 | 24 | Some messages are really small, and it would be good allocate the right size instead of 256 by default. 25 | 26 | ### Row decoding 27 | 28 | Investigate plugability of row decoder that can operate on `@DataObject` directly. 29 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # We're using the official Maven 3 image from the Docker Hub (https://hub.docker.com/_/maven/). 2 | # Take a look at the available versions so you can specify the Java version you want to use. 3 | FROM maven:3 4 | 5 | # INSTALL any further tools you need here so they are cached in the docker build 6 | 7 | WORKDIR /app 8 | 9 | # Copy the whole repository into the image 10 | COPY . ./ 11 | 12 | # Run install task so all necessary dependencies are downloaded and cached in 13 | # the Docker image. We're running through the whole process but disable 14 | # testing and make sure the command doesn't fail. 15 | RUN mvn install clean --fail-never -B -DfailIfNoTests=false 16 | 17 | -------------------------------------------------------------------------------- /docker/postgres/README.md: -------------------------------------------------------------------------------- 1 | ## Postgres containers for testing 2 | 3 | There will be 2 Postgres containers for testing, one with SSL enabled is for `TLSTest` and the other one with SSL disabled is for all other tests. 4 | 5 | ### Configure the containers 6 | 7 | modify the content in the `docker-compose.yml` 8 | 9 | ### Run the containers 10 | 11 | ``` 12 | > docker-compose up --build -V 13 | ``` 14 | 15 | ### Run tests 16 | 17 | ``` 18 | > mvn test -Dconnection.uri=postgres://postgres:postgres@localhost:5432/postgres -Dtls.connection.uri=postgres://postgres:postgres@localhost:5433/postgres -Dunix.socket.directory=/var/run/postgresql -Dunix.socket.port=5432 19 | ``` 20 | -------------------------------------------------------------------------------- /docker/postgres/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | test-postgres: 5 | image: healthcheck/postgres:alpine 6 | ports: 7 | - "5432:5432" 8 | environment: 9 | POSTGRES_USER: postgres 10 | POSTGRES_PASSWORD: postgres 11 | POSTGRES_DB: postgres 12 | volumes: 13 | - /var/run/postgresql:/var/run/postgresql 14 | - ./resources/create-postgres.sql:/docker-entrypoint-initdb.d/create-postgres.sql 15 | tls-test-postgres: 16 | image: healthcheck/postgres:alpine 17 | ports: 18 | - "5433:5432" 19 | environment: 20 | POSTGRES_USER: postgres 21 | POSTGRES_PASSWORD: postgres 22 | POSTGRES_DB: postgres 23 | volumes: 24 | - ./resources/create-postgres.sql:/docker-entrypoint-initdb.d/create-postgres.sql 25 | - ./resources/server.crt:/server.crt 26 | - ./resources/server.key:/server.key 27 | - ./ssl.sh:/docker-entrypoint-initdb.d/ssl.sh 28 | -------------------------------------------------------------------------------- /docker/postgres/resources/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDeDCCAuGgAwIBAgIJAPsnSZ7KK38hMA0GCSqGSIb3DQEBBQUAMIGFMQswCQYD 3 | VQQGEwJDQTEZMBcGA1UECBMQQnJpdGlzaCBDb2x1bWJpYTEOMAwGA1UEBxMFQ29t 4 | b3gxFDASBgNVBAoTC1RoZUJyYWluLmNhMRQwEgYDVQQDEwt0aGVicmFpbi5jYTEf 5 | MB0GCSqGSIb3DQEJARYQaW5mb0B0aGVicmFpbi5jYTAeFw0xNzA5MTUyMTE3MzVa 6 | Fw0yNzA5MTMyMTE3MzVaMIGFMQswCQYDVQQGEwJDQTEZMBcGA1UECBMQQnJpdGlz 7 | aCBDb2x1bWJpYTEOMAwGA1UEBxMFQ29tb3gxFDASBgNVBAoTC1RoZUJyYWluLmNh 8 | MRQwEgYDVQQDEwt0aGVicmFpbi5jYTEfMB0GCSqGSIb3DQEJARYQaW5mb0B0aGVi 9 | cmFpbi5jYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA3ZjwfKKfhp4bHX7l 10 | vdfov6SbGYu8nTz/DhcIt+dY8f1SfjLMtJhI0BCaBNUrC3F5K02val9EUF8HIQFo 11 | HmrUXVVnN54Suca+HuJiJGMBxIPOy8EJsHWybqNdwq3SIUTzODpYQNjTiTR/Dlw6 12 | OLZNFR9d1YgDCdaYAmI/g+V4tbcCAwEAAaOB7TCB6jAdBgNVHQ4EFgQUNLQbcLVw 13 | R2EbXG/ecZkqWIiKgMswgboGA1UdIwSBsjCBr4AUNLQbcLVwR2EbXG/ecZkqWIiK 14 | gMuhgYukgYgwgYUxCzAJBgNVBAYTAkNBMRkwFwYDVQQIExBCcml0aXNoIENvbHVt 15 | YmlhMQ4wDAYDVQQHEwVDb21veDEUMBIGA1UEChMLVGhlQnJhaW4uY2ExFDASBgNV 16 | BAMTC3RoZWJyYWluLmNhMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHRoZWJyYWluLmNh 17 | ggkA+ydJnsorfyEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQDcb+Tt 18 | 1ULpXaWbmwxqjCK9XY3v1k0yPvoArawsQ2LEiJdF7hILlHCzwBxSqkWL2SHqb0NA 19 | /w+8YKv/EGGyoE3LC9tkXt8oO5rnQGEclt74Jz3Q1yFIRpHn5iF4Jd763Z0/ohxe 20 | WLZHrlllNHEw9xIiYgJFlFgPaj1rD0dR8MwcTg== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /docker/postgres/resources/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXgIBAAKBgQDdmPB8op+GnhsdfuW91+i/pJsZi7ydPP8OFwi351jx/VJ+Msy0 3 | mEjQEJoE1SsLcXkrTa9qX0RQXwchAWgeatRdVWc3nhK5xr4e4mIkYwHEg87LwQmw 4 | dbJuo13CrdIhRPM4OlhA2NOJNH8OXDo4tk0VH13ViAMJ1pgCYj+D5Xi1twIDAQAB 5 | AoGBAJayIxkfHo1Vh+sPGP15jvaE4lUFCkeD64+RaoRl977ZHvhjY4KM7TdRkuwm 6 | axdlG5mvQtN75eEiPp7bbgsBa1ipeFAfIM0UZkhRdP0vw+BmTnPaymycR4CP3mRO 7 | 0Nsm0TIFnBpEVWJmVL9QHcw7TXqzsxyO+t1+i+s0cqVc8msBAkEA8Zp9vBBD/e2w 8 | 8nWZ+XzY5V3fuZ1TdAaD9g1dGQZ5DQLEV708bsdJuru77YAQP5yKpmvzU5cl3LFC 9 | /3ryja1OMQJBAOrNRLUza8htYA+lgZuloy+E2lSKguyxlkQuagI5YTligFhYkiyo 10 | WuNGNSIMqdAaVZ7eNu3ADKLEjI994f3SQGcCQCdE0QLsMeDn7Ua7Tpd6b1Z4d5CX 11 | vaSyGmi3q1YR80LmHDuWimgHBDjRoq3rjriIHREHorkHbCP+u8ECnsHgVUECQQCB 12 | VU3qTYeqH+0Q0UaB+IvZieFFPgJ95Bf0OGi2Dusp08MEZs0lghqGI87ykW0cLtVI 13 | q/gvn2CWa5NNGrbXu+8zAkEAuI/0x026m7cr1JCQUCAEHqNa9x1mTNmmqGwkArvy 14 | BU0Zt8XlJcrO6uPH/MJCW4OCE48GLFqeSV3dANKhUgsSqg== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /docker/postgres/ssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Borrowed from https://github.com/muccg/docker-postgres-ssl/blob/master/9.6/docker-entrypoint-initdb.d/devssl.sh 4 | 5 | cp /server.crt "${PGDATA}"/server.crt 6 | cp /server.key "${PGDATA}"/server.key 7 | chmod og-rwx "${PGDATA}"/server.key 8 | chown -R postgres:postgres "${PGDATA}" 9 | 10 | # turn on ssl 11 | sed -ri "s/^#?(ssl\s*=\s*)\S+/\1'on'/" "$PGDATA/postgresql.conf" 12 | -------------------------------------------------------------------------------- /docker/postgres_tc/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres 2 | ENV POSTGRES_DB postgres 3 | ENV POSTGRES_USER postgres 4 | ENV POSTGRES_PASSWORD postgres 5 | RUN apt-get update && apt-get install -y iproute 6 | COPY create-postgres.sql /docker-entrypoint-initdb.d/ 7 | -------------------------------------------------------------------------------- /docker/postgres_tc/README.md: -------------------------------------------------------------------------------- 1 | ## Postgres docker file for testing with tc 2 | 3 | Build container with tc installed 4 | 5 | ``` 6 | > docker build -t test/postgres_tc postgres 7 | ``` 8 | 9 | Running the container 10 | 11 | ``` 12 | > docker run --rm --name test-postgres_tc -p 5432:5432 --cap-add=NET_ADMIN test/postgres_tc 13 | ``` 14 | 15 | Add one 1 ms latency to eth0 16 | 17 | ``` 18 | > docker exec -it test-postgres_tc tc qdisc add dev eth0 root netem delay 1ms 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | 2 | # The Reactive Postgres Client 3 | 4 | * Simple API focusing on scalability and low overhead. 5 | * Reactive and non blocking which able to handle many database connections with a single thread. 6 | * Ranked 1 in the [TechEmpower Benchmark Round 15](https://www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=db) _Single query_ benchmark. 7 | * Top ranked in the TechEmpower Benchmark Round 16 8 | * Single query benchmark: [Ranked 1 physical](https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=db) / [Ranked 1 cloud](https://www.techempower.com/benchmarks/#section=data-r16&hw=cl&test=db) 9 | * Multiples queries benchmark: [Ranked 1 physical](https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=query) / [Ranked 1 cloud](https://www.techempower.com/benchmarks/#section=data-r16&hw=cl&test=query) 10 | * Data updates: [Ranked 1 physical](https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=update) / [Ranked 1 cloud](https://www.techempower.com/benchmarks/#section=data-r16&hw=cl&test=update) 11 | * Fortunes: [Ranked 3 physical](https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=fortune) / [Ranked 2 cloud](https://www.techempower.com/benchmarks/#section=data-r16&hw=cl&test=fortune) 12 | 13 | ## Features 14 | 15 | * Event driven 16 | * Lightweight 17 | * Built-in connection pooling 18 | * Prepared queries caching 19 | * Publish / subscribe using Postgres `NOTIFY/LISTEN` 20 | * Batch and cursor 21 | * Row streaming 22 | * `java.util.stream.Collector` row set transformation 23 | * Command pipeling 24 | * RxJava 1 and RxJava 2 25 | * Direct memory to object without unnecessary copies 26 | * Java 8 Date and Time 27 | * SSL/TLS 28 | * Unix domain socket 29 | * HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy support 30 | 31 | ## Documentation 32 | 33 | * [Java](guide/java/index.md) 34 | * [Kotlin](guide/kotlin/index.md) 35 | * [Groovy](guide/groovy/index.md) 36 | * [JavaScript](guide/js/index.md) 37 | * [Ruby](guide/ruby/index.md) 38 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | repository: reactiverse/reactive-pg-client 3 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/pgclient/pubsub/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.pgclient.pubsub (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.pgclient.pubsub

14 |
15 |

Interfaces

16 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/reactivex/pgclient/data/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.reactivex.pgclient.data (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.reactivex.pgclient.data

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/reactivex/pgclient/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.reactivex.pgclient (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.reactivex.pgclient

14 |
15 |

Classes

16 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/reactivex/pgclient/pubsub/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.reactivex.pgclient.pubsub (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.reactivex.pgclient.pubsub

14 |
15 |

Classes

16 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/rxjava/pgclient/data/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.rxjava.pgclient.data (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.rxjava.pgclient.data

14 |
15 |

Classes

16 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/rxjava/pgclient/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.rxjava.pgclient (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.rxjava.pgclient

14 |
15 |

Classes

16 | 30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /docs/apidocs/io/reactiverse/rxjava/pgclient/pubsub/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | io.reactiverse.rxjava.pgclient.pubsub (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |

io.reactiverse.rxjava.pgclient.pubsub

14 |
15 |

Classes

16 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/apidocs/overview-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Overview List (Reactive Postgres Client 0.11.2 API) 8 | 9 | 10 | 11 | 12 | 13 |
All Classes
14 |
15 |

Packages

16 | 27 |
28 |

 

29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/apidocs/package-list: -------------------------------------------------------------------------------- 1 | io.reactiverse.pgclient 2 | io.reactiverse.pgclient.data 3 | io.reactiverse.pgclient.pubsub 4 | io.reactiverse.reactivex.pgclient 5 | io.reactiverse.reactivex.pgclient.data 6 | io.reactiverse.reactivex.pgclient.pubsub 7 | io.reactiverse.rxjava.pgclient 8 | io.reactiverse.rxjava.pgclient.data 9 | io.reactiverse.rxjava.pgclient.pubsub 10 | -------------------------------------------------------------------------------- /docs/apidocs/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/jsdoc/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vietj/reactive-pg-client/5250ef2a67f3d9c45ccdd37d93ca50f378218f18/docs/jsdoc/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/jsdoc/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (function() { 3 | var source = document.getElementsByClassName('prettyprint source linenums'); 4 | var i = 0; 5 | var lineNumber = 0; 6 | var lineId; 7 | var lines; 8 | var totalLines; 9 | var anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = 'line' + lineNumber; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/jsdoc/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/jsdoc/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/yardoc/css/common.css: -------------------------------------------------------------------------------- 1 | /* Override this file with custom rules */ -------------------------------------------------------------------------------- /docs/yardoc/file_list.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | File List 19 | 20 | 21 | 22 | 32 |
33 |

File List

34 | 49 | 50 | 51 | 58 |
59 | 60 | 61 | -------------------------------------------------------------------------------- /docs/yardoc/frames.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | Documentation by YARD 0.8.7.6 8 | 9 | 20 | 26 | 27 | -------------------------------------------------------------------------------- /jekyll/README.md: -------------------------------------------------------------------------------- 1 | 2 | # The Reactive Postgres Client 3 | 4 | * Simple API focusing on scalability and low overhead. 5 | * Reactive and non blocking which able to handle many database connections with a single thread. 6 | * Ranked *#1* in the [TechEmpower Benchmark Round 15](https://www.techempower.com/benchmarks/#section=data-r15&hw=ph&test=db) _Single query_ benchmark. 7 | 8 | ## Features 9 | 10 | * Event driven 11 | * Lightweight 12 | * Built-in connection pooling 13 | * Prepared queries caching 14 | * Publish / subscribe using Postgres `LISTEN/NOTIFY` 15 | * Batch and cursor support 16 | * Row streaming 17 | * Command pipeling 18 | * RxJava 1 and RxJava 2 support 19 | * Direct memory to object without unnecessary copies 20 | * Java 8 Date and Time support 21 | * SSL/TLS support 22 | * HTTP/1.x CONNECT, SOCKS4a or SOCKS5 proxy support 23 | 24 | ## Documentation 25 | 26 | * [Java](guide/java/index.md) 27 | * [Kotlin](guide/kotlin/index.md) 28 | * [Groovy](guide/groovy/index.md) 29 | * [JavaScript](guide/js/index.md) 30 | * [Ruby](guide/ruby/index.md) 31 | -------------------------------------------------------------------------------- /jekyll/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal 2 | repository: reactiverse/reactive-pg-client 3 | -------------------------------------------------------------------------------- /jekyll/docker-compose.yml: -------------------------------------------------------------------------------- 1 | jekyll: 2 | image: jekyll/jekyll:pages 3 | command: jekyll serve --watch --incremental 4 | ports: 5 | - 4000:4000 6 | volumes: 7 | - .:/srv/jekyll 8 | -------------------------------------------------------------------------------- /jitwatch.properties: -------------------------------------------------------------------------------- 1 | #Thu Dec 14 09:48:37 CET 2017 2 | sandbox.on.stack.replacement=0 3 | Sources=/Users/julien/java/vertx-pg-client/src/main/java,/Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/src.zip,/Users/julien/java/vertx-pg-client/src/benchmark/java,/Users/julien/java/vertx-pg-client/src/test/java 4 | HideInterfaces=true 5 | sandbox.disable.inlining=false 6 | sandbox.intel.mode=false 7 | sandbox.print.assembly=true 8 | JitOnlyClasses=false 9 | Classes=/Users/julien/java/vertx-pg-client/target/classes,/Users/julien/java/vertx-pg-client/target/test-classes 10 | sandbox.compressed.oops.mode=0 11 | triview.local_asm_labels=true 12 | sandbox.tiered.mode=0 13 | sandbox.compiler.threshold=10000 14 | ShowNothingMounted=true 15 | sandbox.background.compilation=2 16 | sandbox.freq.inline.size=35 17 | sandbox.extra.vm.switches= 18 | LastLogDir=/Users/julien/java/vertx-pg-client 19 | last.profile=Default 20 | triview.mouse_follow=false 21 | sandbox.max.inline.size=325 22 | LastSandboxEditorPanes= 23 | JitOnly=true 24 | -------------------------------------------------------------------------------- /jitwatch.sh: -------------------------------------------------------------------------------- 1 | java -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -jar target/vertx-pg-client-0.3.1-SNAPSHOT-benchmarks.jar 2 | -------------------------------------------------------------------------------- /src/assembly/benchmark.xml: -------------------------------------------------------------------------------- 1 | 4 | benchmark 5 | 6 | jar 7 | 8 | false 9 | 10 | 11 | ${project.build.testOutputDirectory} 12 | / 13 | 14 | 15 | 16 | 17 | / 18 | true 19 | test 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/assembly/sources.xml: -------------------------------------------------------------------------------- 1 | 4 | sources 5 | 6 | jar 7 | 8 | false 9 | 10 | 11 | ${project.basedir}/src/main/java 12 | ./ 13 | 14 | 15 | ${project.build.directory}/generated-sources/annotations 16 | ./ 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/benchmark/java/io/reactiverse/pgclient/BenchmarkBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient; 18 | 19 | import org.openjdk.jmh.annotations.*; 20 | 21 | import java.util.concurrent.TimeUnit; 22 | 23 | /** 24 | * @author Julien Viet 25 | */ 26 | @Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS) 27 | @Measurement(iterations = 10, time = 2, timeUnit = TimeUnit.SECONDS) 28 | @Threads(1) 29 | @BenchmarkMode(Mode.Throughput) 30 | @Fork(value = 1, jvmArgs = { 31 | "-XX:+UseBiasedLocking", 32 | "-XX:BiasedLockingStartupDelay=0", 33 | "-XX:+AggressiveOpts", 34 | }) 35 | @OutputTimeUnit(TimeUnit.SECONDS) 36 | public abstract class BenchmarkBase { 37 | } 38 | -------------------------------------------------------------------------------- /src/benchmark/java/io/reactiverse/pgclient/PgBenchmarkBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.vertx.core.Vertx; 21 | import org.openjdk.jmh.annotations.*; 22 | 23 | import java.util.concurrent.CountDownLatch; 24 | 25 | @State(Scope.Thread) 26 | public abstract class PgBenchmarkBase extends BenchmarkBase { 27 | 28 | @Param("localhost") 29 | String host; 30 | 31 | @Param("8081") 32 | int port; 33 | 34 | @Param("postgres") 35 | String database; 36 | 37 | @Param("postgres") 38 | String username; 39 | 40 | @Param("postgres") 41 | String password; 42 | 43 | @Param("1") 44 | int pipeliningLimit; 45 | 46 | Vertx vertx; 47 | PgPool pool; 48 | 49 | @Setup 50 | public void setup() throws Exception { 51 | vertx = Vertx.vertx(); 52 | pool = PgClient.pool(vertx, new PgPoolOptions() 53 | .setHost(host) 54 | .setPort(port) 55 | .setDatabase(database) 56 | .setUser(username) 57 | .setPassword(password) 58 | .setCachePreparedStatements(true) 59 | .setPipeliningLimit(pipeliningLimit) 60 | .setMaxSize(1)); 61 | } 62 | 63 | @TearDown 64 | public void tearDown() throws Exception { 65 | CountDownLatch latch = new CountDownLatch(1); 66 | vertx.close(ar -> { 67 | latch.countDown(); 68 | }); 69 | latch.await(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/benchmark/java/io/reactiverse/pgclient/PipelineBenchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient; 18 | 19 | import org.openjdk.jmh.annotations.Benchmark; 20 | import org.openjdk.jmh.infra.Blackhole; 21 | 22 | import java.util.concurrent.CompletableFuture; 23 | import java.util.concurrent.atomic.AtomicInteger; 24 | 25 | public class PipelineBenchmark extends PgBenchmarkBase { 26 | 27 | public static final int ITER = 25; 28 | 29 | Tuple args; 30 | 31 | @Override 32 | public void setup() throws Exception { 33 | super.setup(); 34 | args = Tuple.of(1); 35 | } 36 | 37 | @Benchmark 38 | public void test1(Blackhole blackhole) throws Exception { 39 | CompletableFuture latch = new CompletableFuture<>(); 40 | AtomicInteger count = new AtomicInteger(); 41 | for (int i = 0;i < ITER;i++) { 42 | pool.query("SELECT id, randomnumber from WORLD where id=1", ar -> { 43 | if (ar.succeeded()) { 44 | if (count.incrementAndGet() == ITER) { 45 | latch.complete(ar.result()); 46 | } 47 | } else { 48 | latch.completeExceptionally(ar.cause()); 49 | } 50 | }); 51 | } 52 | blackhole.consume(latch.get()); 53 | } 54 | 55 | @Benchmark 56 | public void test2(Blackhole blackhole) throws Exception { 57 | CompletableFuture latch = new CompletableFuture<>(); 58 | doSingle(0, latch); 59 | blackhole.consume(latch.get()); 60 | } 61 | 62 | private void doSingle(int count, CompletableFuture latch) { 63 | pool.query("SELECT id, randomnumber from WORLD where id=1", ar -> { 64 | if (ar.succeeded()) { 65 | if (count + 1 == ITER) { 66 | latch.complete(ar.result()); 67 | } else { 68 | doSingle(count + 1, latch); 69 | } 70 | } else { 71 | latch.completeExceptionally(ar.cause()); 72 | } 73 | }); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/benchmark/java/io/reactiverse/pgclient/UpdateBenchmark.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import org.openjdk.jmh.annotations.Benchmark; 21 | import org.openjdk.jmh.annotations.Threads; 22 | import org.openjdk.jmh.infra.Blackhole; 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.Random; 27 | import java.util.concurrent.CompletableFuture; 28 | 29 | @Threads(8) 30 | public class UpdateBenchmark extends PgBenchmarkBase { 31 | 32 | List batch; 33 | 34 | @Override 35 | public void setup() throws Exception { 36 | super.setup(); 37 | int len = 10; 38 | batch = new ArrayList<>(); 39 | Random random = new Random(); 40 | for (int id = 0;id < len;id++) { 41 | batch.add(Tuple.of(1 + random.nextInt(10000), id)); 42 | } 43 | } 44 | 45 | @Benchmark 46 | public void poolPreparedBatchUpdate(Blackhole blackhole) throws Exception { 47 | CompletableFuture> latch = new CompletableFuture<>(); 48 | pool.preparedBatch("UPDATE world SET randomnumber=$1 WHERE id=$2", batch, ar -> { 49 | if (ar.succeeded()) { 50 | latch.complete(ar.result()); 51 | } else { 52 | latch.completeExceptionally(ar.cause()); 53 | } 54 | }); 55 | blackhole.consume(latch.get()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgCursor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.vertx.codegen.annotations.VertxGen; 21 | import io.vertx.core.AsyncResult; 22 | import io.vertx.core.Handler; 23 | 24 | /** 25 | * A cursor that reads progressively the rows from Postgres, it is usefull for reading very large result. 26 | */ 27 | @VertxGen 28 | public interface PgCursor { 29 | 30 | /** 31 | * Read rows from the cursor, the result is provided asynchronously to the {@code handler}. 32 | * 33 | * @param count the amount of rows to read 34 | * @param handler the handler for the result 35 | */ 36 | void read(int count, Handler> handler); 37 | 38 | /** 39 | * Returns {@code true} when the cursor has results in progress and the {@link #execute} should be called to retrieve 40 | * them. 41 | * 42 | * @return whether the cursor has more results, 43 | */ 44 | boolean hasMore(); 45 | 46 | /** 47 | * Release the cursor. 48 | *

49 | * It should be called for prepared queries executed with a fetch size. 50 | */ 51 | default void close() { 52 | close(ar -> {}); 53 | } 54 | 55 | /** 56 | * Like {@link #close()} but with a {@code completionHandler} called when the cursor has been released. 57 | */ 58 | void close(Handler> completionHandler); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.reactiverse.pgclient.impl.codec.decoder.ErrorResponse; 21 | 22 | /** 23 | * @author Julien Viet 24 | */ 25 | public class PgException extends RuntimeException { 26 | 27 | private final ErrorResponse error; 28 | 29 | public PgException(ErrorResponse error) { 30 | super(error.getMessage()); 31 | this.error = error; 32 | } 33 | 34 | public String getSeverity() { 35 | return error.getSeverity(); 36 | } 37 | 38 | public String getCode() { 39 | return error.getCode(); 40 | } 41 | 42 | /** 43 | * @return the detail error message 44 | */ 45 | public String getDetail() { 46 | return error.getDetail(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient; 18 | 19 | import io.vertx.codegen.annotations.VertxGen; 20 | 21 | import java.util.Iterator; 22 | 23 | /** 24 | * An iterator for processing postgres items synchronously. 25 | */ 26 | @VertxGen 27 | public interface PgIterator extends Iterator { 28 | 29 | @Override 30 | boolean hasNext(); 31 | 32 | @Override 33 | Row next(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgNotification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient; 18 | 19 | import io.vertx.codegen.annotations.DataObject; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | /** 23 | * A notification emited by Postgres. 24 | */ 25 | @DataObject(generateConverter = true) 26 | public class PgNotification { 27 | 28 | private int processId; 29 | private String channel; 30 | private String payload; 31 | 32 | public PgNotification() { 33 | } 34 | 35 | public PgNotification(JsonObject json) { 36 | PgNotificationConverter.fromJson(json, this); 37 | } 38 | 39 | /** 40 | * @return the notification process id 41 | */ 42 | public int getProcessId() { 43 | return processId; 44 | } 45 | 46 | /** 47 | * Set the process id. 48 | * 49 | * @return a reference to this, so the API can be used fluently 50 | */ 51 | public PgNotification setProcessId(int processId) { 52 | this.processId = processId; 53 | return this; 54 | } 55 | 56 | /** 57 | * @return the notification channel value 58 | */ 59 | public String getChannel() { 60 | return channel; 61 | } 62 | 63 | /** 64 | * Set the channel value. 65 | * 66 | * @return a reference to this, so the API can be used fluently 67 | */ 68 | public PgNotification setChannel(String channel) { 69 | this.channel = channel; 70 | return this; 71 | } 72 | 73 | /** 74 | * @return the notification payload value 75 | */ 76 | public String getPayload() { 77 | return payload; 78 | } 79 | 80 | /** 81 | * Set the payload value. 82 | * 83 | * @return a reference to this, so the API can be used fluently 84 | */ 85 | public PgNotification setPayload(String payload) { 86 | this.payload = payload; 87 | return this; 88 | } 89 | 90 | public JsonObject toJson() { 91 | JsonObject json = new JsonObject(); 92 | PgNotificationConverter.toJson(this, json); 93 | return json; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.vertx.codegen.annotations.VertxGen; 21 | 22 | import java.util.List; 23 | 24 | /** 25 | * Represents the result of an operation on database. 26 | * @param 27 | */ 28 | @VertxGen 29 | public interface PgResult { 30 | 31 | /** 32 | * Get the number of the affected rows in the operation to this PgResult. 33 | *

34 | * The meaning depends on the executed statement: 35 | *

    36 | *
  • INSERT: the number of rows inserted
  • 37 | *
  • DELETE: the number of rows deleted
  • 38 | *
  • UPDATE: the number of rows updated
  • 39 | *
  • SELECT: the number of rows retrieved
  • 40 | *
41 | * 42 | * @return the count of affected rows. 43 | */ 44 | int rowCount(); 45 | 46 | /** 47 | * Get the names of columns in the PgResult. 48 | * 49 | * @return the list of names of columns. 50 | */ 51 | List columnsNames(); 52 | 53 | /** 54 | * Get the number of rows in the PgResult. 55 | * 56 | * @return the count of rows. 57 | */ 58 | int size(); 59 | 60 | /** 61 | * Get the result value. 62 | * 63 | * @return the result 64 | */ 65 | T value(); 66 | 67 | /** 68 | * Return the next available result or {@code null}, e.g for a simple query that executed multiple queries or for 69 | * a batch result. 70 | * 71 | * @return the next available result or {@code null} if none is available 72 | */ 73 | PgResult next(); 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgRowSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.vertx.codegen.annotations.VertxGen; 21 | 22 | /** 23 | * A set of rows. 24 | */ 25 | @VertxGen 26 | public interface PgRowSet extends Iterable, PgResult { 27 | 28 | @Override 29 | PgIterator iterator(); 30 | 31 | @Override 32 | PgRowSet next(); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/PgStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.vertx.codegen.annotations.VertxGen; 21 | import io.vertx.core.AsyncResult; 22 | import io.vertx.core.Handler; 23 | import io.vertx.core.streams.ReadStream; 24 | 25 | /** 26 | * A row oriented stream. 27 | */ 28 | @VertxGen 29 | public interface PgStream extends ReadStream { 30 | 31 | @Override 32 | PgStream exceptionHandler(Handler handler); 33 | 34 | @Override 35 | PgStream handler(Handler handler); 36 | 37 | @Override 38 | PgStream pause(); 39 | 40 | @Override 41 | PgStream resume(); 42 | 43 | @Override 44 | PgStream endHandler(Handler endHandler); 45 | 46 | /** 47 | * Close the stream and release the resources. 48 | */ 49 | void close(); 50 | 51 | /** 52 | * Close the stream and release the resources. 53 | * 54 | * @param completionHandler the completion handler for this operation 55 | */ 56 | void close(Handler> completionHandler); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/SslMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient; 18 | 19 | /** 20 | * The different values for the sslmode parameter provide different levels of protection. 21 | * See more information in Protection Provided in Different Modes. 22 | */ 23 | public enum SslMode { 24 | 25 | /** 26 | * only try a non-SSL connection. 27 | */ 28 | DISABLE("disable"), 29 | 30 | /** 31 | * first try a non-SSL connection; if that fails, try an SSL connection. 32 | */ 33 | ALLOW("allow"), 34 | 35 | /** 36 | * first try an SSL connection; if that fails, try a non-SSL connection. 37 | */ 38 | PREFER("prefer"), 39 | 40 | /** 41 | * only try an SSL connection. If a root CA file is present, verify the certificate in the same way as if verify-ca was specified. 42 | */ 43 | REQUIRE("require"), 44 | 45 | /** 46 | * only try an SSL connection, and verify that the server certificate is issued by a trusted certificate authority (CA). 47 | */ 48 | VERIFY_CA("verify-ca"), 49 | 50 | /** 51 | * only try an SSL connection, verify that the server certificate is issued by a trusted CA and that the requested server host name matches that in the certificate. 52 | */ 53 | VERIFY_FULL("verify-full"); 54 | 55 | public static final SslMode[] VALUES = SslMode.values(); 56 | 57 | public final String value; 58 | 59 | SslMode(String value) { 60 | this.value = value; 61 | } 62 | 63 | public static SslMode of(String value) { 64 | for (SslMode sslMode : VALUES) { 65 | if (sslMode.value.equalsIgnoreCase(value)) { 66 | return sslMode; 67 | } 68 | } 69 | 70 | throw new IllegalArgumentException("Could not find an appropriate SSL mode for the value [" + value + "]."); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Box.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | /** 7 | * Rectangular box data type in Postgres represented by pairs of {@link Point}s that are opposite corners of the box. 8 | */ 9 | @DataObject(generateConverter = true) 10 | public class Box { 11 | private Point upperRightCorner, lowerLeftCorner; 12 | 13 | public Box() { 14 | this(new Point(), new Point()); 15 | } 16 | 17 | public Box(Point upperRightCorner, Point lowerLeftCorner) { 18 | this.upperRightCorner = upperRightCorner; 19 | this.lowerLeftCorner = lowerLeftCorner; 20 | } 21 | 22 | public Box(JsonObject json) { 23 | BoxConverter.fromJson(json, this); 24 | } 25 | 26 | public Point getUpperRightCorner() { 27 | return upperRightCorner; 28 | } 29 | 30 | public void setUpperRightCorner(Point upperRightCorner) { 31 | this.upperRightCorner = upperRightCorner; 32 | } 33 | 34 | public Point getLowerLeftCorner() { 35 | return lowerLeftCorner; 36 | } 37 | 38 | public void setLowerLeftCorner(Point lowerLeftCorner) { 39 | this.lowerLeftCorner = lowerLeftCorner; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (o == null || getClass() != o.getClass()) return false; 46 | 47 | Box box = (Box) o; 48 | 49 | if (!upperRightCorner.equals(box.upperRightCorner)) return false; 50 | if (!lowerLeftCorner.equals(box.lowerLeftCorner)) return false; 51 | 52 | return true; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | int result = upperRightCorner.hashCode(); 58 | result = 31 * result + lowerLeftCorner.hashCode(); 59 | return result; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "Box(" + upperRightCorner.toString() + "," + lowerLeftCorner.toString() + ")"; 65 | } 66 | 67 | public JsonObject toJson() { 68 | JsonObject json = new JsonObject(); 69 | BoxConverter.toJson(this, json); 70 | return json; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Circle.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | /** 7 | * Circle data type in Postgres represented by a center {@link Point} and radius. 8 | */ 9 | @DataObject(generateConverter = true) 10 | public class Circle { 11 | private Point centerPoint; 12 | private double radius; 13 | 14 | public Circle() { 15 | this(new Point(), 0.0); 16 | } 17 | 18 | public Circle(Point centerPoint, double radius) { 19 | this.centerPoint = centerPoint; 20 | this.radius = radius; 21 | } 22 | 23 | public Circle(JsonObject json) { 24 | CircleConverter.fromJson(json, this); 25 | } 26 | 27 | public Point getCenterPoint() { 28 | return centerPoint; 29 | } 30 | 31 | public void setCenterPoint(Point centerPoint) { 32 | this.centerPoint = centerPoint; 33 | } 34 | 35 | public double getRadius() { 36 | return radius; 37 | } 38 | 39 | public void setRadius(double radius) { 40 | this.radius = radius; 41 | } 42 | 43 | @Override 44 | public boolean equals(Object o) { 45 | if (this == o) return true; 46 | if (o == null || getClass() != o.getClass()) return false; 47 | 48 | Circle that = (Circle) o; 49 | 50 | if (radius != that.radius) return false; 51 | if (!centerPoint.equals(that.centerPoint)) return false; 52 | 53 | return true; 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | int result; 59 | long temp; 60 | result = centerPoint.hashCode(); 61 | temp = Double.doubleToLongBits(radius); 62 | result = 31 * result + (int) (temp ^ (temp >>> 32)); 63 | return result; 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return "Circle<" + centerPoint.toString() + "," + radius + ">"; 69 | } 70 | 71 | public JsonObject toJson() { 72 | JsonObject json = new JsonObject(); 73 | CircleConverter.toJson(this, json); 74 | return json; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Json.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.data; 18 | 19 | import io.reactiverse.pgclient.impl.data.JsonImpl; 20 | import io.vertx.codegen.annotations.VertxGen; 21 | import io.vertx.core.json.JsonArray; 22 | import io.vertx.core.json.JsonObject; 23 | 24 | @VertxGen 25 | public interface Json { 26 | 27 | static Json create(Object value) { 28 | if (value == null) { 29 | return JsonImpl.NULL; 30 | } else if (value instanceof String || value instanceof Number || value instanceof JsonObject || value instanceof JsonArray || value instanceof Boolean) { 31 | return new JsonImpl(value); 32 | } else { 33 | throw new IllegalArgumentException("Invalid json value " + value + " with class " + value.getClass().getName()); 34 | } 35 | } 36 | 37 | Object value(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Line.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | /** 7 | * Line data type in Postgres represented by the linear equation Ax + By + C = 0, where A and B are not both zero. 8 | */ 9 | @DataObject(generateConverter = true) 10 | public class Line { 11 | private double a; 12 | private double b; 13 | private double c; 14 | 15 | public Line() { 16 | this(0.0, 0.0, 0.0); 17 | } 18 | 19 | public Line(double a, double b, double c) { 20 | this.a = a; 21 | this.b = b; 22 | this.c = c; 23 | } 24 | 25 | public Line(JsonObject json) { 26 | LineConverter.fromJson(json, this); 27 | } 28 | 29 | public double getA() { 30 | return a; 31 | } 32 | 33 | public void setA(double a) { 34 | this.a = a; 35 | } 36 | 37 | public double getB() { 38 | return b; 39 | } 40 | 41 | public void setB(double b) { 42 | this.b = b; 43 | } 44 | 45 | public double getC() { 46 | return c; 47 | } 48 | 49 | public void setC(double c) { 50 | this.c = c; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object o) { 55 | if (this == o) return true; 56 | if (o == null || getClass() != o.getClass()) return false; 57 | 58 | Line that = (Line) o; 59 | 60 | if (a != that.a) return false; 61 | if (b != that.b) return false; 62 | if (c != that.c) return false; 63 | 64 | return true; 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | int result; 70 | long temp; 71 | temp = Double.doubleToLongBits(a); 72 | result = (int) (temp ^ (temp >>> 32)); 73 | temp = Double.doubleToLongBits(b); 74 | result = 31 * result + (int) (temp ^ (temp >>> 32)); 75 | temp = Double.doubleToLongBits(c); 76 | result = 31 * result + (int) (temp ^ (temp >>> 32)); 77 | return result; 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | return "Line{" + a + "," + b + "," + c + "}"; 83 | } 84 | 85 | public JsonObject toJson() { 86 | JsonObject json = new JsonObject(); 87 | LineConverter.toJson(this, json); 88 | return json; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/LineSegment.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | /** 7 | * Finite line segment data type in Postgres represented by pairs of {@link Point}s that are the endpoints of the segment. 8 | */ 9 | @DataObject(generateConverter = true) 10 | public class LineSegment { 11 | private Point p1, p2; 12 | 13 | public LineSegment() { 14 | this(new Point(), new Point()); 15 | } 16 | 17 | public LineSegment(Point p1, Point p2) { 18 | this.p1 = p1; 19 | this.p2 = p2; 20 | } 21 | 22 | public LineSegment(JsonObject json) { 23 | LineSegmentConverter.fromJson(json, this); 24 | } 25 | 26 | public Point getP1() { 27 | return p1; 28 | } 29 | 30 | public void setP1(Point p1) { 31 | this.p1 = p1; 32 | } 33 | 34 | public Point getP2() { 35 | return p2; 36 | } 37 | 38 | public void setP2(Point p2) { 39 | this.p2 = p2; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (o == null || getClass() != o.getClass()) return false; 46 | 47 | LineSegment that = (LineSegment) o; 48 | 49 | if (!p1.equals(that.p1)) return false; 50 | if (!p2.equals(that.p2)) return false; 51 | 52 | return true; 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | int result = p1.hashCode(); 58 | result = 31 * result + p2.hashCode(); 59 | return result; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "LineSegment[" + p1.toString() + "," + p2.toString() + "]"; 65 | } 66 | 67 | public JsonObject toJson() { 68 | JsonObject json = new JsonObject(); 69 | LineSegmentConverter.toJson(this, json); 70 | return json; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Path.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Path data type in Postgres represented by lists of connected points. 11 | * Paths can be open, where the first and last points in the list are considered not connected, 12 | * or closed, where the first and last points are considered connected. 13 | */ 14 | @DataObject(generateConverter = true) 15 | public class Path { 16 | private boolean isOpen; 17 | private List points; 18 | 19 | public Path() { 20 | this(false, new ArrayList<>()); 21 | } 22 | 23 | public Path(boolean isOpen, List points) { 24 | this.isOpen = isOpen; 25 | this.points = points; 26 | } 27 | 28 | 29 | public Path(JsonObject json) { 30 | PathConverter.fromJson(json, this); 31 | } 32 | 33 | public boolean isOpen() { 34 | return isOpen; 35 | } 36 | 37 | public void setOpen(boolean open) { 38 | isOpen = open; 39 | } 40 | 41 | public List getPoints() { 42 | return points; 43 | } 44 | 45 | public void setPoints(List points) { 46 | this.points = points; 47 | } 48 | 49 | @Override 50 | public boolean equals(Object o) { 51 | if (this == o) return true; 52 | if (o == null || getClass() != o.getClass()) return false; 53 | 54 | Path path = (Path) o; 55 | 56 | if (isOpen != path.isOpen) return false; 57 | return points.equals(path.points); 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | int result = (isOpen ? 1 : 0); 63 | result = 31 * result + points.hashCode(); 64 | return result; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | String left; 70 | String right; 71 | if (isOpen) { 72 | left = "["; 73 | right = "]"; 74 | } else { 75 | left = "("; 76 | right = ")"; 77 | } 78 | StringBuilder stringBuilder = new StringBuilder(); 79 | stringBuilder.append("Path"); 80 | stringBuilder.append(left); 81 | for (int i = 0; i < points.size(); i++) { 82 | Point point = points.get(i); 83 | stringBuilder.append(point.toString()); 84 | if (i != points.size() - 1) { 85 | // not the last one 86 | stringBuilder.append(","); 87 | } 88 | } 89 | stringBuilder.append(right); 90 | return stringBuilder.toString(); 91 | } 92 | 93 | public JsonObject toJson() { 94 | JsonObject json = new JsonObject(); 95 | PathConverter.toJson(this, json); 96 | return json; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Point.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.data; 18 | 19 | import io.vertx.codegen.annotations.DataObject; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | /** 23 | * A Postgresql point. 24 | */ 25 | @DataObject(generateConverter = true) 26 | public class Point { 27 | 28 | public double x, y; 29 | 30 | public Point() { 31 | this(0, 0); 32 | } 33 | 34 | public Point(double x, double y) { 35 | this.x = x; 36 | this.y = y; 37 | } 38 | 39 | public Point(JsonObject json) { 40 | PointConverter.fromJson(json, this); 41 | } 42 | 43 | public double getX() { 44 | return x; 45 | } 46 | 47 | public Point setX(double x) { 48 | this.x = x; 49 | return this; 50 | } 51 | 52 | public double getY() { 53 | return y; 54 | } 55 | 56 | public Point setY(double y) { 57 | this.y = y; 58 | return this; 59 | } 60 | 61 | @Override 62 | public boolean equals(Object obj) { 63 | if (obj instanceof Point) { 64 | Point that = (Point) obj; 65 | return x == that.x && y == that.y; 66 | } 67 | return false; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "Point(" + x + "," + y + ")"; 73 | } 74 | 75 | public JsonObject toJson() { 76 | JsonObject json = new JsonObject(); 77 | PointConverter.toJson(this, json); 78 | return json; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/data/Polygon.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.vertx.codegen.annotations.DataObject; 4 | import io.vertx.core.json.JsonObject; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Polygon data type in Postgres represented by lists of points (the vertexes of the polygon). 11 | * Polygons are very similar to closed paths, but are stored differently and have their own set of support routines. 12 | */ 13 | @DataObject(generateConverter = true) 14 | public class Polygon { 15 | private List points; 16 | 17 | public Polygon() { 18 | this(new ArrayList<>()); 19 | } 20 | 21 | public Polygon(List points) { 22 | this.points = points; 23 | } 24 | 25 | 26 | public Polygon(JsonObject json) { 27 | PolygonConverter.fromJson(json, this); 28 | } 29 | 30 | public List getPoints() { 31 | return points; 32 | } 33 | 34 | public void setPoints(List points) { 35 | this.points = points; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | 43 | Polygon polygon = (Polygon) o; 44 | 45 | return points.equals(polygon.points); 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | return points.hashCode(); 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | StringBuilder stringBuilder = new StringBuilder(); 56 | stringBuilder.append("Polygon"); 57 | stringBuilder.append("("); 58 | for (int i = 0; i < points.size(); i++) { 59 | Point point = points.get(i); 60 | stringBuilder.append(point.toString()); 61 | if (i != points.size() - 1) { 62 | // not the last one 63 | stringBuilder.append(","); 64 | } 65 | } 66 | stringBuilder.append(")"); 67 | return stringBuilder.toString(); 68 | } 69 | 70 | public JsonObject toJson() { 71 | JsonObject json = new JsonObject(); 72 | PolygonConverter.toJson(this, json); 73 | return json; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/CloseConnectionCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.impl.codec.encoder.MessageEncoder; 21 | 22 | class CloseConnectionCommand extends CommandBase { 23 | 24 | static final CloseConnectionCommand INSTANCE = new CloseConnectionCommand(); 25 | 26 | private CloseConnectionCommand() { 27 | handler = ar -> {}; 28 | } 29 | 30 | @Override 31 | void exec(MessageEncoder out) { 32 | out.writeTerminate(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/ClosePortalCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.impl.codec.encoder.MessageEncoder; 21 | import io.vertx.core.Handler; 22 | 23 | /** 24 | * @author Julien Viet 25 | */ 26 | class ClosePortalCommand extends CommandBase { 27 | 28 | private final String portal; 29 | 30 | ClosePortalCommand(String portal) { 31 | this.portal = portal; 32 | } 33 | 34 | @Override 35 | void exec(MessageEncoder out) { 36 | out.writeClosePortal(portal); 37 | out.writeSync(); 38 | } 39 | 40 | @Override 41 | public void handleCloseComplete() { 42 | // Expected 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/CloseStatementCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.impl.codec.encoder.MessageEncoder; 21 | 22 | /** 23 | * @author Julien Viet 24 | */ 25 | class CloseStatementCommand extends CommandBase { 26 | 27 | @Override 28 | void exec(MessageEncoder out) { 29 | /* 30 | if (conn.psCache == null) { 31 | conn.writeMessage(new Close().setStatement(statement)); 32 | conn.writeMessage(Sync.INSTANCE); 33 | } else { 34 | } 35 | */ 36 | CommandResponse resp = CommandResponse.success(null); 37 | completionHandler.handle(resp); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/CommandResponse.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.impl; 2 | 3 | import io.reactiverse.pgclient.impl.codec.TxStatus; 4 | import io.vertx.core.AsyncResult; 5 | import io.vertx.core.impl.NoStackTraceThrowable; 6 | 7 | public abstract class CommandResponse implements AsyncResult { 8 | 9 | static CommandResponse failure(String msg) { 10 | return failure(new NoStackTraceThrowable(msg), null); 11 | } 12 | 13 | static CommandResponse failure(String msg, TxStatus txStatus) { 14 | return failure(new NoStackTraceThrowable(msg), txStatus); 15 | } 16 | 17 | static CommandResponse failure(Throwable cause) { 18 | return failure(cause, null); 19 | } 20 | 21 | static CommandResponse failure(Throwable cause, TxStatus txStatus) { 22 | return new CommandResponse(txStatus) { 23 | @Override 24 | public R result() { 25 | return null; 26 | } 27 | @Override 28 | public Throwable cause() { 29 | return cause; 30 | } 31 | @Override 32 | public boolean succeeded() { 33 | return false; 34 | } 35 | @Override 36 | public boolean failed() { 37 | return true; 38 | } 39 | }; 40 | } 41 | 42 | static CommandResponse success(R result) { 43 | return success(result, null); 44 | } 45 | 46 | static CommandResponse success(R result, TxStatus txStatus) { 47 | return new CommandResponse(txStatus) { 48 | @Override 49 | public R result() { 50 | return result; 51 | } 52 | @Override 53 | public Throwable cause() { 54 | return null; 55 | } 56 | @Override 57 | public boolean succeeded() { 58 | return true; 59 | } 60 | @Override 61 | public boolean failed() { 62 | return false; 63 | } 64 | }; 65 | } 66 | 67 | // The connection that executed the command 68 | CommandScheduler scheduler; 69 | private final TxStatus txStatus; 70 | 71 | public CommandResponse(TxStatus txStatus) { 72 | this.txStatus = txStatus; 73 | } 74 | 75 | TxStatus txStatus() { 76 | return txStatus; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/CommandScheduler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.impl; 18 | 19 | import io.vertx.core.Handler; 20 | 21 | @FunctionalInterface 22 | interface CommandScheduler { 23 | 24 | void schedule(CommandBase cmd, Handler> handler); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/Connection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | public interface Connection { 21 | 22 | void init(Holder holder); 23 | 24 | boolean isSsl(); 25 | 26 | void schedule(CommandBase cmd); 27 | 28 | void close(Holder holder); 29 | 30 | int getProcessId(); 31 | 32 | int getSecretKey(); 33 | 34 | interface Holder { 35 | 36 | Connection connection(); 37 | 38 | void handleNotification(int processId, String channel, String payload); 39 | 40 | void handleClosed(); 41 | 42 | void handleException(Throwable err); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/ExtendedQueryCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.Row; 21 | import io.reactiverse.pgclient.Tuple; 22 | import io.reactiverse.pgclient.impl.codec.encoder.MessageEncoder; 23 | import io.reactiverse.pgclient.impl.codec.encoder.Parse; 24 | 25 | import java.util.List; 26 | import java.util.stream.Collector; 27 | 28 | public class ExtendedQueryCommand extends ExtendedQueryCommandBase { 29 | 30 | private final Tuple params; 31 | 32 | ExtendedQueryCommand(PreparedStatement ps, 33 | Tuple params, 34 | boolean singleton, 35 | Collector collector, 36 | QueryResultHandler resultHandler) { 37 | this(ps, params, 0, null, false, singleton, collector, resultHandler); 38 | } 39 | 40 | ExtendedQueryCommand(PreparedStatement ps, 41 | Tuple params, 42 | int fetch, 43 | String portal, 44 | boolean suspended, 45 | boolean singleton, 46 | Collector collector, 47 | QueryResultHandler resultHandler) { 48 | super(ps, fetch, portal, suspended, singleton, collector, resultHandler); 49 | this.params = params; 50 | } 51 | 52 | @Override 53 | void exec(MessageEncoder out) { 54 | if (suspended) { 55 | out.writeExecute(portal, fetch); 56 | out.writeSync(); 57 | } else { 58 | if (ps.bind.statement == 0) { 59 | out.writeParse(new Parse(ps.sql)); 60 | } 61 | out.writeBind(ps.bind, portal, (List) params); 62 | out.writeExecute(portal, fetch); 63 | out.writeSync(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/ExtendedQueryCommandBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.Row; 21 | import io.reactiverse.pgclient.impl.codec.decoder.RowDescription; 22 | import io.vertx.core.AsyncResult; 23 | import io.vertx.core.Handler; 24 | 25 | import java.util.stream.Collector; 26 | 27 | /** 28 | * @author Julien Viet 29 | */ 30 | abstract class ExtendedQueryCommandBase extends QueryCommandBase { 31 | 32 | protected final PreparedStatement ps; 33 | protected final int fetch; 34 | protected final String portal; 35 | protected final boolean suspended; 36 | 37 | ExtendedQueryCommandBase(PreparedStatement ps, 38 | int fetch, 39 | String portal, 40 | boolean suspended, 41 | boolean singleton, 42 | Collector collector, 43 | QueryResultHandler resultHandler) { 44 | super(collector, resultHandler); 45 | this.ps = ps; 46 | this.fetch = fetch; 47 | this.portal = portal; 48 | this.suspended = suspended; 49 | this.decoder = new RowResultDecoder<>(collector, singleton, ps.rowDesc); 50 | } 51 | 52 | @Override 53 | String sql() { 54 | return ps.sql; 55 | } 56 | 57 | @Override 58 | public void handleParseComplete() { 59 | // Response to Parse 60 | } 61 | 62 | @Override 63 | public void handlePortalSuspended() { 64 | R result = decoder.complete(); 65 | RowDescription desc = decoder.description(); 66 | int size = decoder.size(); 67 | decoder.reset(); 68 | this.result = true; 69 | resultHandler.handleResult(0, size, desc, result); 70 | } 71 | 72 | @Override 73 | public void handleBindComplete() { 74 | // Response to Bind 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/PgConnectionBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.PgPreparedQuery; 21 | import io.vertx.core.*; 22 | 23 | /** 24 | * @author Julien Viet 25 | */ 26 | public abstract class PgConnectionBase extends PgClientBase { 27 | 28 | protected final Context context; 29 | protected final Connection conn; 30 | 31 | PgConnectionBase(Context context, Connection conn) { 32 | this.context = context; 33 | this.conn = conn; 34 | } 35 | 36 | public C prepare(String sql, Handler> handler) { 37 | schedule(new PrepareStatementCommand(sql), cr -> { 38 | if (cr.succeeded()) { 39 | handler.handle(Future.succeededFuture(new PgPreparedQueryImpl(conn, context, cr.result()))); 40 | } else { 41 | handler.handle(Future.failedFuture(cr.cause())); 42 | } 43 | }); 44 | return (C) this; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/PgResultBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.PgResult; 21 | 22 | import java.util.List; 23 | 24 | public abstract class PgResultBase> implements PgResult { 25 | 26 | int updated; 27 | List columnNames; 28 | int size; 29 | R next; 30 | 31 | @Override 32 | public List columnsNames() { 33 | return columnNames; 34 | } 35 | 36 | @Override 37 | public int rowCount() { 38 | return updated; 39 | } 40 | 41 | @Override 42 | public int size() { 43 | return size; 44 | } 45 | 46 | @Override 47 | public R next() { 48 | return next; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/PgResultBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.PgResult; 21 | import io.reactiverse.pgclient.impl.codec.decoder.RowDescription; 22 | import io.vertx.core.AsyncResult; 23 | import io.vertx.core.Handler; 24 | 25 | import java.util.function.Function; 26 | 27 | /** 28 | * A query result handler for building a {@link PgResult}. 29 | */ 30 | public class PgResultBuilder, L extends PgResult> implements QueryResultHandler, Handler> { 31 | 32 | private final Handler> handler; 33 | private final Function factory; 34 | private R first; 35 | private boolean suspended; 36 | 37 | PgResultBuilder(Function factory, Handler> handler) { 38 | this.factory = factory; 39 | this.handler = handler; 40 | } 41 | 42 | @Override 43 | public void handleResult(int updatedCount, int size, RowDescription desc, T result) { 44 | R r = factory.apply(result); 45 | r.updated = updatedCount; 46 | r.size = size; 47 | r.columnNames = desc != null ? desc.columnNames() : null; 48 | handleResult(r); 49 | } 50 | 51 | private void handleResult(R result) { 52 | if (first == null) { 53 | first = result; 54 | } else { 55 | R h = first; 56 | while (h.next != null) { 57 | h = h.next; 58 | } 59 | h.next = result; 60 | } 61 | } 62 | 63 | @Override 64 | public void handle(AsyncResult res) { 65 | suspended = res.succeeded() && res.result(); 66 | handler.handle((AsyncResult) res.map(first)); 67 | } 68 | 69 | public boolean isSuspended() { 70 | return suspended; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/PgResultImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | public class PgResultImpl extends PgResultBase> { 21 | 22 | private final T value; 23 | 24 | public PgResultImpl(T value) { 25 | this.value = value; 26 | } 27 | 28 | @Override 29 | public T value() { 30 | return value; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/PgRowSetImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.impl; 18 | 19 | import io.reactiverse.pgclient.PgIterator; 20 | import io.reactiverse.pgclient.PgRowSet; 21 | import io.reactiverse.pgclient.Row; 22 | 23 | import java.util.NoSuchElementException; 24 | import java.util.function.Function; 25 | import java.util.stream.Collector; 26 | 27 | class PgRowSetImpl extends PgResultBase implements PgRowSet { 28 | 29 | static Collector COLLECTOR = Collector.of( 30 | PgRowSetImpl::new, 31 | (set, row) -> { 32 | if (set.head == null) { 33 | set.head = set.tail = (RowImpl) row; 34 | } else { 35 | set.tail.next = (RowImpl) row; 36 | set.tail = set.tail.next; 37 | } 38 | }, 39 | (set1, set2) -> null, // Shall not be invoked as this is sequential 40 | (set) -> set 41 | ); 42 | 43 | static Function FACTORY = rs -> (PgRowSetImpl) rs; 44 | 45 | private RowImpl head; 46 | private RowImpl tail; 47 | 48 | @Override 49 | public PgRowSet value() { 50 | return this; 51 | } 52 | 53 | @Override 54 | public PgIterator iterator() { 55 | return new PgIterator() { 56 | RowImpl current = head; 57 | @Override 58 | public boolean hasNext() { 59 | return current != null; 60 | } 61 | @Override 62 | public Row next() { 63 | if (current == null) { 64 | throw new NoSuchElementException(); 65 | } 66 | RowImpl r = current; 67 | current = current.next; 68 | return r; 69 | } 70 | }; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/PreparedStatement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.impl.codec.ColumnDesc; 21 | import io.reactiverse.pgclient.impl.codec.DataFormat; 22 | import io.reactiverse.pgclient.impl.codec.decoder.ParameterDescription; 23 | import io.reactiverse.pgclient.impl.codec.decoder.RowDescription; 24 | import io.reactiverse.pgclient.impl.codec.encoder.Bind; 25 | 26 | import java.util.Arrays; 27 | import java.util.List; 28 | 29 | class PreparedStatement { 30 | 31 | private static final ColumnDesc[] EMPTY_COLUMNS = new ColumnDesc[0]; 32 | 33 | final String sql; 34 | final Bind bind; 35 | private final ParameterDescription paramDesc; 36 | final RowDescription rowDesc; 37 | 38 | PreparedStatement(String sql, long statement, ParameterDescription paramDesc, RowDescription rowDesc) { 39 | 40 | // Fix to use binary when possible 41 | if (rowDesc != null) { 42 | rowDesc = new RowDescription(Arrays.stream(rowDesc.columns()) 43 | .map(c -> new ColumnDesc( 44 | c.getName(), 45 | c.getRelationId(), 46 | c.getRelationAttributeNo(), 47 | c.getDataType(), 48 | c.getLength(), 49 | c.getTypeModifier(), 50 | c.getDataType().supportsBinary ? DataFormat.BINARY : DataFormat.TEXT)) 51 | .toArray(ColumnDesc[]::new)); 52 | } 53 | 54 | this.paramDesc = paramDesc; 55 | this.rowDesc = rowDesc; 56 | this.sql = sql; 57 | this.bind = new Bind(statement, paramDesc != null ? paramDesc.getParamDataTypes() : null, rowDesc != null ? rowDesc.columns() : EMPTY_COLUMNS); 58 | } 59 | 60 | String prepare(List values) { 61 | return paramDesc.prepare(values); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/QueryCommandBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.PgException; 21 | import io.reactiverse.pgclient.Row; 22 | import io.reactiverse.pgclient.impl.codec.decoder.ErrorResponse; 23 | import io.reactiverse.pgclient.impl.codec.decoder.RowDescription; 24 | 25 | import java.util.stream.Collector; 26 | 27 | /** 28 | * @author Julien Viet 29 | */ 30 | 31 | public abstract class QueryCommandBase extends CommandBase { 32 | 33 | public RowResultDecoder decoder; 34 | final QueryResultHandler resultHandler; 35 | final Collector collector; 36 | 37 | QueryCommandBase(Collector collector, QueryResultHandler resultHandler) { 38 | this.resultHandler = resultHandler; 39 | this.collector = collector; 40 | } 41 | 42 | abstract String sql(); 43 | 44 | @Override 45 | public void handleCommandComplete(int updated) { 46 | this.result = false; 47 | T result; 48 | int size; 49 | RowDescription desc; 50 | if (decoder != null) { 51 | result = decoder.complete(); 52 | desc = decoder.description(); 53 | size = decoder.size(); 54 | decoder.reset(); 55 | } else { 56 | result = emptyResult(collector); 57 | size = 0; 58 | desc = null; 59 | } 60 | resultHandler.handleResult(updated, size, desc, result); 61 | } 62 | 63 | @Override 64 | public void handleErrorResponse(ErrorResponse errorResponse) { 65 | failure = new PgException(errorResponse); 66 | } 67 | 68 | private static T emptyResult(Collector collector) { 69 | return collector.finisher().apply(collector.supplier().get()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/QueryResultHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.impl.codec.decoder.RowDescription; 21 | import io.vertx.core.AsyncResult; 22 | import io.vertx.core.Handler; 23 | 24 | /** 25 | * @author Julien Viet 26 | */ 27 | public interface QueryResultHandler { 28 | 29 | void handleResult(int updatedCount, int size, RowDescription desc, T result); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/SimpleQueryCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | import io.reactiverse.pgclient.Row; 21 | import io.reactiverse.pgclient.impl.codec.decoder.RowDescription; 22 | import io.reactiverse.pgclient.impl.codec.encoder.MessageEncoder; 23 | import io.reactiverse.pgclient.impl.codec.encoder.Query; 24 | import io.vertx.core.AsyncResult; 25 | import io.vertx.core.Handler; 26 | 27 | import java.util.stream.Collector; 28 | 29 | /** 30 | * @author Julien Viet 31 | */ 32 | 33 | class SimpleQueryCommand extends QueryCommandBase { 34 | 35 | private final String sql; 36 | private final boolean singleton; 37 | 38 | SimpleQueryCommand(String sql, 39 | boolean singleton, 40 | Collector collector, 41 | QueryResultHandler resultHandler) { 42 | super(collector, resultHandler); 43 | this.sql = sql; 44 | this.singleton = singleton; 45 | } 46 | 47 | @Override 48 | String sql() { 49 | return sql; 50 | } 51 | 52 | @Override 53 | void exec(MessageEncoder out) { 54 | out.writeQuery(new Query(sql)); 55 | } 56 | 57 | @Override 58 | public void handleRowDescription(RowDescription rowDescription) { 59 | decoder = new RowResultDecoder<>(collector, singleton, rowDescription); 60 | } 61 | 62 | public String getSql() { 63 | return sql; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/StringLongSequence.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl; 19 | 20 | public class StringLongSequence { 21 | 22 | private short count; 23 | 24 | public long next() { 25 | short val = count++; 26 | long next = 0x30_30_30_00_00_00_00_00L; 27 | next |= toHex(val >> 12 & 0xF) << 32; 28 | next |= toHex(val >> 8 & 0xF) << 24; 29 | next |= toHex(val >> 4 & 0xF) << 16; 30 | next |= toHex(val >> 0 & 0xF) << 8; 31 | return next; 32 | } 33 | 34 | private static long toHex(int c) { 35 | if (c < 10) { 36 | return (byte)('0' + c); 37 | } else { 38 | return (byte)('A' + c - 10); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/DataFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | 24 | public enum DataFormat { 25 | TEXT(0), 26 | BINARY(1); 27 | final int id; 28 | DataFormat(int id) { 29 | this.id = id; 30 | } 31 | public static DataFormat valueOf(int id) { 32 | return (id == 0) ? DataFormat.TEXT : DataFormat.BINARY; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/TxStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec; 19 | 20 | /** 21 | * 22 | * @author Emad Alblueshi 23 | * 24 | */ 25 | public enum TxStatus { 26 | 27 | IDLE, 28 | ACTIVE, 29 | FAILED; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | 24 | public class ErrorResponse extends Response { 25 | 26 | @Override 27 | public String toString() { 28 | return "ErrorResponse{" + 29 | "severity='" + getSeverity() + '\'' + 30 | ", code='" + getCode() + '\'' + 31 | ", message='" + getMessage() + '\'' + 32 | ", detail='" + getDetail() + '\'' + 33 | ", hint='" + getHint() + '\'' + 34 | ", position='" + getPosition() + '\'' + 35 | ", internalPosition='" + getInternalPosition() + '\'' + 36 | ", internalQuery='" + getInternalQuery() + '\'' + 37 | ", where='" + getWhere() + '\'' + 38 | ", file='" + getFile() + '\'' + 39 | ", line='" + getLine() + '\'' + 40 | ", routine='" + getRoutine() + '\'' + 41 | ", schema='" + getSchema() + '\'' + 42 | ", table='" + getTable() + '\'' + 43 | ", column='" + getColumn() + '\'' + 44 | ", dataType='" + getDataType() + '\'' + 45 | ", constraint='" + getConstraint() + '\'' + 46 | '}'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/InboundMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder; 19 | 20 | /** 21 | * An interface that should be implemented for decoding and encoding messages 22 | * 23 | * @author Emad Alblueshi 24 | */ 25 | 26 | public interface InboundMessage {} 27 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/NoticeResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | 24 | public class NoticeResponse extends Response { 25 | 26 | @Override 27 | public String toString() { 28 | return "NoticeResponse{" + 29 | "severity='" + getSeverity() + '\'' + 30 | ", code='" + getCode() + '\'' + 31 | ", message='" + getMessage() + '\'' + 32 | ", detail='" + getDetail() + '\'' + 33 | ", hint='" + getHint() + '\'' + 34 | ", position='" + getPosition() + '\'' + 35 | ", internalPosition='" + getInternalPosition() + '\'' + 36 | ", internalQuery='" + getInternalQuery() + '\'' + 37 | ", where='" + getWhere() + '\'' + 38 | ", file='" + getFile() + '\'' + 39 | ", line='" + getLine() + '\'' + 40 | ", routine='" + getRoutine() + '\'' + 41 | ", schema='" + getSchema() + '\'' + 42 | ", table='" + getTable() + '\'' + 43 | ", column='" + getColumn() + '\'' + 44 | ", dataType='" + getDataType() + '\'' + 45 | ", constraint='" + getConstraint() + '\'' + 46 | '}'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/NotificationResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder; 19 | 20 | import java.util.Objects; 21 | 22 | /** 23 | * @author Emad Alblueshi 24 | */ 25 | 26 | public class NotificationResponse { 27 | 28 | private final int processId; 29 | private final String channel; 30 | private final String payload; 31 | 32 | public NotificationResponse(int processId, String channel, String payload) { 33 | this.processId = processId; 34 | this.channel = channel; 35 | this.payload = payload; 36 | } 37 | 38 | public int getProcessId() { 39 | return processId; 40 | } 41 | 42 | public String getChannel() { 43 | return channel; 44 | } 45 | 46 | public String getPayload() { 47 | return payload; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object o) { 52 | if (this == o) return true; 53 | if (o == null || getClass() != o.getClass()) return false; 54 | NotificationResponse that = (NotificationResponse) o; 55 | return processId == that.processId && 56 | Objects.equals(channel, that.channel) && 57 | Objects.equals(payload, that.payload); 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | return Objects.hash(processId, channel, payload); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return "NotificationResponse{" + 68 | "processId=" + processId + 69 | ", channel='" + channel + '\'' + 70 | ", payload='" + payload + '\'' + 71 | '}'; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/RowDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | 22 | public interface RowDecoder { 23 | 24 | void decodeRow(int len, ByteBuf in); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/RowDescription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder; 19 | 20 | import io.reactiverse.pgclient.impl.codec.ColumnDesc; 21 | 22 | import java.util.Arrays; 23 | import java.util.Collections; 24 | import java.util.List; 25 | import java.util.stream.Collectors; 26 | import java.util.stream.Stream; 27 | 28 | /** 29 | * @author Emad Alblueshi 30 | */ 31 | 32 | public class RowDescription { 33 | 34 | private final ColumnDesc[] columns; 35 | private final List columnNames; 36 | 37 | public RowDescription(ColumnDesc[] columns) { 38 | this.columns = columns; 39 | this.columnNames = Collections.unmodifiableList(Stream.of(columns) 40 | .map(ColumnDesc::getName) 41 | .collect(Collectors.toList())); 42 | } 43 | 44 | public int columnIndex(String columnName) { 45 | if (columnName == null) { 46 | throw new NullPointerException("Column name must not be null"); 47 | } 48 | return columnNames.indexOf(columnName); 49 | } 50 | 51 | public ColumnDesc[] columns() { 52 | return columns; 53 | } 54 | 55 | public List columnNames() { 56 | return columnNames; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | if (this == o) return true; 62 | if (o == null || getClass() != o.getClass()) return false; 63 | RowDescription that = (RowDescription) o; 64 | return Arrays.equals(columns, that.columns); 65 | } 66 | 67 | @Override 68 | public int hashCode() { 69 | return Arrays.hashCode(columns); 70 | } 71 | 72 | 73 | @Override 74 | public String toString() { 75 | return "RowDescription{" + 76 | "columns=" + Arrays.toString(columns) + 77 | '}'; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/type/AuthenticationType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder.type; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | 24 | public class AuthenticationType { 25 | public static final int OK = 0; 26 | public static final int KERBEROS_V5 = 2; 27 | public static final int CLEARTEXT_PASSWORD = 3; 28 | public static final int MD5_PASSWORD = 5; 29 | public static final int SCM_CREDENTIAL = 6; 30 | public static final int GSS = 7; 31 | public static final int GSS_CONTINUE = 8; 32 | public static final int SSPI = 9; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/type/CommandCompleteType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder.type; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | 24 | public class CommandCompleteType { 25 | public static final String INSERT = "INSERT"; 26 | public static final String DELETE = "DELETE"; 27 | public static final String UPDATE = "UPDATE"; 28 | public static final String SELECT = "SELECT"; 29 | public static final String MOVE = "MOVE"; 30 | public static final String FETCH = "FETCH"; 31 | public static final String COPY = "COPY"; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/type/ErrorOrNoticeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder.type; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | 24 | public class ErrorOrNoticeType { 25 | public static final byte SEVERITY = 'S'; 26 | public static final byte CODE = 'C'; 27 | public static final byte MESSAGE = 'M'; 28 | public static final byte DETAIL = 'D'; 29 | public static final byte HINT = 'H'; 30 | public static final byte POSITION = 'P'; 31 | public static final byte INTERNAL_POSITION = 'p'; 32 | public static final byte INTERNAL_QUERY = 'q'; 33 | public static final byte WHERE = 'W'; 34 | public static final byte FILE = 'F'; 35 | public static final byte LINE = 'L'; 36 | public static final byte ROUTINE = 'R'; 37 | public static final byte SCHEMA = 's'; 38 | public static final byte TABLE = 't'; 39 | public static final byte COLUMN = 'c'; 40 | public static final byte DATA_TYPE = 'd'; 41 | public static final byte CONSTRAINT = 'n'; 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/decoder/type/MessageType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.decoder.type; 19 | 20 | import io.reactiverse.pgclient.impl.codec.decoder.MessageDecoder; 21 | 22 | /** 23 | * 24 | * Backend message types for {@link MessageDecoder} 25 | * 26 | * @author Emad Alblueshi 27 | */ 28 | 29 | public class MessageType { 30 | public static final byte BACKEND_KEY_DATA = 'K'; 31 | public static final byte AUTHENTICATION = 'R'; 32 | public static final byte ERROR_RESPONSE = 'E'; 33 | public static final byte NOTICE_RESPONSE = 'N'; 34 | public static final byte NOTIFICATION_RESPONSE = 'A'; 35 | public static final byte COMMAND_COMPLETE = 'C'; 36 | public static final byte PARAMETER_STATUS = 'S'; 37 | public static final byte READY_FOR_QUERY = 'Z'; 38 | public static final byte PARAMETER_DESCRIPTION = 't'; 39 | public static final byte ROW_DESCRIPTION = 'T'; 40 | public static final byte DATA_ROW = 'D'; 41 | public static final byte PORTAL_SUSPENDED = 's'; 42 | public static final byte NO_DATA = 'n'; 43 | public static final byte EMPTY_QUERY_RESPONSE = 'I'; 44 | public static final byte PARSE_COMPLETE = '1'; 45 | public static final byte BIND_COMPLETE = '2'; 46 | public static final byte CLOSE_COMPLETE = '3'; 47 | public static final byte FUNCTION_RESULT = 'V'; 48 | public static final byte SSL_YES = 'S'; 49 | public static final byte SSL_NO = 'N'; 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/encoder/Bind.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.encoder; 19 | 20 | import io.reactiverse.pgclient.impl.codec.ColumnDesc; 21 | import io.reactiverse.pgclient.impl.codec.DataType; 22 | 23 | /** 24 | * @author Emad Alblueshi 25 | */ 26 | public class Bind { 27 | 28 | public final long statement; 29 | public final DataType[] paramTypes; 30 | public final ColumnDesc[] resultColumns; 31 | 32 | public Bind(long statement, DataType[] paramTypes, ColumnDesc[] resultColumns) { 33 | this.statement = statement; 34 | this.paramTypes = paramTypes; 35 | this.resultColumns = resultColumns; 36 | } 37 | 38 | public long getStatement() { 39 | return statement; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/encoder/Describe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.encoder; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | public class Describe { 24 | 25 | public final long statement; 26 | public final String portal; 27 | 28 | public Describe(long statement, String portal) { 29 | this.statement = statement; 30 | this.portal = portal; 31 | } 32 | 33 | public Describe(long statement) { 34 | this.statement = statement; 35 | this.portal = null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/encoder/Parse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.encoder; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | public final class Parse { 24 | 25 | public final String query; 26 | public final long statement; 27 | 28 | public Parse(String query, long statement) { 29 | this.query = query; 30 | this.statement = statement; 31 | } 32 | 33 | public Parse(String query) { 34 | this.query = query; 35 | this.statement = 0; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/encoder/PasswordMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.encoder; 19 | 20 | import io.reactiverse.pgclient.impl.codec.util.MD5Authentication; 21 | 22 | /** 23 | * @author Emad Alblueshi 24 | */ 25 | public class PasswordMessage { 26 | 27 | public final String hash; 28 | 29 | public PasswordMessage(String username, String password, byte[] salt) { 30 | this.hash = salt != null ? MD5Authentication.encode(username, password, salt) : password; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/encoder/Query.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.encoder; 19 | 20 | /** 21 | * @author Emad Alblueshi 22 | */ 23 | public class Query { 24 | 25 | public final String sql; 26 | 27 | public Query(String sql) { 28 | this.sql = sql; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/encoder/StartupMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.encoder; 19 | 20 | import io.netty.buffer.ByteBuf; 21 | import io.netty.buffer.Unpooled; 22 | 23 | import static java.nio.charset.StandardCharsets.UTF_8; 24 | 25 | /** 26 | * @author Emad Alblueshi 27 | */ 28 | public class StartupMessage { 29 | 30 | public static final ByteBuf BUFF_USER = Unpooled.copiedBuffer("user", UTF_8).asReadOnly(); 31 | public static final ByteBuf BUFF_DATABASE = Unpooled.copiedBuffer("database", UTF_8).asReadOnly(); 32 | public static final ByteBuf BUFF_APPLICATION_NAME = Unpooled.copiedBuffer("application_name", UTF_8).asReadOnly(); 33 | public static final ByteBuf BUFF_VERTX_PG_CLIENT = Unpooled.copiedBuffer("vertx-pg-client", UTF_8).asReadOnly(); 34 | public static final ByteBuf BUFF_CLIENT_ENCODING = Unpooled.copiedBuffer("client_encoding", UTF_8).asReadOnly(); 35 | public static final ByteBuf BUFF_UTF8 = Unpooled.copiedBuffer("utf8", UTF_8).asReadOnly(); 36 | public static final ByteBuf BUFF_DATE_STYLE = Unpooled.copiedBuffer("DateStyle", UTF_8).asReadOnly(); 37 | public static final ByteBuf BUFF_ISO = Unpooled.copiedBuffer("ISO", UTF_8).asReadOnly(); 38 | public static final ByteBuf BUFF_INTERVAL_STYLE = Unpooled.copiedBuffer("intervalStyle", UTF_8).asReadOnly(); 39 | public static final ByteBuf BUFF_INTERVAL_STYLE_TYPE = Unpooled.copiedBuffer("postgres", UTF_8).asReadOnly(); 40 | public static final ByteBuf BUFF_EXTRA_FLOAT_DIGITS = Unpooled.copiedBuffer("extra_float_digits", UTF_8).asReadOnly(); 41 | public static final ByteBuf BUFF_2 = Unpooled.copiedBuffer("2", UTF_8).asReadOnly(); 42 | 43 | public final String username; 44 | public final String database; 45 | 46 | public StartupMessage(String username, String database) { 47 | this.username = username; 48 | this.database = database; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/formatter/DateTimeFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.formatter; 19 | 20 | import java.time.format.DateTimeFormatterBuilder; 21 | 22 | import static java.time.format.DateTimeFormatter.*; 23 | 24 | /** 25 | * @author Emad Alblueshi 26 | */ 27 | 28 | public class DateTimeFormatter { 29 | 30 | public static final java.time.format.DateTimeFormatter TIMESTAMP_FORMAT = new DateTimeFormatterBuilder() 31 | .parseCaseInsensitive() 32 | .append(ISO_LOCAL_DATE) 33 | .appendLiteral(' ') 34 | .append(ISO_LOCAL_TIME) 35 | .toFormatter(); 36 | 37 | public static final java.time.format.DateTimeFormatter TIMESTAMPTZ_FORMAT = new DateTimeFormatterBuilder() 38 | .append(TIMESTAMP_FORMAT) 39 | .appendOffset("+HH:mm", "00:00") 40 | .toFormatter(); 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/formatter/TimeFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.formatter; 19 | 20 | import java.time.format.DateTimeFormatterBuilder; 21 | 22 | import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME; 23 | 24 | /** 25 | * @author Emad Alblueshi 26 | */ 27 | 28 | public class TimeFormatter { 29 | 30 | public static final java.time.format.DateTimeFormatter TIMETZ_FORMAT = new DateTimeFormatterBuilder() 31 | .parseCaseInsensitive() 32 | .append(ISO_LOCAL_TIME) 33 | .appendOffset("+HH:mm", "00:00") 34 | .toFormatter(); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/util/MD5Authentication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.impl.codec.util; 19 | 20 | import java.security.MessageDigest; 21 | import java.security.NoSuchAlgorithmException; 22 | 23 | import static java.nio.charset.StandardCharsets.*; 24 | 25 | public class MD5Authentication { 26 | 27 | private final static char[] HEX_ALPHABET = "0123456789abcdef".toCharArray(); 28 | 29 | private static String toHex(byte[] bytes) { 30 | char[] hexChars = new char[bytes.length * 2]; 31 | for ( int j = 0; j < bytes.length; j++ ) { 32 | int v = bytes[j] & 0xFF; 33 | hexChars[j * 2] = HEX_ALPHABET[v >>> 4]; 34 | hexChars[j * 2 + 1] = HEX_ALPHABET[v & 0x0F]; 35 | } 36 | return new String(hexChars); 37 | } 38 | 39 | public static String encode(String username, String password, byte[] salt) { 40 | 41 | byte[] digest, passDigest; 42 | 43 | MessageDigest messageDigest; 44 | 45 | try { 46 | messageDigest = MessageDigest.getInstance("MD5"); 47 | } 48 | catch (NoSuchAlgorithmException e) { 49 | throw new RuntimeException(e); 50 | } 51 | 52 | messageDigest.update(password.getBytes(UTF_8)); 53 | messageDigest.update(username.getBytes(UTF_8)); 54 | digest = messageDigest.digest(); 55 | 56 | byte[] hexDigest = toHex(digest).getBytes(US_ASCII); 57 | 58 | messageDigest.update(hexDigest); 59 | messageDigest.update(salt); 60 | passDigest = messageDigest.digest(); 61 | 62 | return "md5" + toHex(passDigest); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/codec/util/UTF8StringEndDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.impl.codec.util; 18 | 19 | import io.netty.util.ByteProcessor; 20 | 21 | /** 22 | * A processor that detects the end of a well formed UTF8 string, starting end ending with a {@code "}. 23 | *

24 | * It process all bytes until it finds the ending {@code "}. 25 | */ 26 | public class UTF8StringEndDetector implements ByteProcessor { 27 | 28 | private boolean inString; 29 | private boolean escaped; 30 | 31 | @Override 32 | public boolean process(byte value) { 33 | boolean wasEscaped = escaped; 34 | escaped = false; 35 | // In UTF-8 low ASCII have their 8th bit == 0 36 | if ((value & 0b10000000) == 0) { 37 | switch (value) { 38 | case '"': 39 | if (!wasEscaped) { 40 | if (inString) { 41 | return false; 42 | } else { 43 | inString = true; 44 | } 45 | } 46 | break; 47 | case '\\': 48 | if (inString) { 49 | escaped = true; 50 | } 51 | break; 52 | } 53 | } 54 | return true; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/impl/data/JsonImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.impl.data; 18 | 19 | import io.reactiverse.pgclient.data.Json; 20 | 21 | import java.util.Objects; 22 | 23 | public class JsonImpl implements Json { 24 | 25 | public static final JsonImpl NULL = new JsonImpl(null); 26 | 27 | private final Object value; 28 | 29 | public JsonImpl(Object value) { 30 | this.value = value; 31 | } 32 | 33 | @Override 34 | public Object value() { 35 | return value; 36 | } 37 | 38 | @Override 39 | public int hashCode() { 40 | return Objects.hashCode(value); 41 | } 42 | 43 | @Override 44 | public boolean equals(Object obj) { 45 | return obj instanceof Json && Objects.equals(value, ((Json) obj).value()); 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return String.valueOf(value); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/io/reactiverse/pgclient/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | @ModuleGen(name = "reactive-pg-client", groupPackage = "io.reactiverse") 19 | package io.reactiverse.pgclient; 20 | 21 | import io.vertx.codegen.annotations.ModuleGen; 22 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/PgConnection.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient 17 | 18 | import io.reactiverse.pgclient.PgConnection 19 | import io.reactiverse.pgclient.PgPreparedQuery 20 | import io.reactiverse.pgclient.PgRowSet 21 | import io.reactiverse.pgclient.Tuple 22 | import io.vertx.kotlin.coroutines.awaitResult 23 | 24 | /** 25 | * Suspending version of method [io.reactiverse.pgclient.PgConnection.prepare] 26 | * 27 | * @param sql the sql 28 | * @return [PgPreparedQuery] 29 | * 30 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgConnection] using Vert.x codegen. 31 | */ 32 | suspend fun PgConnection.prepareAwait(sql: String): PgPreparedQuery { 33 | return awaitResult { 34 | this.prepare(sql, it) 35 | } 36 | } 37 | 38 | suspend fun PgConnection.preparedQueryAwait(sql: String): PgRowSet { 39 | return awaitResult { 40 | this.preparedQuery(sql, it) 41 | } 42 | } 43 | 44 | suspend fun PgConnection.queryAwait(sql: String): PgRowSet { 45 | return awaitResult { 46 | this.query(sql, it) 47 | } 48 | } 49 | 50 | suspend fun PgConnection.preparedQueryAwait(sql: String, arguments: Tuple): PgRowSet { 51 | return awaitResult { 52 | this.preparedQuery(sql, arguments, it) 53 | } 54 | } 55 | 56 | suspend fun PgConnection.preparedBatchAwait(sql: String, batch: List): PgRowSet { 57 | return awaitResult { 58 | this.preparedBatch(sql, batch, it) 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/PgCursor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient 17 | 18 | import io.reactiverse.pgclient.PgCursor 19 | import io.reactiverse.pgclient.PgRowSet 20 | import io.vertx.kotlin.coroutines.awaitResult 21 | 22 | /** 23 | * Suspending version of method [io.reactiverse.pgclient.PgCursor.read] 24 | * 25 | * @param count the amount of rows to read 26 | * @return [PgRowSet] 27 | * 28 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgCursor] using Vert.x codegen. 29 | */ 30 | suspend fun PgCursor.readAwait(count: Int): PgRowSet { 31 | return awaitResult { 32 | this.read(count, it) 33 | } 34 | } 35 | 36 | /** 37 | * Suspending version of method [io.reactiverse.pgclient.PgCursor.close] 38 | * 39 | * 40 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgCursor] using Vert.x codegen. 41 | */ 42 | suspend fun PgCursor.closeAwait(): Unit { 43 | return awaitResult { 44 | this.close { ar -> it.handle(ar.mapEmpty()) } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/PgNotification.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient 17 | 18 | import io.reactiverse.pgclient.PgNotification 19 | 20 | /** 21 | * A function providing a DSL for building [io.reactiverse.pgclient.PgNotification] objects. 22 | * 23 | * A notification emited by Postgres. 24 | * 25 | * @param channel Set the channel value. 26 | * @param payload Set the payload value. 27 | * @param processId Set the process id. 28 | * 29 | *

30 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.PgNotification original] using Vert.x codegen. 31 | */ 32 | fun pgNotificationOf( 33 | channel: String? = null, 34 | payload: String? = null, 35 | processId: Int? = null): PgNotification = io.reactiverse.pgclient.PgNotification().apply { 36 | 37 | if (channel != null) { 38 | this.setChannel(channel) 39 | } 40 | if (payload != null) { 41 | this.setPayload(payload) 42 | } 43 | if (processId != null) { 44 | this.setProcessId(processId) 45 | } 46 | } 47 | 48 | /** 49 | * A function providing a DSL for building [io.reactiverse.pgclient.PgNotification] objects. 50 | * 51 | * A notification emited by Postgres. 52 | * 53 | * @param channel Set the channel value. 54 | * @param payload Set the payload value. 55 | * @param processId Set the process id. 56 | * 57 | *

58 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.PgNotification original] using Vert.x codegen. 59 | */ 60 | @Deprecated( 61 | message = "This function will be removed in a future version", 62 | replaceWith = ReplaceWith("pgNotificationOf(channel, payload, processId)") 63 | ) 64 | fun PgNotification( 65 | channel: String? = null, 66 | payload: String? = null, 67 | processId: Int? = null): PgNotification = io.reactiverse.pgclient.PgNotification().apply { 68 | 69 | if (channel != null) { 70 | this.setChannel(channel) 71 | } 72 | if (payload != null) { 73 | this.setPayload(payload) 74 | } 75 | if (processId != null) { 76 | this.setProcessId(processId) 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/PgPool.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient 17 | 18 | import io.reactiverse.pgclient.PgConnection 19 | import io.reactiverse.pgclient.PgPool 20 | import io.reactiverse.pgclient.PgRowSet 21 | import io.reactiverse.pgclient.PgTransaction 22 | import io.reactiverse.pgclient.Tuple 23 | import io.vertx.kotlin.coroutines.awaitResult 24 | 25 | suspend fun PgPool.preparedQueryAwait(sql: String): PgRowSet { 26 | return awaitResult { 27 | this.preparedQuery(sql, it) 28 | } 29 | } 30 | 31 | suspend fun PgPool.queryAwait(sql: String): PgRowSet { 32 | return awaitResult { 33 | this.query(sql, it) 34 | } 35 | } 36 | 37 | suspend fun PgPool.preparedQueryAwait(sql: String, arguments: Tuple): PgRowSet { 38 | return awaitResult { 39 | this.preparedQuery(sql, arguments, it) 40 | } 41 | } 42 | 43 | suspend fun PgPool.preparedBatchAwait(sql: String, batch: List): PgRowSet { 44 | return awaitResult { 45 | this.preparedBatch(sql, batch, it) 46 | } 47 | } 48 | 49 | /** 50 | * Suspending version of method [io.reactiverse.pgclient.PgPool.getConnection] 51 | * 52 | * @return [PgConnection] 53 | * 54 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgPool] using Vert.x codegen. 55 | */ 56 | suspend fun PgPool.getConnectionAwait(): PgConnection { 57 | return awaitResult { 58 | this.getConnection(it) 59 | } 60 | } 61 | 62 | /** 63 | * Suspending version of method [io.reactiverse.pgclient.PgPool.begin] 64 | * 65 | * @return [PgTransaction] 66 | * 67 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgPool] using Vert.x codegen. 68 | */ 69 | suspend fun PgPool.beginAwait(): PgTransaction { 70 | return awaitResult { 71 | this.begin(it) 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/PgPreparedQuery.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient 17 | 18 | import io.reactiverse.pgclient.PgPreparedQuery 19 | import io.reactiverse.pgclient.PgRowSet 20 | import io.reactiverse.pgclient.Tuple 21 | import io.vertx.kotlin.coroutines.awaitResult 22 | 23 | /** 24 | * Suspending version of method [io.reactiverse.pgclient.PgPreparedQuery.execute] 25 | * 26 | * @return [PgRowSet] 27 | * 28 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgPreparedQuery] using Vert.x codegen. 29 | */ 30 | suspend fun PgPreparedQuery.executeAwait(): PgRowSet { 31 | return awaitResult { 32 | this.execute(it) 33 | } 34 | } 35 | 36 | /** 37 | * Suspending version of method [io.reactiverse.pgclient.PgPreparedQuery.execute] 38 | * 39 | * @param args the list of arguments 40 | * @return [PgRowSet] 41 | * 42 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgPreparedQuery] using Vert.x codegen. 43 | */ 44 | suspend fun PgPreparedQuery.executeAwait(args: Tuple): PgRowSet { 45 | return awaitResult { 46 | this.execute(args, it) 47 | } 48 | } 49 | 50 | /** 51 | * Suspending version of method [io.reactiverse.pgclient.PgPreparedQuery.batch] 52 | * 53 | * @param argsList the list of tuple for the batch 54 | * @return [PgRowSet] 55 | * 56 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgPreparedQuery] using Vert.x codegen. 57 | */ 58 | suspend fun PgPreparedQuery.batchAwait(argsList: List): PgRowSet { 59 | return awaitResult { 60 | this.batch(argsList, it) 61 | } 62 | } 63 | 64 | /** 65 | * Suspending version of method [io.reactiverse.pgclient.PgPreparedQuery.close] 66 | * 67 | * 68 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgPreparedQuery] using Vert.x codegen. 69 | */ 70 | suspend fun PgPreparedQuery.closeAwait(): Unit { 71 | return awaitResult { 72 | this.close { ar -> it.handle(ar.mapEmpty()) } 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/PgStream.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient 17 | 18 | import io.reactiverse.pgclient.PgStream 19 | import io.vertx.core.streams.WriteStream 20 | import io.vertx.kotlin.coroutines.awaitResult 21 | 22 | suspend fun PgStream.pipeToAwait(dst: WriteStream): Unit { 23 | return awaitResult { 24 | this.pipeTo(dst) { ar -> it.handle(ar.mapEmpty()) } 25 | } 26 | } 27 | 28 | /** 29 | * Suspending version of method [io.reactiverse.pgclient.PgStream.close] 30 | * 31 | * 32 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.PgStream] using Vert.x codegen. 33 | */ 34 | suspend fun PgStream.closeAwait(): Unit { 35 | return awaitResult { 36 | this.close { ar -> it.handle(ar.mapEmpty()) } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/Box.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.Box 19 | import io.reactiverse.pgclient.data.Point 20 | 21 | /** 22 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Box] objects. 23 | * 24 | * Rectangular box data type in Postgres represented by pairs of [io.reactiverse.pgclient.data.Point]s that are opposite corners of the box. 25 | * 26 | * @param lowerLeftCorner 27 | * @param upperRightCorner 28 | * 29 | *

30 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Box original] using Vert.x codegen. 31 | */ 32 | fun boxOf( 33 | lowerLeftCorner: io.reactiverse.pgclient.data.Point? = null, 34 | upperRightCorner: io.reactiverse.pgclient.data.Point? = null): Box = io.reactiverse.pgclient.data.Box().apply { 35 | 36 | if (lowerLeftCorner != null) { 37 | this.setLowerLeftCorner(lowerLeftCorner) 38 | } 39 | if (upperRightCorner != null) { 40 | this.setUpperRightCorner(upperRightCorner) 41 | } 42 | } 43 | 44 | /** 45 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Box] objects. 46 | * 47 | * Rectangular box data type in Postgres represented by pairs of [io.reactiverse.pgclient.data.Point]s that are opposite corners of the box. 48 | * 49 | * @param lowerLeftCorner 50 | * @param upperRightCorner 51 | * 52 | *

53 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Box original] using Vert.x codegen. 54 | */ 55 | @Deprecated( 56 | message = "This function will be removed in a future version", 57 | replaceWith = ReplaceWith("boxOf(lowerLeftCorner, upperRightCorner)") 58 | ) 59 | fun Box( 60 | lowerLeftCorner: io.reactiverse.pgclient.data.Point? = null, 61 | upperRightCorner: io.reactiverse.pgclient.data.Point? = null): Box = io.reactiverse.pgclient.data.Box().apply { 62 | 63 | if (lowerLeftCorner != null) { 64 | this.setLowerLeftCorner(lowerLeftCorner) 65 | } 66 | if (upperRightCorner != null) { 67 | this.setUpperRightCorner(upperRightCorner) 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/Circle.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.Circle 19 | import io.reactiverse.pgclient.data.Point 20 | 21 | /** 22 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Circle] objects. 23 | * 24 | * Circle data type in Postgres represented by a center [io.reactiverse.pgclient.data.Point] and radius. 25 | * 26 | * @param centerPoint 27 | * @param radius 28 | * 29 | *

30 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Circle original] using Vert.x codegen. 31 | */ 32 | fun circleOf( 33 | centerPoint: io.reactiverse.pgclient.data.Point? = null, 34 | radius: Double? = null): Circle = io.reactiverse.pgclient.data.Circle().apply { 35 | 36 | if (centerPoint != null) { 37 | this.setCenterPoint(centerPoint) 38 | } 39 | if (radius != null) { 40 | this.setRadius(radius) 41 | } 42 | } 43 | 44 | /** 45 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Circle] objects. 46 | * 47 | * Circle data type in Postgres represented by a center [io.reactiverse.pgclient.data.Point] and radius. 48 | * 49 | * @param centerPoint 50 | * @param radius 51 | * 52 | *

53 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Circle original] using Vert.x codegen. 54 | */ 55 | @Deprecated( 56 | message = "This function will be removed in a future version", 57 | replaceWith = ReplaceWith("circleOf(centerPoint, radius)") 58 | ) 59 | fun Circle( 60 | centerPoint: io.reactiverse.pgclient.data.Point? = null, 61 | radius: Double? = null): Circle = io.reactiverse.pgclient.data.Circle().apply { 62 | 63 | if (centerPoint != null) { 64 | this.setCenterPoint(centerPoint) 65 | } 66 | if (radius != null) { 67 | this.setRadius(radius) 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/Line.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.Line 19 | 20 | /** 21 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Line] objects. 22 | * 23 | * Line data type in Postgres represented by the linear equation Ax + By + C = 0, where A and B are not both zero. 24 | * 25 | * @param a 26 | * @param b 27 | * @param c 28 | * 29 | *

30 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Line original] using Vert.x codegen. 31 | */ 32 | fun lineOf( 33 | a: Double? = null, 34 | b: Double? = null, 35 | c: Double? = null): Line = io.reactiverse.pgclient.data.Line().apply { 36 | 37 | if (a != null) { 38 | this.setA(a) 39 | } 40 | if (b != null) { 41 | this.setB(b) 42 | } 43 | if (c != null) { 44 | this.setC(c) 45 | } 46 | } 47 | 48 | /** 49 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Line] objects. 50 | * 51 | * Line data type in Postgres represented by the linear equation Ax + By + C = 0, where A and B are not both zero. 52 | * 53 | * @param a 54 | * @param b 55 | * @param c 56 | * 57 | *

58 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Line original] using Vert.x codegen. 59 | */ 60 | @Deprecated( 61 | message = "This function will be removed in a future version", 62 | replaceWith = ReplaceWith("lineOf(a, b, c)") 63 | ) 64 | fun Line( 65 | a: Double? = null, 66 | b: Double? = null, 67 | c: Double? = null): Line = io.reactiverse.pgclient.data.Line().apply { 68 | 69 | if (a != null) { 70 | this.setA(a) 71 | } 72 | if (b != null) { 73 | this.setB(b) 74 | } 75 | if (c != null) { 76 | this.setC(c) 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/LineSegment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.LineSegment 19 | import io.reactiverse.pgclient.data.Point 20 | 21 | /** 22 | * A function providing a DSL for building [io.reactiverse.pgclient.data.LineSegment] objects. 23 | * 24 | * Finite line segment data type in Postgres represented by pairs of [io.reactiverse.pgclient.data.Point]s that are the endpoints of the segment. 25 | * 26 | * @param p1 27 | * @param p2 28 | * 29 | *

30 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.LineSegment original] using Vert.x codegen. 31 | */ 32 | fun lineSegmentOf( 33 | p1: io.reactiverse.pgclient.data.Point? = null, 34 | p2: io.reactiverse.pgclient.data.Point? = null): LineSegment = io.reactiverse.pgclient.data.LineSegment().apply { 35 | 36 | if (p1 != null) { 37 | this.setP1(p1) 38 | } 39 | if (p2 != null) { 40 | this.setP2(p2) 41 | } 42 | } 43 | 44 | /** 45 | * A function providing a DSL for building [io.reactiverse.pgclient.data.LineSegment] objects. 46 | * 47 | * Finite line segment data type in Postgres represented by pairs of [io.reactiverse.pgclient.data.Point]s that are the endpoints of the segment. 48 | * 49 | * @param p1 50 | * @param p2 51 | * 52 | *

53 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.LineSegment original] using Vert.x codegen. 54 | */ 55 | @Deprecated( 56 | message = "This function will be removed in a future version", 57 | replaceWith = ReplaceWith("lineSegmentOf(p1, p2)") 58 | ) 59 | fun LineSegment( 60 | p1: io.reactiverse.pgclient.data.Point? = null, 61 | p2: io.reactiverse.pgclient.data.Point? = null): LineSegment = io.reactiverse.pgclient.data.LineSegment().apply { 62 | 63 | if (p1 != null) { 64 | this.setP1(p1) 65 | } 66 | if (p2 != null) { 67 | this.setP2(p2) 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/Path.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.Path 19 | import io.reactiverse.pgclient.data.Point 20 | 21 | /** 22 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Path] objects. 23 | * 24 | * Path data type in Postgres represented by lists of connected points. 25 | * Paths can be open, where the first and last points in the list are considered not connected, 26 | * or closed, where the first and last points are considered connected. 27 | * 28 | * @param open 29 | * @param points 30 | * 31 | *

32 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Path original] using Vert.x codegen. 33 | */ 34 | fun pathOf( 35 | open: Boolean? = null, 36 | points: Iterable? = null): Path = io.reactiverse.pgclient.data.Path().apply { 37 | 38 | if (open != null) { 39 | this.setOpen(open) 40 | } 41 | if (points != null) { 42 | this.setPoints(points.toList()) 43 | } 44 | } 45 | 46 | /** 47 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Path] objects. 48 | * 49 | * Path data type in Postgres represented by lists of connected points. 50 | * Paths can be open, where the first and last points in the list are considered not connected, 51 | * or closed, where the first and last points are considered connected. 52 | * 53 | * @param open 54 | * @param points 55 | * 56 | *

57 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Path original] using Vert.x codegen. 58 | */ 59 | @Deprecated( 60 | message = "This function will be removed in a future version", 61 | replaceWith = ReplaceWith("pathOf(open, points)") 62 | ) 63 | fun Path( 64 | open: Boolean? = null, 65 | points: Iterable? = null): Path = io.reactiverse.pgclient.data.Path().apply { 66 | 67 | if (open != null) { 68 | this.setOpen(open) 69 | } 70 | if (points != null) { 71 | this.setPoints(points.toList()) 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/Point.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.Point 19 | 20 | /** 21 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Point] objects. 22 | * 23 | * A Postgresql point. 24 | * 25 | * @param x 26 | * @param y 27 | * 28 | *

29 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Point original] using Vert.x codegen. 30 | */ 31 | fun pointOf( 32 | x: Double? = null, 33 | y: Double? = null): Point = io.reactiverse.pgclient.data.Point().apply { 34 | 35 | if (x != null) { 36 | this.setX(x) 37 | } 38 | if (y != null) { 39 | this.setY(y) 40 | } 41 | } 42 | 43 | /** 44 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Point] objects. 45 | * 46 | * A Postgresql point. 47 | * 48 | * @param x 49 | * @param y 50 | * 51 | *

52 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Point original] using Vert.x codegen. 53 | */ 54 | @Deprecated( 55 | message = "This function will be removed in a future version", 56 | replaceWith = ReplaceWith("pointOf(x, y)") 57 | ) 58 | fun Point( 59 | x: Double? = null, 60 | y: Double? = null): Point = io.reactiverse.pgclient.data.Point().apply { 61 | 62 | if (x != null) { 63 | this.setX(x) 64 | } 65 | if (y != null) { 66 | this.setY(y) 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/data/Polygon.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.data 17 | 18 | import io.reactiverse.pgclient.data.Polygon 19 | import io.reactiverse.pgclient.data.Point 20 | 21 | /** 22 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Polygon] objects. 23 | * 24 | * Polygon data type in Postgres represented by lists of points (the vertexes of the polygon). 25 | * Polygons are very similar to closed paths, but are stored differently and have their own set of support routines. 26 | * 27 | * @param points 28 | * 29 | *

30 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Polygon original] using Vert.x codegen. 31 | */ 32 | fun polygonOf( 33 | points: Iterable? = null): Polygon = io.reactiverse.pgclient.data.Polygon().apply { 34 | 35 | if (points != null) { 36 | this.setPoints(points.toList()) 37 | } 38 | } 39 | 40 | /** 41 | * A function providing a DSL for building [io.reactiverse.pgclient.data.Polygon] objects. 42 | * 43 | * Polygon data type in Postgres represented by lists of points (the vertexes of the polygon). 44 | * Polygons are very similar to closed paths, but are stored differently and have their own set of support routines. 45 | * 46 | * @param points 47 | * 48 | *

49 | * NOTE: This function has been automatically generated from the [io.reactiverse.pgclient.data.Polygon original] using Vert.x codegen. 50 | */ 51 | @Deprecated( 52 | message = "This function will be removed in a future version", 53 | replaceWith = ReplaceWith("polygonOf(points)") 54 | ) 55 | fun Polygon( 56 | points: Iterable? = null): Polygon = io.reactiverse.pgclient.data.Polygon().apply { 57 | 58 | if (points != null) { 59 | this.setPoints(points.toList()) 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/pubsub/PgChannel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.pubsub 17 | 18 | import io.reactiverse.pgclient.pubsub.PgChannel 19 | import io.vertx.core.streams.WriteStream 20 | import io.vertx.kotlin.coroutines.awaitResult 21 | 22 | suspend fun PgChannel.pipeToAwait(dst: WriteStream): Unit { 23 | return awaitResult { 24 | this.pipeTo(dst) { ar -> it.handle(ar.mapEmpty()) } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/main/kotlin/io/reactiverse/kotlin/pgclient/pubsub/PgSubscriber.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Red Hat, Inc. 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package io.reactiverse.kotlin.pgclient.pubsub 17 | 18 | import io.reactiverse.pgclient.pubsub.PgSubscriber 19 | import io.vertx.kotlin.coroutines.awaitResult 20 | 21 | /** 22 | * Suspending version of method [io.reactiverse.pgclient.pubsub.PgSubscriber.connect] 23 | * 24 | * 25 | * NOTE: This function has been automatically generated from [io.reactiverse.pgclient.pubsub.PgSubscriber] using Vert.x codegen. 26 | */ 27 | suspend fun PgSubscriber.connectAwait(): Unit { 28 | return awaitResult { 29 | this.connect { ar -> it.handle(ar.mapEmpty()) } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/ErrorCodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | /** 21 | * @author Julien Viet 22 | */ 23 | public class ErrorCodes { 24 | 25 | public static final String syntax_error = "42601"; 26 | public static final String invalid_text_representation = "22P02"; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/JdbcTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | 21 | import org.junit.After; 22 | import org.junit.Before; 23 | import org.postgresql.PGProperty; 24 | 25 | import java.sql.Connection; 26 | import java.sql.DriverManager; 27 | import java.sql.SQLException; 28 | import java.util.Properties; 29 | 30 | public class JdbcTestBase extends PgTestBase { 31 | 32 | Connection con; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | Properties props = new Properties(); 37 | PGProperty.PREPARE_THRESHOLD.set(props, -1); 38 | PGProperty.BINARY_TRANSFER.set(props, "true"); 39 | // PGProperty.BINARY_TRANSFER_ENABLE.set(props, "true"); 40 | PGProperty.USER.set(props, "postgres"); 41 | PGProperty.PASSWORD.set(props, "postgres"); 42 | con = DriverManager.getConnection("jdbc:postgresql://" 43 | + options.getHost() + ":" 44 | + options.getPort() + "/postgres", props); 45 | 46 | } 47 | 48 | @After 49 | public void tearDown() throws SQLException { 50 | if (con != null) { 51 | con.close(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/PreparedStatementCachedTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.vertx.ext.unit.Async; 21 | import io.vertx.ext.unit.TestContext; 22 | import org.junit.Test; 23 | 24 | public class PreparedStatementCachedTest extends PreparedStatementTestBase { 25 | 26 | @Override 27 | protected PgConnectOptions options() { 28 | return new PgConnectOptions(options).setCachePreparedStatements(true); 29 | } 30 | 31 | @Test 32 | public void testConcurrent(TestContext ctx) { 33 | PgClient.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> { 34 | Async[] asyncs = new Async[10]; 35 | for (int i = 0;i < 10;i++) { 36 | asyncs[i] = ctx.async(); 37 | } 38 | for (int i = 0;i < 10;i++) { 39 | Async async = asyncs[i]; 40 | conn.prepare("SELECT * FROM Fortune WHERE id=$1", ctx.asyncAssertSuccess(ps -> { 41 | ps.execute(Tuple.of(1), ctx.asyncAssertSuccess(results -> { 42 | ctx.assertEquals(1, results.size()); 43 | Tuple row = results.iterator().next(); 44 | ctx.assertEquals(1, row.getInteger(0)); 45 | ctx.assertEquals("fortune: No such file or directory", row.getString(1)); 46 | async.complete(); 47 | })); 48 | })); 49 | } 50 | })); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/PreparedStatementTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | public class PreparedStatementTest extends PreparedStatementTestBase { 21 | 22 | @Override 23 | protected PgConnectOptions options() { 24 | return new PgConnectOptions(options).setCachePreparedStatements(false); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/StringLongSequenceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient; 19 | 20 | import io.reactiverse.pgclient.impl.StringLongSequence; 21 | import io.netty.buffer.ByteBuf; 22 | import io.netty.buffer.Unpooled; 23 | import org.junit.Assert; 24 | import org.junit.Test; 25 | 26 | import java.nio.charset.StandardCharsets; 27 | 28 | public class StringLongSequenceTest { 29 | 30 | @Test 31 | public void testSequence() { 32 | StringLongSequence seq = new StringLongSequence(); 33 | assertEquals("0000000", seq.next()); 34 | assertEquals("0000001", seq.next()); 35 | assertEquals("0000002", seq.next()); 36 | assertEquals("0000003", seq.next()); 37 | assertEquals("0000004", seq.next()); 38 | assertEquals("0000005", seq.next()); 39 | assertEquals("0000006", seq.next()); 40 | assertEquals("0000007", seq.next()); 41 | assertEquals("0000008", seq.next()); 42 | assertEquals("0000009", seq.next()); 43 | assertEquals("000000A", seq.next()); 44 | assertEquals("000000B", seq.next()); 45 | assertEquals("000000C", seq.next()); 46 | assertEquals("000000D", seq.next()); 47 | assertEquals("000000E", seq.next()); 48 | assertEquals("000000F", seq.next()); 49 | assertEquals("0000010", seq.next()); 50 | } 51 | 52 | @Test 53 | public void testEndingZero() { 54 | StringLongSequence seq = new StringLongSequence(); 55 | for (int i = 0;i < 10000;i++) { 56 | Assert.assertEquals(0, seq.next() & 0xFF); 57 | } 58 | } 59 | 60 | private static void assertEquals(String s, long l) { 61 | ByteBuf buf = Unpooled.buffer(); 62 | buf.writeLong(l); 63 | String actual = buf.getCharSequence(0, 7, StandardCharsets.UTF_8).toString(); 64 | Assert.assertEquals(s, actual); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/UtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.buffer.Unpooled; 21 | import io.reactiverse.pgclient.impl.codec.util.UTF8StringEndDetector; 22 | import io.reactiverse.pgclient.impl.codec.util.Util; 23 | import io.vertx.core.buffer.Buffer; 24 | import org.junit.Test; 25 | 26 | import java.nio.charset.StandardCharsets; 27 | 28 | import static org.junit.Assert.assertEquals; 29 | 30 | public class UtilTest { 31 | 32 | @Test 33 | public void testWriteHexString() { 34 | assertWriteHexString("00", (byte) 0); 35 | assertWriteHexString("01", (byte) 1); 36 | assertWriteHexString("0a", (byte) 10); 37 | assertWriteHexString("10", (byte) 16); 38 | assertWriteHexString("ff", (byte) 255); 39 | assertWriteHexString("ff0a0a", (byte) 255, (byte)10, (byte)10); 40 | Buffer buff = Buffer.buffer(); 41 | for (int i = 0; i < 512;i++) { 42 | buff.appendByte((byte)('A' + i % 26)); 43 | } 44 | } 45 | 46 | private static void assertWriteHexString(String expected, byte... data) { 47 | ByteBuf buff = Unpooled.buffer(); 48 | Util.writeHexString(Buffer.buffer().appendBytes(data), buff); 49 | String hex = buff.toString(StandardCharsets.UTF_8); 50 | assertEquals(expected, hex); 51 | } 52 | 53 | @Test 54 | public void testUTF8StringEndDetector() throws Exception { 55 | assertSeparator("", -1); 56 | assertSeparator("\"", -1); 57 | assertSeparator("\"\"", 1); 58 | assertSeparator("\"a\"", 2); 59 | assertSeparator("\"€\"", 4); 60 | assertSeparator("\"\\\"\"", 3); 61 | } 62 | 63 | private void assertSeparator(String s, int expected) throws Exception { 64 | ByteBuf buf = Unpooled.buffer(); 65 | buf.writeCharSequence(s, StandardCharsets.UTF_8); 66 | UTF8StringEndDetector processor = new UTF8StringEndDetector(); 67 | int actual = buf.forEachByte(processor); 68 | assertEquals(expected, actual); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/BinaryDataTypesExtendedCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.Row; 5 | import io.reactiverse.pgclient.Tuple; 6 | import io.vertx.core.buffer.Buffer; 7 | import io.vertx.ext.unit.Async; 8 | import io.vertx.ext.unit.TestContext; 9 | import org.junit.Test; 10 | 11 | import java.util.Random; 12 | 13 | public class BinaryDataTypesExtendedCodecTest extends ExtendedQueryDataTypeCodecTestBase { 14 | @Test 15 | public void testBytea(TestContext ctx) { 16 | Random r = new Random(); 17 | int len = 2048; 18 | byte[] bytes = new byte[len]; 19 | r.nextBytes(bytes); 20 | Async async = ctx.async(); 21 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 22 | conn.prepare("SELECT $1::BYTEA \"Bytea\"", 23 | ctx.asyncAssertSuccess(p -> { 24 | p.execute(Tuple.of(Buffer.buffer(bytes)), ctx.asyncAssertSuccess(result -> { 25 | ColumnChecker.checkColumn(0, "Bytea") 26 | .returns(Tuple::getValue, Row::getValue, Buffer.buffer(bytes)) 27 | .returns(Tuple::getBuffer, Row::getBuffer, Buffer.buffer(bytes)) 28 | .forRow(result.iterator().next()); 29 | async.complete(); 30 | })); 31 | })); 32 | })); 33 | } 34 | 35 | @Test 36 | public void testBufferArray(TestContext ctx) { 37 | Random r = new Random(); 38 | int len = 2048; 39 | byte[] bytes = new byte[len]; 40 | r.nextBytes(bytes); 41 | Async async = ctx.async(); 42 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 43 | conn.prepare("SELECT ARRAY[$1::BYTEA] \"Bytea\"", 44 | ctx.asyncAssertSuccess(p -> { 45 | p.execute(Tuple.of(Buffer.buffer(bytes)), ctx.asyncAssertSuccess(result -> { 46 | ColumnChecker.checkColumn(0, "Bytea") 47 | .returns(Tuple::getValue, Row::getValue, new Buffer[]{Buffer.buffer(bytes)}) 48 | .returns(Tuple::getBufferArray, Row::getBufferArray, new Buffer[]{Buffer.buffer(bytes)}) 49 | .forRow(result.iterator().next()); 50 | async.complete(); 51 | })); 52 | })); 53 | })); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/BooleanTypeSimpleCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.Row; 4 | import io.reactiverse.pgclient.Tuple; 5 | import io.vertx.ext.unit.TestContext; 6 | import org.junit.Test; 7 | 8 | public class BooleanTypeSimpleCodecTest extends SimpleQueryDataTypeCodecTestBase { 9 | @Test 10 | public void testBoolean1(TestContext ctx) { 11 | testDecodeGeneric(ctx, "true", "BOOLEAN", "TrueValue", Tuple::getBoolean, Row::getBoolean, true); 12 | } 13 | 14 | @Test 15 | public void testBoolean2(TestContext ctx) { 16 | testDecodeGeneric(ctx, "false", "BOOLEAN", "FalseValue", Tuple::getBoolean, Row::getBoolean, false); 17 | } 18 | 19 | @Test 20 | public void testDecodeBOOLArray(TestContext ctx) { 21 | testDecodeGenericArray(ctx, "ARRAY ['TRUE' :: BOOLEAN,'FALSE' :: BOOLEAN]", "BooleanArray", Tuple::getBooleanArray, Row::getBooleanArray, true, false); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/CustomTypesExtendedCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.Row; 5 | import io.reactiverse.pgclient.Tuple; 6 | import io.vertx.ext.unit.Async; 7 | import io.vertx.ext.unit.TestContext; 8 | import org.junit.Test; 9 | 10 | public class CustomTypesExtendedCodecTest extends ExtendedQueryDataTypeCodecTestBase { 11 | @Test 12 | public void testEncodeCustomType(TestContext ctx) { 13 | Async async = ctx.async(); 14 | String actual = "('Othercity',\" 'Second Ave'\",f)"; 15 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 16 | conn.prepare("UPDATE \"CustomDataType\" SET \"address\" = $1 WHERE \"id\" = $2 RETURNING \"address\"", 17 | ctx.asyncAssertSuccess(p -> { 18 | p.execute(Tuple.tuple() 19 | .addString("('Othercity', 'Second Ave', false)") 20 | .addInteger(2) 21 | , ctx.asyncAssertSuccess(result -> { 22 | ctx.assertEquals(1, result.size()); 23 | ctx.assertEquals(1, result.rowCount()); 24 | Row row = result.iterator().next(); 25 | ColumnChecker.checkColumn(0, "address") 26 | .returns(Tuple::getValue, Row::getValue, actual) 27 | .returns(Tuple::getString, Row::getString, actual) 28 | .forRow(row); 29 | async.complete(); 30 | })); 31 | })); 32 | })); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/CustomTypesSimpleCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.Row; 5 | import io.reactiverse.pgclient.Tuple; 6 | import io.vertx.ext.unit.Async; 7 | import io.vertx.ext.unit.TestContext; 8 | import org.junit.Test; 9 | 10 | public class CustomTypesSimpleCodecTest extends SimpleQueryDataTypeCodecTestBase { 11 | @Test 12 | public void testCustomType(TestContext ctx) { 13 | Async async = ctx.async(); 14 | String expected = "Anytown"; 15 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 16 | conn 17 | .query("SELECT (address).city FROM \"CustomDataType\"", ctx.asyncAssertSuccess(result -> { 18 | ctx.assertEquals(2, result.size()); 19 | Row row = result.iterator().next(); 20 | ColumnChecker.checkColumn(0, "city") 21 | .returns(Tuple::getValue, Row::getValue, expected) 22 | .returns(Tuple::getString, Row::getString, expected) 23 | .forRow(row); 24 | async.complete(); 25 | })); 26 | })); 27 | } 28 | 29 | @Test 30 | public void testDecodeCustomTypeArray(TestContext ctx) { 31 | String [] addresses = new String [] {"(Anytown,\"Main St\",t)", "(Anytown,\"First St\",f)"}; 32 | 33 | testDecodeXXXArray(ctx, "CustomType", "ArrayDataType", Tuple::getStringArray, Row::getStringArray, addresses); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/DataTypeTestBase.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgConnectOptions; 4 | import io.reactiverse.pgclient.PgTestBase; 5 | import io.vertx.core.Vertx; 6 | import io.vertx.ext.unit.TestContext; 7 | import io.vertx.ext.unit.junit.VertxUnitRunner; 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.runner.RunWith; 11 | 12 | import java.time.LocalDateTime; 13 | import java.time.LocalTime; 14 | import java.time.OffsetDateTime; 15 | import java.time.OffsetTime; 16 | import java.time.format.DateTimeFormatter; 17 | import java.util.UUID; 18 | 19 | /** 20 | * @author Emad Alblueshi 21 | */ 22 | @RunWith(VertxUnitRunner.class) 23 | public abstract class DataTypeTestBase extends PgTestBase { 24 | 25 | protected Vertx vertx; 26 | 27 | protected abstract PgConnectOptions options(); 28 | 29 | protected static final UUID uuid = UUID.fromString("6f790482-b5bd-438b-a8b7-4a0bed747011"); 30 | protected static final LocalDateTime ldt = LocalDateTime.parse("2017-05-14T19:35:58.237666"); 31 | protected static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSS"); 32 | protected static final LocalTime lt = LocalTime.parse("17:55:04.90512", dtf); 33 | protected static final OffsetTime dt = OffsetTime.parse("17:55:04.90512+03:00"); 34 | protected static final OffsetDateTime odt = OffsetDateTime.parse("2017-05-15T02:59:59.237666Z"); 35 | protected static final Interval[] intervals = new Interval[] { 36 | Interval.of().years(10).months(3).days(332).hours(20).minutes(20).seconds(20).microseconds(999991), 37 | Interval.of().minutes(20).seconds(20).microseconds(123456), 38 | Interval.of().years(-2).months(-6) 39 | }; 40 | 41 | @Before 42 | public void setup() { 43 | vertx = Vertx.vertx(); 44 | } 45 | 46 | @After 47 | public void teardown(TestContext ctx) { 48 | vertx.close(ctx.asyncAssertSuccess()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/EnumeratedTypesSimpleCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.Row; 5 | import io.reactiverse.pgclient.Tuple; 6 | import io.vertx.ext.unit.Async; 7 | import io.vertx.ext.unit.TestContext; 8 | import org.junit.Test; 9 | 10 | public class EnumeratedTypesSimpleCodecTest extends SimpleQueryDataTypeCodecTestBase { 11 | @Test 12 | public void testEnum(TestContext ctx) { 13 | Async async = ctx.async(); 14 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 15 | conn 16 | .query("SELECT \"currentMood\" FROM \"EnumDataType\" WHERE \"id\" = 5", ctx.asyncAssertSuccess(result -> { 17 | ctx.assertEquals(1, result.size()); 18 | Row row = result.iterator().next(); 19 | ColumnChecker.checkColumn(0, "currentMood") 20 | .returns(Tuple::getValue, Row::getValue, "ok") 21 | .returns(Tuple::getString, Row::getString, "ok") 22 | .forRow(row); 23 | async.complete(); 24 | })); 25 | })); 26 | } 27 | 28 | @Test 29 | public void testDecodeENUMArray(TestContext ctx) { 30 | String [] moods = new String [] {"ok", "unhappy", "happy"}; 31 | testDecodeXXXArray(ctx, "Enum", "ArrayDataType", Tuple::getStringArray, Row::getStringArray, moods); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/ExtendedQueryDataTypeCodecTestBase.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.PgConnectOptions; 5 | import io.reactiverse.pgclient.Row; 6 | import io.reactiverse.pgclient.Tuple; 7 | import io.vertx.ext.unit.Async; 8 | import io.vertx.ext.unit.TestContext; 9 | 10 | import java.util.Arrays; 11 | import java.util.Iterator; 12 | import java.util.List; 13 | import java.util.function.BiFunction; 14 | import java.util.stream.Collectors; 15 | import java.util.stream.Stream; 16 | 17 | /** 18 | * @author Emad Alblueshi 19 | */ 20 | public abstract class ExtendedQueryDataTypeCodecTestBase extends DataTypeTestBase { 21 | private static void compare(TestContext ctx, T expected, T actual) { 22 | if (expected != null && expected.getClass().isArray()) { 23 | ctx.assertNotNull(actual); 24 | ctx.assertTrue(actual.getClass().isArray()); 25 | List expectedList = Arrays.asList((Object[]) expected); 26 | List actualList = Arrays.asList((Object[]) actual); 27 | ctx.assertEquals(expectedList, actualList); 28 | } else { 29 | ctx.assertEquals(expected, actual); 30 | } 31 | } 32 | 33 | @Override 34 | protected PgConnectOptions options() { 35 | return new PgConnectOptions(options).setCachePreparedStatements(false); 36 | } 37 | 38 | protected void testGeneric(TestContext ctx, String sql, T[] expected, BiFunction getter) { 39 | Async async = ctx.async(); 40 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 41 | List batch = Stream.of(expected).map(Tuple::of).collect(Collectors.toList()); 42 | conn.preparedBatch(sql, batch, 43 | ctx.asyncAssertSuccess(result -> { 44 | for (T n : expected) { 45 | ctx.assertEquals(result.size(), 1); 46 | Iterator it = result.iterator(); 47 | Row row = it.next(); 48 | compare(ctx, n, getter.apply(row, 0)); 49 | compare(ctx, n, row.getValue(0)); 50 | result = result.next(); 51 | } 52 | ctx.assertNull(result); 53 | async.complete(); 54 | })); 55 | })); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/NullSimpleCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.Row; 5 | import io.vertx.ext.unit.Async; 6 | import io.vertx.ext.unit.TestContext; 7 | import org.junit.Test; 8 | 9 | public class NullSimpleCodecTest extends SimpleQueryDataTypeCodecTestBase { 10 | @Test 11 | public void testNull(TestContext ctx) { 12 | Async async = ctx.async(); 13 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 14 | conn 15 | .query("SELECT null \"NullValue\"", ctx.asyncAssertSuccess(result -> { 16 | ctx.assertEquals(1, result.size()); 17 | Row row = result.iterator().next(); 18 | ColumnChecker.checkColumn(0, "NullValue").forRow(row); 19 | async.complete(); 20 | })); 21 | })); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/PreparedStatementParamCoercionTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.PgClient; 4 | import io.reactiverse.pgclient.PgConnectOptions; 5 | import io.reactiverse.pgclient.PgConnection; 6 | import io.reactiverse.pgclient.Tuple; 7 | import io.vertx.ext.unit.Async; 8 | import io.vertx.ext.unit.TestContext; 9 | import org.junit.Test; 10 | 11 | import java.lang.reflect.Array; 12 | import java.math.BigInteger; 13 | 14 | public class PreparedStatementParamCoercionTest extends DataTypeTestBase { 15 | 16 | @Override 17 | protected PgConnectOptions options() { 18 | return options; 19 | } 20 | 21 | private static final Object[] VALUES_TO_COERCE = { 22 | (byte)5, (short)5, 5, 5L, 5f, 5d, BigInteger.valueOf(5), Numeric.create(5) 23 | }; 24 | private static final String[] SQL_TYPES_TO_COERCE_TO = { 25 | "SMALLINT", "INTEGER", "BIGINT", "DECIMAL", "NUMERIC", "REAL", "DOUBLE PRECISION" 26 | }; 27 | 28 | @Test 29 | public void testCoerceSingleParam(TestContext ctx) { 30 | Async async = ctx.async(VALUES_TO_COERCE.length * SQL_TYPES_TO_COERCE_TO.length); 31 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 32 | for (String sqlType : SQL_TYPES_TO_COERCE_TO) { 33 | for (Object value: VALUES_TO_COERCE) { 34 | assertCoerceParam(conn, ctx, "SELECT 1 \"result\" WHERE $1::" + sqlType + "=5", value, async::countDown); 35 | } 36 | } 37 | })); 38 | } 39 | 40 | @Test 41 | public void testCoerceArrayParam(TestContext ctx) { 42 | Async async = ctx.async(VALUES_TO_COERCE.length * SQL_TYPES_TO_COERCE_TO.length); 43 | PgClient.connect(vertx, options, ctx.asyncAssertSuccess(conn -> { 44 | for (String sqlType : SQL_TYPES_TO_COERCE_TO) { 45 | for (Object value: VALUES_TO_COERCE) { 46 | Object array = Array.newInstance(value.getClass(), 1); 47 | Array.set(array, 0, value); 48 | assertCoerceParam(conn, ctx, "SELECT 1 \"result\" WHERE ($1::" + sqlType + "[])=ARRAY[5::" + sqlType + "]", array, async::countDown); 49 | } 50 | } 51 | })); 52 | } 53 | 54 | private void assertCoerceParam(PgConnection conn, TestContext ctx, String query, Object value, Runnable cont) { 55 | conn 56 | .preparedQuery(query, Tuple.of(value), 57 | ctx.asyncAssertSuccess(result -> { 58 | ctx.assertEquals(1, result.size()); 59 | ctx.assertEquals(1, result.iterator().next().getInteger(0)); 60 | cont.run(); 61 | })); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/data/UUIDTypeSimpleCodecTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.data; 2 | 3 | import io.reactiverse.pgclient.Row; 4 | import io.reactiverse.pgclient.Tuple; 5 | import io.vertx.ext.unit.TestContext; 6 | import org.junit.Test; 7 | 8 | import java.util.UUID; 9 | 10 | public class UUIDTypeSimpleCodecTest extends SimpleQueryDataTypeCodecTestBase { 11 | @Test 12 | public void testUUID(TestContext ctx) { 13 | UUID expected = UUID.fromString("50867d3d-0098-4f61-bd31-9309ebf53475"); 14 | testDecodeGeneric(ctx, "50867d3d-0098-4f61-bd31-9309ebf53475", "UUID", "uuid", Tuple::getUUID, Row::getUUID, expected); 15 | } 16 | 17 | @Test 18 | public void testDecodeUUIDArray(TestContext ctx) { 19 | testDecodeGenericArray(ctx, "ARRAY ['6f790482-b5bd-438b-a8b7-4a0bed747011' :: UUID]", "UUID", Tuple::getUUIDArray, Row::getUUIDArray, uuid); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/impl/codec/util/MD5AuthenticationTest.java: -------------------------------------------------------------------------------- 1 | package io.reactiverse.pgclient.impl.codec.util; 2 | 3 | import org.junit.Test; 4 | 5 | import java.nio.charset.StandardCharsets; 6 | 7 | import static org.junit.Assert.*; 8 | 9 | public class MD5AuthenticationTest { 10 | 11 | @Test 12 | public void encodeTest() { 13 | assertEquals( 14 | "md54cd35160716308e3e571bbba12bb7591", 15 | MD5Authentication.encode("scott", "tiger", "salt'n'pepper".getBytes(StandardCharsets.UTF_8))); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/it/EnvTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | package io.reactiverse.pgclient.it; 18 | 19 | import io.reactiverse.pgclient.PgConnectOptions; 20 | import io.reactiverse.pgclient.SslMode; 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | public class EnvTest { 26 | 27 | @Test 28 | public void testFoo() { 29 | PgConnectOptions options = PgConnectOptions.fromEnv(); 30 | assertEquals("test_host", options.getHost()); 31 | assertEquals("test_database", options.getDatabase()); 32 | assertEquals("test_user", options.getUser()); 33 | assertEquals("test_password", options.getPassword()); 34 | assertEquals(SslMode.REQUIRE, options.getSslMode()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/pool/ConnectionQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.pool; 19 | 20 | import io.reactiverse.pgclient.impl.Connection; 21 | import io.vertx.core.AsyncResult; 22 | import io.vertx.core.Future; 23 | import io.vertx.core.Handler; 24 | 25 | import java.util.ArrayDeque; 26 | import java.util.function.Consumer; 27 | 28 | class ConnectionQueue extends ArrayDeque>> implements Consumer>> { 29 | 30 | @Override 31 | public void accept(Handler> event) { 32 | add(event); 33 | } 34 | 35 | void connect(SimpleConnection conn) { 36 | poll().handle(Future.succeededFuture(conn)); 37 | } 38 | 39 | void fail(Throwable cause) { 40 | poll().handle(Future.failedFuture(cause)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/pool/SimpleConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.pool; 19 | 20 | import io.reactiverse.pgclient.impl.CommandBase; 21 | import io.reactiverse.pgclient.impl.Connection; 22 | 23 | class SimpleConnection implements Connection { 24 | 25 | Holder holder; 26 | int closed; 27 | 28 | @Override 29 | public void init(Holder holder) { 30 | this.holder = holder; 31 | } 32 | 33 | @Override 34 | public boolean isSsl() { 35 | return false; 36 | } 37 | 38 | @Override 39 | public void close(Holder holder) { 40 | closed++; 41 | } 42 | 43 | void close() { 44 | holder.handleClosed(); 45 | } 46 | 47 | @Override 48 | public void schedule(CommandBase cmd) { 49 | throw new UnsupportedOperationException(); 50 | } 51 | 52 | @Override 53 | public int getProcessId() { 54 | return -1; 55 | } 56 | 57 | @Override 58 | public int getSecretKey() { 59 | return -1; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/io/reactiverse/pgclient/pool/SimpleHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Julien Viet 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package io.reactiverse.pgclient.pool; 19 | 20 | import io.reactiverse.pgclient.impl.Connection; 21 | import io.vertx.core.AsyncResult; 22 | import io.vertx.core.Handler; 23 | 24 | class SimpleHolder implements Connection.Holder, Handler> { 25 | 26 | private Connection conn; 27 | private Throwable failure; 28 | private int closed; 29 | 30 | SimpleHolder() { 31 | } 32 | 33 | int closed() { 34 | return closed; 35 | } 36 | 37 | boolean isConnected() { 38 | return conn != null; 39 | } 40 | 41 | boolean isComplete() { 42 | return isConnected() || isFailed(); 43 | } 44 | 45 | boolean isFailed() { 46 | return failure != null; 47 | } 48 | 49 | Throwable failure() { 50 | return failure; 51 | } 52 | 53 | void init() { 54 | conn.init(this); 55 | } 56 | 57 | @Override 58 | public void handle(AsyncResult ar) { 59 | if (ar.succeeded()) { 60 | conn = ar.result(); 61 | } else { 62 | failure = ar.cause(); 63 | } 64 | } 65 | 66 | @Override 67 | public Connection connection() { 68 | return conn; 69 | } 70 | 71 | @Override 72 | public void handleClosed() { 73 | closed++; 74 | } 75 | 76 | @Override 77 | public void handleException(Throwable err) { 78 | } 79 | 80 | @Override 81 | public void handleNotification(int processId, String channel, String payload) { 82 | } 83 | 84 | void close() { 85 | conn.close(this); 86 | } 87 | } 88 | --------------------------------------------------------------------------------