{"id":19136864,"url":"https://github.com/pgjdbc/pgadba","last_synced_at":"2025-05-06T20:13:26.702Z","repository":{"id":57739864,"uuid":"120908014","full_name":"pgjdbc/pgadba","owner":"pgjdbc","description":"Implementation of Java 10 sql2 spec for PostgreSQL","archived":false,"fork":false,"pushed_at":"2023-02-05T16:51:30.000Z","size":1056,"stargazers_count":71,"open_issues_count":17,"forks_count":10,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-19T14:57:37.084Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pgjdbc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-09T13:19:35.000Z","updated_at":"2025-04-16T08:09:24.000Z","dependencies_parsed_at":"2023-02-19T00:46:05.715Z","dependency_job_id":null,"html_url":"https://github.com/pgjdbc/pgadba","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgjdbc%2Fpgadba","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgjdbc%2Fpgadba/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgjdbc%2Fpgadba/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pgjdbc%2Fpgadba/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pgjdbc","download_url":"https://codeload.github.com/pgjdbc/pgadba/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252761237,"owners_count":21800127,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T06:35:44.112Z","updated_at":"2025-05-06T20:13:26.671Z","avatar_url":"https://github.com/pgjdbc.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pgAdba\n\nAn implementation of [ADBA](http://cr.openjdk.java.net/%7Elancea/8188051/apidoc/jdk/incubator/sql2/package-summary.html), a proposed asynchronous SQL specification, for PostgreSQL.\n\n## Asynchronous querying with `Future`\n\nThe primary difference from JDBC is that with ADBA, query execution is managed using futures. \nWhen the database returns a result it completes the future, either normally or exceptionally \nif the query had an error.\n\nCompared to plain JDBC, ADBA, this decouples the network communication to the database \nfrom the business logic that produces queries and consumes the results.\n\nThis reduces the number of threads needed in the application, since there isn't any need\nfor threads to wait for the database to produce results. This in turn reduces memory \nfootprint and the amount of context switching needed.\n\n## Structural improvements over JDBC\n\n* No parsing of queries in the connection library. This significantly reduces the amount of\nwork the library needs to perform.\n\n* All queries are sent as prepared statements, this helps mitigate the problem with SQL \ninjection, as it's no longer possible to terminate one query and start a new one in the same\nstatement. It doesn't solve the SQL injection problem totally of course.\n\n* Query pipelining, the library will send query number 2 over the network without \nwaiting for the result of query number 1 if the arguments to query 2 doesn't depend on \nquery 1. This helps a great deal in reducing query time in environments where there is \nnetwork latency against the database server.\n \n\n## How does it work\n\nThe library's network stack is based on the asynchronous part of the NIO framework.\n\nThe programmer interface is a significant rework and upgrade of the old JDBC standard.\n\nThe core concepts are `DataSources`, `Sessions` and `Operations`.\n\n* `DataSource` represents the database on the other side of the network, you can start \n`Session`s from it.\n* `Session` is a connection to the database, over TCP and optionally TLS in the case of \nPostgresql. `Session`s is where you send in Operations containing SQL queries and get Futures \nback\n* Operations represent SQL queries, since there is a large amount of different types of queries,\nthere is also a number of different operations that perform different tasks.\n\n## Dependency inclusion\n\n### Maven\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.postgresql\u003c/groupId\u003e\n  \u003cartifactId\u003epgadba\u003c/artifactId\u003e\n  \u003cversion\u003e0.1.0-ALPHA\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\n```groovy\ncompile 'org.postgresql:pgadba:0.1.0-ALPHA'\n```\n\n## Examples\n\n### Creating a DataSource\n\n```java\n    DataSourceFactory.newFactory(\"org.postgresql.adba.PgDataSourceFactory\")\n        .builder()\n        .url(\"jdbc:postgresql://\" + postgres.getContainerIpAddress() + \":\" + postgres.getMappedPort(5432)\n            + \"/\" + postgres.getDatabaseName())\n        .username(postgres.getUsername())\n        .password(postgres.getPassword())\n        .build();\n```\n\nThis is a straightforward building pattern.\n\n### Performing a query\n\n```java\n    List\u003cInteger\u003e result = new ArrayList\u003c\u003e();\n    try (Session session = ds.getSession()) {\n      Submission\u003cList\u003cInteger\u003e\u003e sub = session.\u003cList\u003cInteger\u003e\u003erowOperation(\"select $1 as id\")\n          .set(\"$1\", 1, AdbaType.INTEGER)\n          .collect(() -\u003e result,\n              (list, row) -\u003e list.add(row.at(\"id\").get(Integer.class)))\n          .submit();\n      get10(sub.getCompletionStage());\n    }\n```\n\nLets go over this line by line.\n\n0. Just a list to hold the result of the operation.\n1. We start by getting a session in a try-with-resources construct. `getSession()` is a \nconvenience function that creates a ConnectionOperation and submits it to the operation \nstack\n2. Here we create a row operation, queries that returns rows generally want to use row\noperations, while queries that return the number of rows affected should use countOperations\n3. Setting of parameters, no parsing of the query is done in the library, so replacing\nthe $1 with the parameter is done by the server in the same way that prepared statements\nwork in regular jdbc.\n4. The collect call takes a standard java.util.stream.Collector, and have a overloaded \ndefault implementation that uses Collector.of().\n5. `submit()` signals that we are done building the `Operation` and want to send it off\nto be executed by the server.\n6. get10 is a helper function that waits for a future to complete, with a timeout of 10s.\n\n### Full application example\n\n[Spring Boot Example](https://github.com/alexanderkjall/pgadba-example-application-spring-boot/)\n\n## How can I get involved\n\nThis is very much a work in progress. Bail in if interested!\n\nAll bug reports, pull requests and suggestions are very welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgjdbc%2Fpgadba","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpgjdbc%2Fpgadba","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpgjdbc%2Fpgadba/lists"}