{"id":22848341,"url":"https://github.com/feedzai/pdb","last_synced_at":"2025-02-28T15:18:52.534Z","repository":{"id":10039032,"uuid":"12083899","full_name":"feedzai/pdb","owner":"feedzai","description":"PulseDB is a database-mapping software library written in Java, it provides a transparent access and manipulation to a great variety of database implementations. PDB provides a DSL that covers most of SQL functionalities and allows to easily integrate persistence into your projects and modules.","archived":false,"fork":false,"pushed_at":"2024-08-27T10:53:04.000Z","size":2325,"stargazers_count":43,"open_issues_count":35,"forks_count":29,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-11-30T00:27:29.471Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/feedzai.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-08-13T14:29:45.000Z","updated_at":"2024-08-25T05:50:45.000Z","dependencies_parsed_at":"2023-10-14T18:47:12.954Z","dependency_job_id":"aeca5b50-ae54-4209-8212-8915cca4c03e","html_url":"https://github.com/feedzai/pdb","commit_stats":null,"previous_names":[],"tags_count":69,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedzai%2Fpdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedzai%2Fpdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedzai%2Fpdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feedzai%2Fpdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/feedzai","download_url":"https://codeload.github.com/feedzai/pdb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241172992,"owners_count":19922036,"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-12-13T04:11:28.524Z","updated_at":"2025-02-28T15:18:52.513Z","avatar_url":"https://github.com/feedzai.png","language":"Java","funding_links":[],"categories":["数据库开发"],"sub_categories":[],"readme":"# PDB\n![Build PDB](https://github.com/feedzai/pdb/workflows/Build%20PDB/badge.svg?branch=master) \\\n![PDB tests with H2 embedded](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20H2%20embedded/badge.svg?branch=master) \\\n![PDB tests with PostgreSQL](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20PostgreSQL/badge.svg?branch=master) \\\n![PDB tests with SQLServer](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20SQLServer/badge.svg?branch=master) \\\n![PDB tests with CockroachDB](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20CockroachDB/badge.svg?branch=master) \\\n![PDB tests with MySQL](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20MySQL/badge.svg?branch=master) \\\n![PDB tests with Oracle](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20Oracle/badge.svg?branch=master) \\\n![PDB tests with IBM DB2](https://github.com/feedzai/pdb/workflows/PDB%20tests%20with%20IBM%20DB2/badge.svg?branch=master)\n\nPulseDB is a database-mapping software library written in Java,\nit provides a transparent access and manipulation to a great variety of database implementations.\nPDB provides a DSL that covers most of SQL functionalities and allows to easily integrate persistence into your projects and modules.\n\n## Using PDB\n\nAdd the following dependency to your Maven pom (example for PDB v2.8.14):\n\n```\n\u003cdependencies\u003e\n    ...\n\t\u003cdependency\u003e\n\t\t\u003cgroupId\u003ecom.feedzai\u003c/groupId\u003e\n\t\t\u003cartifactId\u003epdb\u003c/artifactId\u003e\n\t\t\u003cversion\u003e2.8.14\u003c/version\u003e\n\t\u003c/dependency\u003e\n\t...\n\u003c/dependencies\u003e\n```\n\n## Breaking changes\nThe timeout properties have been redefined in PdbProperties as numeric instead of strings since v2.4.6 - avoid using versions 2.4.4 and 2.4.5.\n\nDatabaseEngine interface has a new method #dropView() since v2.5.3. This method was created without a default so this led to a breaking change. Use 2.5.5 and avoid using 2.5.3 and 2.5.4.\n\nDatabaseEngine methods `#getPSResultSet(final String name)`, `#getPSIterator(final String name)`, `#getPSIterator\n(final String name, final int fetchSize)`, since 2.7.0, throw an extra `ConnectionResetException` when the database\nconnection is lost and recovered.\n\n## Changes from 2.0.0\n* It is now possible to call built-in database vendor functions [e.g. f(\"lower\", column(\"COL1\"))]\n* Added lower and upper functions\n* Fixed several connection leaks\n* Fixed MySQL large result fetching\n\n## Changes from 2.8.0\n* It now uses Guava 25.1-jre version, which might require the client to also upgrade it to match the same version\n\n## Changes from 2.8.10\n* H2 version upgraded to 2.1.210\n* `H2Engine` is now deprecated and uses the H2v2 legacy mode if this engine is used with the H2v2 driver (for more information regarding the legacy mode see: http://www.h2database.com/html/features.html)\n* The `H2V2Engine` was created and it is the engine that should be used from now on (it works on regular mode, not legacy)\n\n## Changes from 2.8.14\n* Added a multithreaded implementation for batches, that uses multiple connections to the database. This may improve\nwrite performance to the database, if it is not otherwise limited by resource usage.\n* Batch implementations should now be obtained by calling the method `DatabaseEngine#createBatch(BatchConfig)`, where the type\nof config dictates the type of batch implementation that is created.\n* NOTE: versions 2.8.12 and 2.8.13 already had introduced this, but due to a bug, creating a batch would change the DatabaseEngine,\npossibly causing it to malfunction. If using that version, avoid the new method to create batches.\n\n## Changes from 2.8.16\nVersion 2.8.15 added back compatibility with Guice v4, but also changed the method SqlBuilder.k to return K instead of Expression.\nThis breaks compatibility with existing code compiled with older PDB versions, so 2.8.16 reverts this change.\n\n## Compiling PDB\n\nIn order to compile PDB you will need to have the Oracle Driver JAR in your local repository.  \nThe current version assumes Oracle Driver version 12.2.0.1 (even when compiled with this version\n it is possible to use version 11 drivers in runtime; it is also possible to compile with\n  version 11 instead, but the oracle pom dependency has to be modified).  \nPlease download the driver from the respective\n [Oracle driver page](http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html) and\n run the following to install the driver in your local maven repository.\n```bash\nmvn install:install-file -DgroupId=com.oracle.jdbc -DartifactId=ojdbc8 \\\n-Dversion=12.2.0.1 -Dpackaging=jar -Dfile=ojdbc8.jar\n```\nAlternatively you can setup the username/password for accessing Oracle's Maven repository in your _settings.xml_ file.\n\n## Running PDB tests\n\nTo test PDB with different database engines there are several Maven profiles that can be used,\none for each vendor (check list of supported vendors below, under [Establishing a connection](#establishing-a-connection)).\n\nRun the following to run the tests for the chosen vendor **specified in lowercase**:\n```bash\nmvn test -P\u003cvendor\u003e\n```\n_NOTE_: there is also a \"special\" profile for H2 to test that engine in server mode (instead of the default H2 embedded);\n for that case the profile `h2remote` is used in the `\u003cvendor\u003e` placeholder.    \n\nThis will start a docker container running the chosen vendor's database server, and run the tests.\nThe container will be stopped at the end if all tests pass, otherwise will be kept running.\n\n**Note**: the containers will be started assuming the respective vendor's license agreements have been read and accepted.\nMore info:  \nMicrosoft SQL Server: https://hub.docker.com/r/microsoft/mssql-server-linux/  \nIBM DB2: https://hub.docker.com/r/ibmcom/db2express-c/\n\n## Getting  started\n\n### Index\n\n- [Example Description](#example-description)\n- [Establishing a connection](#establishing-a-connection)\n- Table Manipulation\n\t- [Create Table](#create-table)\n\t- [Drop Table](#drop-table)\n\t- [Alter Table](#alter-table)\n- Data Manipulation\n\t- [Insertion Queries](#insertion-queries)\n\t- [Batches](#batches)\n\t- [Updating and Deleting Queries](#updating-and-deleting-queries)\n\t- [Truncate Queries](#truncate-queries)\n\t- [Selection Queries](#selection-queries)\n\t- [Prepared Statements](#prepared-statements)\n- [Create View](#create-view)\n\n### Example Description\n\nWe describe a scenario where there are some data Providers that share Streams of data with the world.\nThese Streams have a data Type, and they are consumed by some Modules.\nThe entities and its relations are modeled into SQL using PDB in the following sections.\n\n### Establishing a connection\n\nWith PDB you connect to the database of your preference using the following code.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.engine.configuration.PdbProperties.*;\n\n(...)\n\nProperties properties = new Properties() {\n\t{\n\t\tsetProperty(JDBC, \"\u003cJDBC-CONNECTION-STRING\u003e\");\n\t\tsetProperty(USERNAME, \"username\");\n\t\tsetProperty(PASSWORD, \"password\");\n\t\tsetProperty(ENGINE, \"\u003cPDB-ENGINE\u003e\");\n\t\tsetProperty(SCHEMA_POLICY, \"create\");\n\t}\n};\n\nDatabaseEngine engine = DatabaseFactory.getConnection(properties);\n```\nThe following table shows how to connect for the supported database vendors.\n\n|Vendor|Engine|JDBC|\n|:---|:---|:---|\n|DB2|com.feedzai.commons.sql.abstraction.engine.impl.DB2Engine|jdbc:db2://\u0026lt;HOST\u0026gt;:\u0026lt;PORT\u0026gt;/\u0026lt;DATABASE\u0026gt;|\n|Oracle|com.feedzai.commons.sql.abstraction.engine.impl.OracleEngine|jdbc:oracle:thin:@\u0026lt;HOST\u0026gt;:1521:\u0026lt;DATABASE\u0026gt;|\n|PostgreSQL|com.feedzai.commons.sql.abstraction.engine.impl.PostgreSqlEngine|jdbc:postgresql://\u0026lt;HOST\u0026gt;/\u0026lt;DATABASE\u0026gt;|\n|MySQL|com.feedzai.commons.sql.abstraction.engine.impl.MySqlEngine|jdbc:mysql://\u0026lt;HOST\u0026gt;/\u0026lt;DATABASE\u0026gt;|\n|H2|com.feedzai.commons.sql.abstraction.engine.impl.H2Engine|jdbc:h2:\u0026lt;FILE\u0026gt; \u0026#124; jdbc:h2:mem|\n|SQLServer|com.feedzai.commons.sql.abstraction.engine.impl.SqlServerEngine|jdbc:sqlserver://\u0026lt;HOST\u0026gt;;database=\u0026lt;DATABASE\u0026gt;|\n\n\nIt is also important to select a schema policy. There are four possible schema policies:\n- create - New entities are created normally.\n- create-drop - Same as create policy but before the connection is closed all entries created during this session will be dropped.\n- drop-create - New entities are dropped before creation if they already exist.\n- none - The program is not allowed to create new entities.\n\n### PDB Pool Usage\nPDB natively supports connection pools. You can create one using either a `Properties` or a `Map\u003cString, String\u003e`\ninstance when defining the properties.\n```java\nfinal DatabaseEnginePool dbPool = DatabaseEnginePool.getConnectionPool(properties);\n```\n\nAdditionally, you can specify a modifier for the `DatabaseEngine`.\nThis can be useful when you need to load entities to be able to insert entries on them.\n\n```java\nfinal DatabaseEnginePool dbPool = DatabaseEnginePool.getConnectionPool(properties, engine -\u003e engine.loadEntity(entity));\n```\n\n`DatabaseEnginePool` implements `AutoClosable` so you can close the pool when you need, \nfor instance, before exiting the application.\n\nApart from the already described PDB configurations,\nyou can configure your pool using the parameters in the following table. \n\nThe `pool.generic.maxTotal`, `pool.generic.maxIdle`, `pool.generic.minIdle`, \nand `pool.generic.maxWaitMillis` are the most common ones.\n\n| Property | Description | Default value |\n| - | - | - |\n| `pool.generic.maxTotal` | The maximum number of active `DatabaseEngine` instances that can be allocated from the pool at the same time, or negative for no limit. | 8 |\n| `pool.generic.maxIdle` | The maximum number of `DatabaseEngine` instances that can remain idle in the pool, without extra ones being released, or negative for no limit. | 8 |\n| `pool.generic.minIdle` | The minimum number of `DatabaseEngine` instances that can remain idle in the pool, without extra ones being created, or zero to create none. | 0 |\n| `pool.generic.maxWaitMillis` | The maximum number of milliseconds that the pool will wait (when there are no available `DatabaseEngine` instances) for a `DatabaseEngine` instance to be returned before throwing an error, or -1 to wait indefinitely. | -1 |\n| `pool.generic.testOnCreate` | The indication of whether `DatabaseEngine` instances will be validated after creation. If the instance is invalid, the borrow attempt that triggered the `DatabaseEngine` instance creation will fail. | false |\n| `pool.generic.testOnBorrow` | The indication of whether `DatabaseEngine` instances will be validated before being borrowed from the pool. If the instance is invalid, it is dropped from the pool and another one is tried to be borrowed. | true |\n| `pool.generic.testOnReturn` | The indication of whether `DatabaseEngine` instances will be validated before being returned to the pool. | false |\n| `pool.generic.testWhileIdle` | The indication of whether `DatabaseEngine` instances will be validated by the idle evictor (if any). If an instance is invalid, it will be dropped from the pool. | false |\n| `pool.generic.timeBetweenEvictionRunsMillis` | The number of milliseconds to sleep between runs of the idle evictor thread. When non-positive, no idle evictor thread will be run. | -1 |\n| `pool.generic.numTestsPerEvictionRun` | The number of `DatabaseEngine` instances to examine during each run of the idle evictor thread (if any). | 3 |\n| `pool.generic.minEvictableIdleTimeMillis` | The minimum amount of time a `DatabaseEngine` instance may sit idle in the pool before it is eligible for eviction by the idle evictor (if any). | 1000 \\* 60 \\* 30 |\n| `pool.generic.lifo` | True means that the pool returns the most recently used (\"last in\") `DatabaseEngine` instance in the pool (if there are idle instances available). False means that the pool behaves as a FIFO queue - instances are taken from the idle instance pool in the order that they are returned to the pool. | true |\n| `pool.abandoned.removeAbandonedOnMaintenance`\u003cbr/\u003e`pool.abandoned.removeAbandonedOnBorrow` | Flags to remove abandoned `DatabaseEngine` instances if they exceed `pool.abandoned.removeAbandonedTimout`.\u003cbr/\u003eA `DatabaseEngine` instance is considered abandoned and eligible for removal if it has not been used for longer than `pool.abandoned.removeAbandonedTimeout`.\u003cbr/\u003eSetting `pool.abandoned.removeAbandonedOnMaintenance` to true removes abandoned `DatabaseEngine` instances on the maintenance cycle (when eviction ends). This property has no effect unless maintenance is enabled by setting `pool.generic.timeBetweenEvictionRunsMillis` to a positive value. \u003cbr/\u003eIf `pool.abandoned.removeAbandonedOnBorrow` is true, abandoned `DatabaseEngine` instances are removed each time a instance is borrowed from the pool, with the additional requirements that `[number of active instances]` \u003e `pool.generic.maxTotal` - 3  and `[number of idle instances]` \u003c 2 | false |\n| `pool.abandoned.removeAbandonedTimeout` | Timeout in seconds before an abandoned `DatabaseEngine` instance can be removed. | 300 |\n| `pool.abandoned.logAbandoned` | Flag to log stack traces for application code which abandoned a `DatabaseEngine` instance. | false |\n\n\u003e If no `pool.abandoned` property is defined in the configuration file, then no policy to remove abandoned `DatabaseEngine` instances is applied.\n\n### Create Table\n\nWe start by creating the table to store the different data Types:\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nDbEntity data_type_table =\n\tdbEntity()\n\t\t.name(\"data_type\")\n\t\t.addColumn(\"id\", INT, UNIQUE, NOT_NULL)\n\t\t.addColumn(\"code\", STRING, UNIQUE, NOT_NULL)\n\t\t.addColumn(\"description\", CLOB)\n\t\t.pkFields(\"id\")\n\t\t.build();\n```\n\nA table is represented with a DbEntity and its properties can be defined with methods:\n\n|Function|Description|\n|:---|:---|\n[name](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbEntity.Builder.html#name(java.lang.String))|Select the name for this table.|\n[addColumn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbEntity.Builder.html#pkFields(java.util.Collection))|Create a column with a given name and type. Additionally you can had autoincrement behaviour and define some extra constraints. There are two possible constraints available: UNIQUE and NOT_NULL.|\n[pkFields](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbEntity.Builder.html#pkFields(java.util.Collection))|Define which columns are part of the primary key.|\n\nTo create the data_type_table you call addEntity method on the previously created database engine.\nDepending on the policy you chose existing tables might be dropped before creation.\n\n```java\nengine.addEntity(data_type_table);\n```\n\nLet's now create the Providers and Streams tables:\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nDbEntity provider_table =\n\tdbEntity()\n\t\t.name(\"provider\")\n\t\t\t.addColumn(\"id\", INT, true, UNIQUE, NOT_NULL)\n\t\t\t.addColumn(\"uri\", STRING, UNIQUE, NOT_NULL)\n\t\t\t.addColumn(\"certified\", BOOLEAN, NOT_NULL)\n\t\t\t.addColumn(\"description\", CLOB)\n\t\t\t.pkFields(\"id\")\n\t\t\t.build();\n\nengine.addEntity(provider_table);\n\nDbEntity stream_table =\n\tdbEntity()\n\t.name(\"stream\")\n\t\t.addColumn(\"id\", INT, true, UNIQUE, NOT_NULL)\n\t\t.addColumn(\"provider_id\", INT, NOT_NULL)\n\t\t.addColumn(\"data_type_id\", INT, NOT_NULL)\n\t\t.addColumn(\"description\", CLOB)\n\t\t.pkFields(\"id\")\n\t\t.addFk(\n\t\t\tdbFk()\n\t\t\t\t.addColumn(\"provider_id\")\n\t\t\t\t.foreignTable(\"provider\")\n\t\t\t\t.addForeignColumn(\"id\"),\n\t\t\tdbFk()\n\t\t\t\t.addColumn(\"data_type_id\")\n\t\t\t\t.foreignTable(\"data_type\")\n\t\t\t\t.addForeignColumn(\"id\"))\n\t\t.addIndex(false, \"provider_id\", \"data_type_id\")\n\t\t.build();\n\nengine.addEntity(stream_table);\n```\n\nYou may have noticed that this stream_table has some foreign keys, which we define using the addFK method.\nThis method receives a list of the foreign keys constraints.\nA foreign key is created with dbFk(), and it is defined using these methods:\n\n|Function|Description|\n|:---|:---|\n|[addColumn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbFk.Builder.html#addColumn(java.lang.String...))|Define which columns will be part of this constraint.|\n|[foreignTable](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbFk.Builder.html#foreignTable(java.lang.String))|Define the foreign table we are referring to.|\n|[addForeignColumn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbFk.Builder.html#addColumn(java.lang.String...))|Selects the affected columns in the foreign table.|\n\nWait! Looks like we also created an index in the Stream table.\n\n|Function|Description|\n|:---|:---|\n|[addIndex](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbEntity.Builder.html#addIndex(boolean,%20java.lang.String...))|Creates and index for the listed columns. If not specified, an index is not unique.|\n\nThe rest of the example case is created with the following code:\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nDbEntity module_table =\n\tdbEntity()\n\t\t.name(\"module\")\n        .addColumn(\"name\", STRING, UNIQUE, NOT_NULL)\n        .build();\n\nengine.addEntity(module_table);\n\nDbEntity stream_to_module_table =\n\tdbEntity()\n\t\t.name(\"stream_to_module\")\n\t\t\t.addColumn(\"name\", STRING, NOT_NULL)\n\t\t\t.addColumn(\"stream_id\", INT, NOT_NULL)\n\t\t\t.addColumn(\"active\", INT)\n\t\t\t.pkFields(\"name\", \"stream_id\")\n\t\t\t.addFk(\n\t\t\t\tdbFk()\n\t\t\t\t\t.addColumn(\"name\")\n\t\t\t\t\t.foreignTable(\"module\")\n\t\t\t\t\t.addForeignColumn(\"name\"),\n\t\t\t\tdbFk()\n\t\t\t\t\t.addColumn(\"stream_id\")\n\t\t\t\t\t.foreignTable(\"stream\")\n\t\t\t\t\t.addForeignColumn(\"id\"))\n            .build();\n\nengine.addEntity(stream_to_module_table);\n```\n\n### Drop Table\n\nWhen you are done with this example you might want to clean the database.\n\n```java\nengine.dropEntity(\"stream_to_module\");\n```\n|Function|Description|\n|:---|:---|\n|[dropEntity](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#dropEntity(java.lang.String))|Drops an entity given the name.|\n\n### Alter Table\n\nWith PDB you can change some aspects of a previously created tables.\nAfter calling the the addEntity method with the created entity you can continue to modify this local representation by calling the methods described in the previous sections.\nThen to synchronize the local representation with the actual table in the database you call the updateEntity method.\n\n```java\ndata_type_table = data_type_table\n                    .newBuilder()\n                    .removeColumn(\"description\")\n                    .build();\n\nengine.updateEntity(data_type_table);\n```\n|Function|Description|\n|:---|:---|\n|[removeColumn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbEntity.Builder.html#removeColumn(java.lang.String))|Removes a column from the local representation of the table.|\n|[updateEntity](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#updateEntity(com.feedzai.commons.sql.abstraction.ddl.DbEntity))|Synchronizes the entity representation with the table in the database. If schema policy is set to drop-create the whole table is dropped and created again.|\n\nAnother mechanism to alter table is by using the AlterColumn expression creation and the executeUpdate method provided by the database engine.\nIn this case changes are made to each column, one at a time.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nExpression alterColumn = alterColumn(\n                            table(\"stream_to_module\"),\n\t\t\t\t\t        dbColumn(\"active\", BOOLEAN).addConstraint(NOT_NULL).build());\n\nengine.executeUpdate(alterColumn);\n```\n|Function|Description|\n|:---|:---|\n|[alterColumn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#alterColumn(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.ddl.DbColumn))|Creates a expression of changing a given table schema affecting a column.|\n|[dbColumn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#dbColumn(java.lang.String,%20com.feedzai.commons.sql.abstraction.ddl.DbColumnType))|Column definition. Provide new type and autoincrement behavior.|\n|[addConstraint](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbColumn.Builder.html#addConstraint(com.feedzai.commons.sql.abstraction.ddl.DbColumnConstraint))|Define the constraints you want the column to oblige to.|\n|[addConstraints](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/ddl/DbColumn.Builder.html#addConstraints(java.util.Collection))|Define the constraints you want the column to oblige to.|\n\nIt is also possible to remove the the primary key constraint.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nExpression dropPrimaryKey = dropPK(table(\"TEST\"));\n\nengine.executeUpdate(dropPrimaryKey);\n```\n|Function|Description|\n|:---|:---|\n|[dropPK](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#dropPK(com.feedzai.commons.sql.abstraction.dml.Expression))|Drops the primary key constraint on the given table.|\n\n### Insertion Queries\n\nNow that we have the structure of the database in place, let's play it with some data.\nAn EntityEntry it's our representation of an entry that we want to add to the database.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nEntityEntry data_type_entry =\n\tentry()\n\t\t.set(\"id\", 1)\n\t\t.set(\"code\", \"INT16\")\n\t\t.set(\"description\", \"The type of INT you always want!\")\n\t\t.build();\n```\n|Function|Description|\n|:---|:---|\n|[set](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/entry/EntityEntry.Builder.html#set(java.lang.String,%20java.lang.Object))|Define the value that will be assigned to a given column.|\n\nNotice that the values for each column were defined using the set method.\nA new entry for the database is persisted with engine's method persist.\n\n```java\nengine.persist(\"data_type\", data_type_entry, false);\n```\n|Function|Description|\n|:---|:---|\n|[persist](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#persist(java.lang.String,%20com.feedzai.commons.sql.abstraction.entry.EntityEntry))|Select the table in which the new entity will be inserted. If the affected table has an autoincrement column you might want to activate this flag. In case that the autoincrement behaviour is active, this method returns the generated key.|\n\nIf you want to use the autoincrement behavior you must activate the autoincrement flag when defining the entity.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nEntityEntry provider_entry =\n\tentry()\n\t\t.set(\"uri\", \"from.some.where\")\n\t\t.set(\"certified\", true)\n\t\t.build();\n\nlong generatedKey = engine.persist(\"provider\", provider_entry, true);\n```\n\n### Batches\n\nPDB also provides support for batches. With batches you reduce the amount of communication overhead, thereby improving performance.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nengine.beginTransaction();\n\ntry {\n    EntityEntry entry = entry()\n    \t.set(\"code\", \"SINT\")\n    \t.set(\"description\", \"A special kind of INT\")\n    \t.build();\n\n    engine.addBatch(\"data_type\", entry);\n\n    entry = entry()\n    \t.set(\"code\", \"VARBOOLEAN\")\n    \t.set(\"description\", \"A boolean with a variable number of truth values\")\n    \t.build();\n\n    engine.addBatch(\"data_type\", entry);\n\n    // Perform more additions...\n\n    engine.flush();\n    engine.commit();\n} finally {\n    if (engine.isTransactionActive()) {\n        engine.rollback();\n    }\n}\n```\n|Function|Description|\n|:---|:---|\n|[beginTransaction](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#beginTransaction())|Starts a transaction.|\n|[addBatch](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#addBatch(java.lang.String,%20com.feedzai.commons.sql.abstraction.entry.EntityEntry))|Adds an entry to the current batch.|\n|[flush](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#flush())|Executes all entries registered in the batch.|\n|[commit](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#commit())|Commits the current transaction transaction.|\n|[isTransactionActive](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#isTransactionActive())|Tests if the transaction is active.|\n|[rollback](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#rollback())|Rolls back the transaction.|\n\n### Updating and Deleting Queries\n\nNow you might want to the update data or simply erase them. Let's see how this can be done.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nengine.executeUpdate(\n\tupdate(table(\"stream\"))\n\t.set(\n\t\teq(column(\"cd\"), k(\"Double\")),\n\t\teq(column(\"description\", k(\"Double precision floating point number\")))\n\t.where(eq(column(id), k(1))));\n```\n\nExpressions that produce changes to the database are executed with engine's executeUpdate method.\nThere are some defined static methods that allow you to create SQL queries.\nUpdate is one of them.\nIn this section we describe queries that make changes to the database, while in the following section selection queries will be present in detail.\n\n|Function|Description|\n|:---|:---|\n|[update](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#update(com.feedzai.commons.sql.abstraction.dml.Expression))|Creates an update query that will affect the table referred by the given expression.|\n|[set](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Update.html#set(com.feedzai.commons.sql.abstraction.dml.Expression...))|Expression that defines the values that will be assigned to each given column.|\n|[where](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Update.html#where(com.feedzai.commons.sql.abstraction.dml.Expression))|Expression for filtering/selecting the affected entries.|\n|[table](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#table(java.lang.String))|Creates a reference to a table of your choice.|\n\nMaybe you want to delete entries instead. In that case creating a delete query is required.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nengine.executeUpdate(\n\tdelete(table(\"stream\")));\n\nengine.executeUpdate(\n\tdelete(table(\"stream\"\n\t\t.where(eq(column(id), k(1))));\n```\n\n|Function|Description|\n|:---|:---|\n|[delete](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#delete(com.feedzai.commons.sql.abstraction.dml.Expression))|Creates a delete query that will affect the table referred by the given expression.|\n|[where](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Delete.html#where(com.feedzai.commons.sql.abstraction.dml.Expression))|Expression for filtering/selecting the affected entries.|\n\n### Truncate Queries\n\nIf what you seek is to delete all table entries at once, it is recommended to use the truncate query.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nengine.executeUpdate(truncate(table(\"stream\")));\n```\n\n|Function|Description|\n|:---|:---|\n|[truncate](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#truncate(com.feedzai.commons.sql.abstraction.dml.Expression))|Creates a truncate query that will affect the table referred by the given expression.|\n\n### Selection Queries\n\nNow things will get interesting. In this section we will see how PDB uses SQL to select data from the database.\nUsing the query method we get the result for any given query as a list of entries.\nThese entries are represented as a map of column name to content.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nExpression query =\n\tselect(all())\n\t.from(table(\"streams\"));\n\n// Fetches everything! Use with care when you know the result set is small.\nList\u003cMap\u003cString, ResultColumn\u003e\u003e results = engine.query(query);\n\nfor(Map\u003cString, ResultColumn\u003e result : results) {\n    Int id = result.get(\"id\").toInt();\n    String description = result.get(\"description\").toString();\n\tSystem.out.println(id + \": \"+ description);\n}\n\n// If your result set is large consider using the iterator.\nResultIterator it = engine.iterator(select(all()).from(table(\"streams\")));\nMap\u003cString, ResultColumn\u003e next;\nwhile ((next = it.next()) != null) {\n    Int id = next.get(\"id\").toInt();\n    String description = next.get(\"description\").toString();\n\tSystem.out.println(id + \": \"+ description);\n}\n```\nThe iterator closes automatically when it reaches the end of the result set, but you can close it on any time by calling it.close().\n\n|Function|Description|\n|:---|:---|\n|[query](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#query(com.feedzai.commons.sql.abstraction.dml.Expression))|Processes a given query and computes the corresponding result. It returns a List of results if any. For each column a result is a Map that maps column names to ResultColumn objects.|\n|[iterator](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#iterator(com.feedzai.commons.sql.abstraction.dml.Expression))|Returns an iterator to cycle through the result set. Preferable when dealing with large result sets.|\n|[toXXX](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/result/ResultColumn.html)|ResultColumn provides methods to convert the data to the type of your preference. It throws an exception if you try to convert the underlying data to some incompatible type.|\n\nLet's see this simple query in more detail.\nWhere we list all entries in table Streams and return all columns.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(all())\n\t.from(table(\"streams\")));\n```\n|Function|Description|\n|:---|:---|\n|[select](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#select(com.feedzai.commons.sql.abstraction.dml.Expression...))|Expression defining the selection of columns or other manipulations of its values.|\n|[distinct](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#distinct())|Filter the query so it only returns distinct values.|\n|[from](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#from(com.feedzai.commons.sql.abstraction.dml.Expression...))|Defines what tables or combination of them the data must be fetched from. By default the listed sources will be joined together with an inner join.|\n|[all](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#all())|Defines a reference to all column the underlying query might return.|\n|[k](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#k(java.lang.Object))|Creates a Constant from obj.|\n|[lit](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#lit(java.lang.Object))|Creates a Literal from obj.|\n|[column](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#column(java.lang.String))|Defines a reference to a given column.|\n|[with](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#with(com.feedzai.commons.sql.abstraction.dml.Expression))|Provides a way to write auxiliary statements for use in a larger query.|\n\nThis is useful but not very interesting.\nWe should proceed by filtering the results with some condition of our choice.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(all())\n\t.from(table(\"streams\"))\n\t.where(eq(column(\"data_type_id\"), k(4)))\n\t.andWhere(like(column(\"description\"), k(\"match t%xt\"))));\n```\n|Function|Description|\n|:---|:---|\n|[where](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#where(com.feedzai.commons.sql.abstraction.dml.Expression))|Defines a series of testes a entry must oblige in order to be part of the result set.|\n|[andWhere](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#andWhere(com.feedzai.commons.sql.abstraction.dml.Expression))|If there is already ab where clause it defines an and expression with the old clause.|\n|[eq](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#eq(com.feedzai.commons.sql.abstraction.dml.Expression...))|Applies the equality condition to the expressions. It is also used in insertion queries to represent attribution.|\n|[neq](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#neq(com.feedzai.commons.sql.abstraction.dml.Expression...))|Negation of the equality condition.|\n|[like](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#like(com.feedzai.commons.sql.abstraction.dml.Expression...))|Likelihood comparison between expression. Those expression must resolve to String constants or columns of the same type.|\n|[lt](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#lt(com.feedzai.commons.sql.abstraction.dml.Expression...))|Predicate over numerical or alphanumerical values.|\n|[lteq](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#lteq(com.feedzai.commons.sql.abstraction.dml.Expression...))|Predicate over numerical or alphanumerical values.|\n|[gt](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#gt(com.feedzai.commons.sql.abstraction.dml.Expression...))|Predicate over numerical or alphanumerical values.|\n|[gteq](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#gteq(com.feedzai.commons.sql.abstraction.dml.Expression...))|Predicate over numerical or alphanumerical values.|\n\nA more complex filter would be one that select Streams from a given range of data Types and a set of Providers.\nAnd we manage just that with the following query.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(all())\n\t.from(table(\"streams\"))\n\t.where(\n\t\tand(between(column(\"data_type_id\"), k(2), k(5)),\n\t\t\tnotIn(column(\"provider_id\"), L(k(1), k(7), k(42))))));\n```\n|Function|Description|\n|:---|:---|\n|[and](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#and(com.feedzai.commons.sql.abstraction.dml.Expression...))|Computes the boolean result of the underlying expressions.|\n|[or](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#or(com.feedzai.commons.sql.abstraction.dml.Expression...))|Computes the boolean result of the underlying expressions.|\n|[between](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#between(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Defines a test condition that asserts if exp1 is part of the range of values from exp2 to exp3.|\n|[notBetween](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#notBetween(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Defines a test condition that asserts if exp1 is part of the range of values from exp2 to exp3.|\n|[in](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#in(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Defines a test condition that asserts if exp1 is part of exp2. Expression exp2 might be a List of constants or the result of a sub query.|\n|[notIn](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#notIn(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Defines a test condition that asserts if exp1 is part of exp2. Expression exp2 might be a List of constants or the result of a sub query.|\n|[L](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#L(com.feedzai.commons.sql.abstraction.dml.Expression...))|Defines a list of elements represent by the passing expressions.|\n|[caseWhen](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#caseWhen(com.feedzai.commons.sql.abstraction.dml.Expression...))|Defines a test using a list of conditions by going through them and returning a value when the first condition is met. If none are met, it will return the otherwise clause or NULL if not defined.|\n|[cast](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#cast(com.feedzai.commons.sql.abstraction.dml.Expression...))|Specifies how to perform a conversion between two data types.|\n\nIt is widely known that greater the id greater the Stream of data.\nFor this purpose you just design a query that selects the maximum Stream id of data Type 4 from Provider 1.\nYou might just get a raise for this.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(max(column(\"id\")).alias(\"the_best\"))\n\t.from(table(\"streams\"))\n\t.where(\n\t\tand(eq(column(\"data_type_id\"), k(4)),\n\t\t\teq(column(\"provider_id\"), k(1)))));\n```\n|Function|Description|\n|:---|:---|\n|[alias](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#alias(java.lang.String))|Assigns an alias to the expression.|\n|[count](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#count(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator for numeric values. They are applicable to expression involving columns.|\n|[max](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#min(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator for numeric values. They are applicable to expression involving columns.|\n|[min](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#max(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator for numeric values. They are applicable to expression involving columns.|\n|[sum](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#sum(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator for numeric values. They are applicable to expression involving columns.|\n|[avg](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#avg(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator for numeric values. They are applicable to expression involving columns.|\n|[stddev](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#stddev(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator for numeric values. They are applicable to expression involving columns.|\n|[stringAgg](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#stringAgg(com.feedzai.commons.sql.abstraction.dml.Expression))|Aggregation operator that aggregates data of a column into a string.|\n|[concat](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#concat(com.feedzai.commons.sql.abstraction.dml.Expression, com.feedzai.commons.sql.abstraction.dml.Expression...))|Concatenates the expressions with a delimiter.|\n|[floor](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#floor(com.feedzai.commons.sql.abstraction.dml.Expression))|Operator that returns the largest integer value that is smaller than or equal to a number. They are applicable to expression involving columns.|\n|[ceil](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#ceil(com.feedzai.commons.sql.abstraction.dml.Expression))|Operator that returns the smallest integer value that is larger than or equal to a number. They are applicable to expression involving columns.|\n|[udf](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#udf(java.lang.String,%20com.feedzai.commons.sql.abstraction.dml.Expression))|If you have defined your own sql function you may access it with udf.|\n\nSometimes it is required to merge the content of more than one table.\nFor that purpose you can use joins.\nThey allow you to merge content of two or more table regrading some condition.\nIn this example we provide a little bit more flavor to the result by adding the data Type information to the Stream information.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(all())\n\tfrom(table(\"stream\")\n\t\t.innerJoin((table(\"data_type\"),\n\t\t\t\t\tjoin(\n\t\t\t\t\t    column(\"stream\", \"data_type_id\"),\n\t\t\t\t\t    column(\"data_type\", \"id\")))));\n```\n|Function|Description|\n|:---|:---|\n|[innerJoin](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#innerJoin(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Merges the table results of two expression regarding a condition.|\n|[leftOuterJoin](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#leftOuterJoin(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Merges the table results of two expression regarding a condition.|\n|[rightOuterJoin](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#rightOuterJoin(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Merges the table results of two expression regarding a condition.|\n|[fullOuterJoin](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#fullOuterJoin(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Merges the table results of two expression regarding a condition.|\n|[join](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#join(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Applies the equality condition to the expressions.|\n|[union](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#union(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Unions the results of multiple expressions.|\n\nThe market is collapsing! The reason, some say, is that some provider messed up.\nIn your contract it is stated that Provider with id 4 provides a given number of streams for each data_type.\nWith the following query you will find out if the actual data in the database matches the contract.\nBy filtering the results to only account for Provider 4 and grouping on the data Type you are able to count the number of streams by Type.\nYour Boss will be pleased.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(column(\"data_type_id\"), count(column(\"id\")).alias(\"count\"))\n\t.from(table(\"streams\"))\n\t.where(eq(column(\"provider_id\"), k(4)))\n\t.groupby(column(\"data_type_id\"))\n\t.orderby(column(\"data_type_id\").asc());\n```\n|Function|Description|\n|:---|:---|\n|[groupby](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#groupby(com.feedzai.commons.sql.abstraction.dml.Expression...))|Groups the result on some of the table columns.|\n|[orderby](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#orderby(com.feedzai.commons.sql.abstraction.dml.Expression...))|Orders the result according to some expression of the table columns.|\n|[asc](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#asc())|Sets the ordering as ascendant.|\n|[desc](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Expression.html#desc())|Sets the ordering as descendant.|\n\nSome documents leaked online last week suggest that there are some hidden message in our data.\nTo visualize this hidden message we need to do some arithmetic's with the ids of the provider and data_type on table Streams.\nEven more strange is the need to filter the description column, where in case of a null value an alternative is presented.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(\n\t\tplus(\n\t\t\tcolumn(\"data_type_id\"),\n\t\t\tcolumn(\"provider_id\"),\n\t\t\tk(1)\n\t\t).alias(\"mess_ids\"),\n\t\tcoalesce(\n\t\t\tcolumn(\"description\"),\n\t\t\tk(\"Romeo must die\")))\n\t.from(table(\"streams\")));\n```\n|Function|Description|\n|:---|:---|\n|[minus](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#minus(com.feedzai.commons.sql.abstraction.dml.Expression...))|Applies the subtraction operator to the list of value with left precedence.|\n|[mult](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#mult(com.feedzai.commons.sql.abstraction.dml.Expression...))|Applies the multiplication operator to the list of value with left precedence.|\n|[plus](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#plus(com.feedzai.commons.sql.abstraction.dml.Expression...))|Applies the addiction operator to the list of value with left precedence.|\n|[div](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#div(com.feedzai.commons.sql.abstraction.dml.Expression...))|Applies the division operator to the list of value with left precedence.|\n|[mod](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#mod(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Applies the module operator to the list of value with left precedence.|\n|[coalesce](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#coalesce(com.feedzai.commons.sql.abstraction.dml.Expression,%20com.feedzai.commons.sql.abstraction.dml.Expression...))|Coalesce tests a given expression and returns its value if it is not null. If the primary expression is null, it will return the first alternative that is not.|\n\nFor this next example, imagine you want to select all Streams for which the sum of data_type_id and provider_id is greater than 5.\nIt might not be a very useful query, but when you had that you just want 10 rows of the result with and offset of 2, people might wonder what you are up to.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nresults = engine.query(\n\tselect(all())\n\t.from(table(\"streams\"))\n\t.having(\n\t\tgt(plus(\n\t\t\t\tcolumn(\"data_type_id\"),\n\t\t\t\tcolumn(\"provider_id\")),\n\t\t\tk(5)))\n\t.limit(10)\n\t.offset(2));\n```\n|Function|Description|\n|:---|:---|\n|[having](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#having(com.feedzai.commons.sql.abstraction.dml.Expression))|Query will select only the result rows where aggregate values meet the specified conditions.|\n|[limit](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#limit(java.lang.Integer))|Defines the number of rows that the query returns.|\n|[offset](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/Query.html#offset(java.lang.Integer))|Defines the offset for the start position of the resulting rows.|\n\n### Prepared Statements\n\nPDB also allows the creation of prepared statements.\nHere you have two of the previous example queries done using prepared statements\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nQuery query = select(all())\n\t\t.from(table(\"streams\"))\n\t\t.where(eq(column(\"data_type_id\"), lit(\"?\")))\n\t\t.andWhere(like(column(\"description\"), k(\"match t%xt\")));\n\nengine.createPreparedStatement(\"MyPS\", query);\n\n// It is always a good policy to clear the parameters\nengine.clearParameters(\"MyPS\");\nengine.setParameter(\"MyPS\", 1, 10);\n\nengine.executePS(\"MyPS\");\nList\u003cMap\u003cString, ResultColumn\u003e\u003e result = engine.getPSResultSet(\"MyPS\");\n```\nIn PDB prepared statements are stored internally and they are maintained if the connection is lost, but the parameters are always lost.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nUpdate update = update(table(\"stream\"))\n\t\t\t.set(\n\t\t\t\teq(column(\"cd\"), lit(\"?\")),\n\t\t\t\teq(column(\"description\", lit(\"?\")))\n\t\t\t.where(eq(column(id), k(1))));\n\nengine.createPreparedStatement(\"MyPS\", query);\n\nengine.clearParameters(\"MyPS\");\nengine.setParameter(\"MyPS\", 1, \"INT\");\nengine.setParameter(\"MyPS\", 2, \"Your regular integer implementation.\");\n\nint affectedEntries = engine.executePSUpdate(\"MyPS\");\n```\n\n|Function|Description|\n|:---|:---|\n|[createPreparedStatement](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#createPreparedStatement(java.lang.String,%20com.feedzai.commons.sql.abstraction.dml.Expression))|Creates a prepared statement and assigns it to a given identifier.|\n|[clearParameters](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#clearParameters(java.lang.String))|Clears the parameters of a given prepared statement.|\n|[setParameter](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#setParameter(java.lang.String,%20int,%20java.lang.Object))|Assigns a object to a given parameter of a prepared statement.|\n|[executePS](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#executePS(java.lang.String))|Executes a given prepared statement.|\n|[executePSUpdate](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#executePSUpdate(java.lang.String))|Executes a given update prepared statement and returns the number of affected rows.|\n|[getPSResultSet](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#getPSResultSet(java.lang.String))|Returns the result set of the last executed query.|\n|[getPSIterator](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#getPSIterator(java.lang.String))|Returns an iterator to the result set of the last executed query.|\n\n### Create View\n\nSometimes, for security reasons or just for simplicity, it is useful to have a view of the database.\n\n```java\nimport static com.feedzai.commons.sql.abstraction.dml.dialect.SqlBuilder.*;\n\n(...)\n\nExpression view = createView(\"simple_stream\")\n\t\t\t\t\t.as(select(column(\"id\"), column(\"data_type_id\"))\n\t\t\t\t\t\t.from(table(\"stream\")))\n\t\t\t\t\t.replace();\n\nengine.executeUpdate(view);\n```\n|Function|Description|\n|:---|:---|\n|[createView](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/dialect/SqlBuilder.html#createView(java.lang.String))|Creates a view with the given name.|\n|[as](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/View.html#as(com.feedzai.commons.sql.abstraction.dml.Expression))|Defines the query that provides the data for this view.|\n|[replace](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/dml/View.html#replace())|Whether or not the view creation is authorized to overwrite over existing views.|\n\n### Drop View\n\nAfter creating a view, you may also want to delete it.\n\n```java\nengine.dropView(\"view_name\");\n```\n|Function|Description|\n|:---|:---|\n|[dropView](https://feedzai.github.io/pdb/com/feedzai/commons/sql/abstraction/engine/AbstractDatabaseEngine.html#dropView(java.lang.String))|Drops a view with the given name.|\n\n\n## Further Documentation\n\nFor more insight on the available functionality please see projects [javadoc](https://feedzai.github.io/pdb).\n\n## Contact\n\nFor more information please contact opensource@feedzai.com, we will happily answer your questions.\n\n## Special Thanks\n* Miguel Miranda (miguelnmiranda@gmail.com) for the documentation and first steps on making this library opensource\n\n## License\n\nCopyright 2014 Feedzai\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeedzai%2Fpdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeedzai%2Fpdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeedzai%2Fpdb/lists"}