Add PostgreSQL Support (#3)
Reviewed-on: #3
This commit was merged in pull request #3.
This commit is contained in:
@@ -33,4 +33,28 @@ class Count
|
||||
{
|
||||
return self::all($tableName) . ' WHERE ' . Query::whereByFields($fields, $match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to count matching documents using a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which documents should be counted
|
||||
* @return string The query to count documents using a JSON containment query
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byContains(string $tableName): string
|
||||
{
|
||||
return self::all($tableName) . ' WHERE ' . Query::whereDataContains();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to count matching documents using a JSON Path match (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which documents should be counted
|
||||
* @return string The query to count documents using a JSON Path match
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byJsonPath(string $tableName): string
|
||||
{
|
||||
return self::all($tableName) . ' WHERE ' . Query::whereJsonPathMatches();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace BitBadger\PDODocument\Query;
|
||||
|
||||
use BitBadger\PDODocument\{Configuration, DocumentException, Mode};
|
||||
use BitBadger\PDODocument\{Configuration, DocumentException, DocumentIndex, Mode};
|
||||
|
||||
/**
|
||||
* Queries to define tables and indexes
|
||||
@@ -68,4 +68,25 @@ class Definition
|
||||
{
|
||||
return str_replace('INDEX', 'UNIQUE INDEX', self::ensureIndexOn($tableName, 'key', [Configuration::$idField]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a document-wide index on a table (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table on which the document index should be created
|
||||
* @param DocumentIndex $indexType The type of index to be created
|
||||
* @return string The SQL statement to create an index on JSON documents in the specified table
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function ensureDocumentIndexOn(string $tableName, DocumentIndex $indexType): string
|
||||
{
|
||||
if (Configuration::$mode <> Mode::PgSQL) {
|
||||
throw new DocumentException('Document indexes are only supported on PostgreSQL');
|
||||
}
|
||||
[, $tbl] = self::splitSchemaAndTable($tableName);
|
||||
$extraOps = match ($indexType) {
|
||||
DocumentIndex::Full => '',
|
||||
DocumentIndex::Optimized => ' jsonb_path_ops'
|
||||
};
|
||||
return "CREATE INDEX IF NOT EXISTS idx_{$tbl}_document ON $tableName USING GIN (data$extraOps)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@ class Delete
|
||||
* Query to delete a document by its ID
|
||||
*
|
||||
* @param string $tableName The name of the table from which a document should be deleted
|
||||
* @param mixed $docId The ID of the document to be deleted (optional; string ID assumed)
|
||||
* @return string The DELETE statement to delete a document by its ID
|
||||
* @throws DocumentException If the database mode has not been set
|
||||
*/
|
||||
public static function byId(string $tableName): string
|
||||
public static function byId(string $tableName, mixed $docId = null): string
|
||||
{
|
||||
return "DELETE FROM $tableName WHERE " . Query::whereById();
|
||||
return "DELETE FROM $tableName WHERE " . Query::whereById(docId: $docId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,4 +35,28 @@ class Delete
|
||||
{
|
||||
return "DELETE FROM $tableName WHERE " . Query::whereByFields($fields, $match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to delete documents using a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table from which documents should be deleted
|
||||
* @return string The DELETE statement to delete documents via a JSON containment query
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byContains(string $tableName): string
|
||||
{
|
||||
return "DELETE FROM $tableName WHERE " . Query::whereDataContains();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to delete documents using a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table from which documents should be deleted
|
||||
* @return string The DELETE statement to delete documents via a JSON Path match
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byJsonPath(string $tableName): string
|
||||
{
|
||||
return "DELETE FROM $tableName WHERE " . Query::whereJsonPathMatches();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,13 @@ class Exists
|
||||
* Query to determine if a document exists for the given ID
|
||||
*
|
||||
* @param string $tableName The name of the table in which document existence should be checked
|
||||
* @param mixed $docId The ID of the document whose existence should be checked (optional; string ID assumed)
|
||||
* @return string The query to determine document existence by ID
|
||||
* @throws DocumentException If the database mode has not been set
|
||||
*/
|
||||
public static function byId(string $tableName): string
|
||||
public static function byId(string $tableName, mixed $docId = null): string
|
||||
{
|
||||
return self::query($tableName, Query::whereById());
|
||||
return self::query($tableName, Query::whereById(docId: $docId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,4 +47,28 @@ class Exists
|
||||
{
|
||||
return self::query($tableName, Query::whereByFields($fields, $match));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to determine if documents exist using a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which document existence should be checked
|
||||
* @return string The query to determine document existence by a JSON containment query
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byContains(string $tableName): string
|
||||
{
|
||||
return self::query($tableName, Query::whereDataContains());
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to determine if documents exist using a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which document existence should be checked
|
||||
* @return string The query to determine document existence by a JSON Path match
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byJsonPath(string $tableName): string
|
||||
{
|
||||
return self::query($tableName, Query::whereJsonPathMatches());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@ class Find
|
||||
* Query to retrieve a document by its ID
|
||||
*
|
||||
* @param string $tableName The name of the table from which a document should be retrieved
|
||||
* @param mixed $docId The ID of the document to be retrieved (optional; string ID assumed)
|
||||
* @return string The SELECT statement to retrieve a document by its ID
|
||||
* @throws DocumentException If the database mode has not been set
|
||||
*/
|
||||
public static function byId(string $tableName): string
|
||||
public static function byId(string $tableName, mixed $docId = null): string
|
||||
{
|
||||
return Query::selectFromTable($tableName) . ' WHERE ' . Query::whereById();
|
||||
return Query::selectFromTable($tableName) . ' WHERE ' . Query::whereById(docId: $docId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,4 +35,28 @@ class Find
|
||||
{
|
||||
return Query::selectFromTable($tableName) . ' WHERE ' . Query::whereByFields($fields, $match);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to retrieve documents using a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table from which documents should be retrieved
|
||||
* @return string The SELECT statement to retrieve documents by a JSON containment query
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byContains(string $tableName): string
|
||||
{
|
||||
return Query::selectFromTable($tableName) . ' WHERE ' . Query::whereDataContains();
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to retrieve documents using a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table from which documents should be retrieved
|
||||
* @return string The SELECT statement to retrieve documents by a JSON Path match
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byJsonPath(string $tableName): string
|
||||
{
|
||||
return Query::selectFromTable($tableName) . ' WHERE ' . Query::whereJsonPathMatches();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,12 +31,13 @@ class Patch
|
||||
* Query to patch (partially update) a document by its ID
|
||||
*
|
||||
* @param string $tableName The name of the table in which a document should be patched
|
||||
* @param mixed $docId The ID of the document to be patched (optional; string ID assumed)
|
||||
* @return string The query to patch a document by its ID
|
||||
* @throws DocumentException If the database mode has not been set
|
||||
*/
|
||||
public static function byId(string $tableName): string
|
||||
public static function byId(string $tableName, mixed $docId = null): string
|
||||
{
|
||||
return self::update($tableName, Query::whereById());
|
||||
return self::update($tableName, Query::whereById(docId: $docId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,4 +53,28 @@ class Patch
|
||||
{
|
||||
return self::update($tableName, Query::whereByFields($field, $match));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to patch (partially update) a document via a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which documents should be patched
|
||||
* @return string The query to patch documents via a JSON containment query
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byContains(string $tableName): string
|
||||
{
|
||||
return self::update($tableName, Query::whereDataContains());
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to patch (partially update) a document via a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which documents should be patched
|
||||
* @return string The query to patch documents via a JSON Path match
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byJsonPath(string $tableName): string
|
||||
{
|
||||
return self::update($tableName, Query::whereJsonPathMatches());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,8 @@ class RemoveFields
|
||||
{
|
||||
switch (Configuration::$mode) {
|
||||
case Mode::PgSQL:
|
||||
return "UPDATE $tableName SET data = data - " . array_keys($parameters)[0] . " WHERE $whereClause";
|
||||
return "UPDATE $tableName SET data = data - " . array_keys($parameters)[0]
|
||||
. "::text[] WHERE $whereClause";
|
||||
case Mode::SQLite:
|
||||
$paramNames = implode(', ', array_keys($parameters));
|
||||
return "UPDATE $tableName SET data = json_remove(data, $paramNames) WHERE $whereClause";
|
||||
@@ -40,12 +41,13 @@ class RemoveFields
|
||||
*
|
||||
* @param string $tableName The name of the table in which the document should be manipulated
|
||||
* @param array $parameters The parameter list for the query
|
||||
* @param mixed $docId The ID of the document from which fields should be removed (optional; string ID assumed)
|
||||
* @return string The UPDATE statement to remove fields from a document by its ID
|
||||
* @throws DocumentException If the database mode has not been set
|
||||
*/
|
||||
public static function byId(string $tableName, array $parameters): string
|
||||
public static function byId(string $tableName, array $parameters, mixed $docId = null): string
|
||||
{
|
||||
return self::update($tableName, $parameters, Query::whereById());
|
||||
return self::update($tableName, $parameters, Query::whereById(docId: $docId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,4 +65,30 @@ class RemoveFields
|
||||
{
|
||||
return self::update($tableName, $parameters, Query::whereByFields($fields, $match));
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to remove fields from documents via a JSON containment query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which documents should be manipulated
|
||||
* @param array $parameters The parameter list for the query
|
||||
* @return string The UPDATE statement to remove fields from documents via a JSON containment query
|
||||
* @throws DocumentException If the database mode is not PostgreSQL
|
||||
*/
|
||||
public static function byContains(string $tableName, array $parameters): string
|
||||
{
|
||||
return self::update($tableName, $parameters, Query::whereDataContains());
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to remove fields from documents via a JSON Path match query (PostgreSQL only)
|
||||
*
|
||||
* @param string $tableName The name of the table in which documents should be manipulated
|
||||
* @param array $parameters The parameter list for the query
|
||||
* @return string The UPDATE statement to remove fields from documents via a JSON Path match
|
||||
* @throws DocumentException
|
||||
*/
|
||||
public static function byJsonPath(string $tableName, array $parameters): string
|
||||
{
|
||||
return self::update($tableName, $parameters, Query::whereJsonPathMatches());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user