| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- <?php
- $_ = [
- 'TESTDB_CONNECTION_ERROR' => 0xFFF,
- 'TABLEEXISTS_NOT_FALSE' => 0x100,
- 'TABLEEXISTS_NOT_TRUE' => 0x101,
- 'GET_QUERY_MISMATCH' => 0x200,
- 'GET_RETURNING_WRONG_DATA' => 0x201,
- 'GET_QUERY_LIMIT_MISMATCH' => 0x202,
- 'GET_QUERY_ARRAY_LIMIT_MISMATCH' => 0x203,
- 'GET_RETURN_MISSING_RESULT' => 0x204,
- 'GET_RETURN_TOO_MANY_RESULT' => 0x205,
- 'GET_RETURN_WRONG_RESULT_TYPE_STRING' => 0x206,
- 'GET_RETURN_WRONG_RESULT_TYPE_INT' => 0x207,
- 'INSERT_QUERY_MISMATCH' => 0x300,
- 'INSERT_RETURN_WRONG_DATA' => 0x301,
- 'INSERT_RETURN_WRONG_DATA_TYPE_INT' => 0x302,
- 'INSERT_RETURN_WRONG_DATA_TYPE_STRING' => 0x303,
- 'INSERT_DUPE_PRIMARY_KEY_WRONG_ERROR_MSG' => 0x304,
- 'INSERT_RETURN_WRONG_DATA_TYPE_ARRAY' => 0x305,
- 'GETONE_QUERY_MISMATCH' => 0x400,
- 'GETONE_RETURNING_WRONG_STRUCTURE' => 0x401,
- 'GETONE_RETURNING_WRONG_DATA' => 0x402,
- 'GETONE_QUERY_COLUMN_MISMATCH' => 0x403,
- 'GETONE_RETURNING_WRONG_DATA_TYPE_INT' => 0x402,
- 'GETONE_RETURNING_WRONG_DATA_TYPE_STRING' => 0x402,
- 'GETONE_RETURNING_COLUMN_WRONG_DATA' => 0x403,
- 'WHERE_QUERY_MISMATCH' => 0x500,
- 'WHERE_RETURNING_WRONG_DATA' => 0x501,
- 'WHERE_QUERY_LITERAL_MISMATCH' => 0x502,
- 'WHERE_QUERY_ARRAY_MISMATCH' => 0x503,
- 'WHERE_RETURNING_WRONG_DATA_TYPE_INT' => 0x504,
- 'WHERE_RETURNING_WRONG_DATA_TYPE_STRING' => 0x505,
- 'WHERE_QUERY_BETWEEN_ARRAY_MISMATCH' => 0x506,
- 'WHERE_QUERY_NULL_MISMATCH' => 0x507,
- 'ORDERBY_QUERY_MISMATCH' => 0x600,
- 'ORDERBY_RETURNING_WRONG_DATA' => 0x601,
- 'ORDERBY_RETURNING_WRONG_DATA_TYPE_INT' => 0x602,
- 'ORDERBY_RETURNING_WRONG_DATA_TYPE_STRING' => 0x603,
- 'QUERY_QUERY_MISMATCH' => 0x700,
- 'QUERY_RETURNING_WRONG_DATA' => 0x701,
- 'QUERY_ARRAY_QUERY_MISMATCH' => 0x702,
- 'QUERY_ARRAY_RETURNING_WRONG_DATA' => 0x703,
- 'COUNT_QUERY_MISMATCH' => 0x800,
- 'COUNT_RETURNING_WRONG_DATA_TYPE' => 0x801,
- 'COUNT_RETURNING_WRONG_DATA' => 0x802,
- 'HAS_RETURNING_WRONG_DATA_TYPE' => 0x900,
- 'HAS_RETURNING_WRONG_DATA' => 0x901,
- 'DELETE_WHERE_NOT_DELETING' => 0xA00,
- 'DELETE_WHERE_DELETING_WRONG_ROWS' => 0xA01,
- 'DELETE_NOT_DELETING' => 0xA02,
- 'DELETE_QUERY_MISMATCH' => 0xA03,
- 'DELETE_RETURNING_WRONG_DATA' => 0xA04,
- 'DELETE_RETURNING_WRONG_DATA_TYPE_STRING' => 0xA05,
- 'JOIN_QUERY_MISMATCH' => 0xB00,
- 'JOIN_QUERY_ALIAS_MISMATCH' => 0xB01,
- 'PDO_ERRMODE_UNCHANGED_PRECONN' => 0xC00,
- 'PDO_ERRMODE_UNCHANGED_POSTCONN' => 0xC01,
- 'GROUPBY_QUERY_MISMATCH' => 0xD00,
- 'GROUPBY_RETURNING_WRONG_DATA' => 0xD01,
- 'STRING_MISMATCH' => 0xFFF,
- ];
- function fail($exit_key)
- {
- global $_;
- if (!isset($_[$exit_key])) {
- throw new RuntimeException("FAILURE: $exit_key (invalid exit code)");
- }
- $RawExitCode = $_[$exit_key];
- $ExitCode = '0x' . strtoupper(dechex($RawExitCode));
- throw new RuntimeException("FAILURE: $exit_key ($ExitCode)\n");
- }
- function expect($generated, $expect, $exit_key = 'STRING_MISMATCH')
- {
- if ($expect !== $generated) {
- echo "Mismatched string\nExpected: ", var_export($expect, true), "\n Got: ", var_export($generated, true), "\n";
- fail($exit_key);
- }
- }
- require __DIR__ . '/src/PostgresDb.php';
- use \SeinopSys\PostgresDb;
- # replacePlaceHolders() checks
- expect(
- PostgresDb::replacePlaceHolders('SELECT * FROM users WHERE id = ? AND name = ?', [1, 'John']),
- "SELECT * FROM users WHERE id = 1 AND name = 'John'"
- );
- expect(
- PostgresDb::replacePlaceHolders('SELECT * FROM users WHERE id = :id AND name = :un', [':id' => 1, ':un' => 'John']),
- "SELECT * FROM users WHERE id = 1 AND name = 'John'"
- );
- expect(
- PostgresDb::replacePlaceHolders('SELECT * FROM users WHERE id = :id AND name = ?', [':id' => 1, 'John']),
- "SELECT * FROM users WHERE id = 1 AND name = 'John'"
- );
- expect(
- PostgresDb::replacePlaceHolders('SELECT * FROM users WHERE id = :id AND name = ? AND role = ? AND password IS :pw', [':id' => 1, 'John', ':pw' => null, 'admin']),
- "SELECT * FROM users WHERE id = 1 AND name = 'John' AND role = 'admin' AND password IS NULL"
- );
- expect(
- PostgresDb::replacePlaceHolders('SELECT * FROM users WHERE id = :id AND name = ? AND role = ? AND password IS :pw', ['id' => 1, 'John', 'pw' => null, 'admin']),
- "SELECT * FROM users WHERE id = 1 AND name = 'John' AND role = 'admin' AND password IS NULL"
- );
- $db = new PostgresDb('test', 'localhost', 'postgres', '');
- function checkQuery($expect, $exit_key)
- {
- global $db;
- if ($db === null) {
- return false;
- }
- expect($db->getLastQuery(), $expect, $exit_key);
- }
- // Check tableExists & query
- try {
- $db->getConnection();
- } catch (Throwable $e) {
- var_dump($e);
- fail('TESTDB_CONNECTION_ERROR');
- }
- if ($db->tableExists('users') !== false) {
- fail('TABLEEXISTS_NOT_FALSE');
- }
- $db->query('CREATE TABLE "users" (id SERIAL NOT NULL, name CHARACTER VARYING(10), gender CHARACTER(1) NOT NULL)');
- if ($db->tableExists('users') !== true) {
- fail('TABLEEXISTS_NOT_TRUE');
- }
- // Add PRIMARY KEY constraint
- $db->query('ALTER TABLE "users" ADD CONSTRAINT "users_id" PRIMARY KEY ("id")');
- # get() Checks
- // Regular call
- $users = $db->get('users');
- checkQuery('SELECT * FROM "users"', 'GET_QUERY_MISMATCH');
- if (!is_array($users)) {
- var_dump($users);
- fail('GET_RETURNING_WRONG_DATA');
- }
- // Check get with limit
- $users = $db->get('users', 1);
- checkQuery('SELECT * FROM "users" LIMIT 1', 'GET_QUERY_LIMIT_MISMATCH');
- // Check get with array limit
- $users = $db->get('users', [10, 2]);
- checkQuery('SELECT * FROM "users" LIMIT 2 OFFSET 10', 'GET_QUERY_ARRAY_LIMIT_MISMATCH');
- // Check get with column(s)
- $users = $db->get('users', null, 'id');
- checkQuery('SELECT id FROM "users"', 'GET_QUERY_COLUMNS_MISMATCH');
- // Check get with complex column(s)
- $users = $db->get('users', null, "'ayy-'||id as happy_id");
- checkQuery("SELECT 'ayy-'||id AS happy_id FROM \"users\"", 'GET_QUERY_COLUMNS_MISMATCH');
- // Check get with column aliases
- $users = $db->get('users', null, 'id as user_id');
- checkQuery('SELECT id AS user_id FROM "users"', 'GET_QUERY_COLUMNS_MISMATCH');
- $users = $db->get('users', null, 'id as limit, name as from');
- checkQuery('SELECT id AS "limit", "name" AS "from" FROM "users"', 'GET_QUERY_COLUMNS_MISMATCH');
- # Check PDO error mode setting
- $db->setPDOErrmode(PDO::ERRMODE_EXCEPTION);
- $caught = false;
- try {
- // There's no email column so we should get an exception
- $db->getOne('users', 'email');
- } catch (PDOException $e) {
- $caught = true;
- }
- if (!$caught) {
- fail('PDO_ERRMODE_UNCHANGED_POSTCONN');
- }
- # count() Checks
- // Call
- $count = $db->count('users');
- checkQuery('SELECT COUNT(*) AS cnt FROM "users" LIMIT 1', 'COUNT_QUERY_MISMATCH');
- if (!is_int($count)) {
- fail('COUNT_RETURNING_WRONG_DATA_TYPE');
- }
- if ($count !== 0) {
- fail('COUNT_RETURNING_WRONG_DATA');
- }
- # has() Checks
- // Call
- $has = $db->has('users');
- if (!is_bool($has)) {
- fail('HAS_RETURNING_WRONG_DATA_TYPE');
- }
- if ($has !== false) {
- fail('HAS_RETURNING_WRONG_DATA');
- }
- # insert() Checks
- $return = $db->insert('users', ['name' => 'David', 'gender' => 'm']);
- checkQuery('INSERT INTO "users" ("name", gender) VALUES (\'David\', \'m\')', 'INSERT_QUERY_MISMATCH');
- if ($return !== true) {
- fail('INSERT_RETURN_WRONG_DATA');
- }
- # get() format checks
- $users = $db->get('users');
- if (!is_array($users)) {
- fail('GET_RETURNING_WRONG_DATA');
- }
- if (!isset($users[0])) {
- fail('GET_RETURN_MISSING_RESULT');
- }
- if (isset($users[1])) {
- fail('GET_RETURN_TOO_MANY_RESULT');
- }
- if (!is_string($users[0]['name'])) {
- fail('GET_RETURN_WRONG_RESULT_TYPE_STRING');
- }
- if (!is_int($users[0]['id'])) {
- fail('GET_RETURN_WRONG_RESULT_TYPE_INT');
- }
- // Check insert with returning integer
- $id = $db->insert('users', ['name' => 'Jon', 'gender' => 'm'], 'id');
- checkQuery('INSERT INTO "users" ("name", gender) VALUES (\'Jon\', \'m\') RETURNING id', 'INSERT_QUERY_MISMATCH');
- if (!is_int($id)) {
- fail('INSERT_RETURN_WRONG_DATA_TYPE_INT');
- }
- if ($id !== 2) {
- fail('INSERT_RETURN_WRONG_DATA');
- }
- // Check insert with returning string
- $name = $db->insert('users', ['name' => 'Anna', 'gender' => 'f'], 'name');
- checkQuery('INSERT INTO "users" ("name", gender) VALUES (\'Anna\', \'f\') RETURNING "name"', 'INSERT_QUERY_MISMATCH');
- if (!is_string($name)) {
- fail('INSERT_RETURN_WRONG_DATA_TYPE_STRING');
- }
- if ($name !== 'Anna') {
- fail('INSERT_RETURN_WRONG_DATA');
- }
- // Check insert with returning multiple columns
- $return = $db->insert('users', ['name' => 'Jason', 'gender' => 'm'], 'name, gender');
- checkQuery('INSERT INTO "users" ("name", gender) VALUES (\'Jason\', \'m\') RETURNING "name", gender', 'INSERT_QUERY_MISMATCH');
- if (!is_array($return)) {
- fail('INSERT_RETURN_WRONG_DATA_TYPE_ARRAY');
- }
- if ($return['name'] !== 'Jason' || $return['gender'] !== 'm') {
- fail('INSERT_RETURN_WRONG_DATA');
- }
- # where() Checks
- // Generic use
- $id1 = $db->where('id', 1)->get('users');
- checkQuery('SELECT * FROM "users" WHERE id = 1', 'WHERE_QUERY_MISMATCH');
- if (empty($id1) || !isset($id1[0]['id'])) {
- fail('WHERE_RETURNING_WRONG_DATA');
- }
- if ($id1[0]['id'] !== 1) {
- fail('WHERE_RETURNING_WRONG_DATA_TYPE_INT');
- }
- if ($id1[0]['name'] !== 'David') {
- fail('WHERE_RETURNING_WRONG_DATA_TYPE_STRING');
- }
- // Literal string check
- $id1 = $db->where('"id" = 1')->get('users');
- checkQuery('SELECT * FROM "users" WHERE "id" = 1', 'WHERE_QUERY_LITERAL_MISMATCH');
- if (empty($id1) || !isset($id1[0]['id']) || $id1[0]['id'] != 1) {
- fail('WHERE_RETURNING_WRONG_DATA');
- }
- if (!is_int($id1[0]['id'])) {
- fail('WHERE_RETURNING_WRONG_DATA_TYPE_INT');
- }
- // Null equality check
- $db->where('id', null)->get('users');
- checkQuery('SELECT * FROM "users" WHERE id IS NULL', 'WHERE_QUERY_NULL_MISMATCH');
- // Array check
- $id1 = $db->where('id', [1, 2])->orderBy('id')->get('users');
- checkQuery('SELECT * FROM "users" WHERE id IN (1, 2) ORDER BY id ASC', 'WHERE_QUERY_ARRAY_MISMATCH');
- if (empty($id1) || !isset($id1[0]['id'], $id1[1]['id']) || $id1[0]['id'] != 1 || $id1[1]['id'] != 2) {
- fail('WHERE_RETURNING_WRONG_DATA');
- }
- if (!is_int($id1[0]['id']) || !is_int($id1[1]['id'])) {
- fail('WHERE_RETURNING_WRONG_DATA_TYPE_INT');
- }
- $db->where('id', [1, 2], '!=')->orderBy('id')->get('users');
- checkQuery('SELECT * FROM "users" WHERE id NOT IN (1, 2) ORDER BY id ASC', 'WHERE_QUERY_ARRAY_MISMATCH');
- // Between array check
- $id1 = $db->where('id', [1, 2], 'BETWEEN')->orderBy('id')->get('users');
- checkQuery('SELECT * FROM "users" WHERE id BETWEEN 1 AND 2 ORDER BY id ASC', 'WHERE_QUERY_BETWEEN_ARRAY_MISMATCH');
- if (empty($id1) || !isset($id1[0]['id'], $id1[1]['id']) || $id1[0]['id'] != 1 || $id1[1]['id'] != 2) {
- fail('WHERE_RETURNING_WRONG_DATA');
- }
- if (!is_int($id1[0]['id']) || !is_int($id1[1]['id'])) {
- fail('WHERE_RETURNING_WRONG_DATA_TYPE_INT');
- }
- # getOne() Checks
- // Generic call
- $first_user = $db->where('id', 1)->getOne('users');
- checkQuery('SELECT * FROM "users" WHERE id = 1 LIMIT 1', 'GETONE_QUERY_MISMATCH');
- if (isset($first_user[0]) && is_array($first_user[0])) {
- fail('GETONE_RETURNING_WRONG_STRUCTURE');
- }
- if ($first_user['id'] != 1) {
- fail('GETONE_RETURNING_COLUMN_WRONG_DATA');
- }
- if (!is_int($first_user['id'])) {
- fail('GETONE_RETURNING_WRONG_DATA_TYPE_INT');
- }
- if (!is_string($first_user['name'])) {
- fail('GETONE_RETURNING_WRONG_DATA_TYPE_STRING');
- }
- // Columns
- $first_user = $db->where('id', 1)->getOne('users', 'id, name');
- checkQuery('SELECT id, "name" FROM "users" WHERE id = 1 LIMIT 1', 'GETONE_QUERY_COLUMN_MISMATCH');
- if ($first_user['id'] != 1) {
- fail('GETONE_RETURNING_COLUMN_WRONG_DATA');
- }
- if (!is_int($first_user['id'])) {
- fail('GETONE_RETURNING_WRONG_DATA_TYPE_INT');
- }
- if (!is_string($first_user['name'])) {
- fail('GETONE_RETURNING_WRONG_DATA_TYPE_STRING');
- }
- # orderBy() Checks
- // Generic call
- $last_user = $db->orderBy('id', 'DESC')->getOne('users');
- checkQuery('SELECT * FROM "users" ORDER BY id DESC LIMIT 1', 'ORDERBY_QUERY_MISMATCH');
- if (!isset($last_user['id'])) {
- fail('ORDERBY_RETURNING_WRONG_DATA');
- }
- if ($last_user['id'] != 4) {
- fail('ORDERBY_RETURNING_WRONG_DATA');
- }
- if (!is_int($last_user['id'])) {
- fail('ORDERBY_RETURNING_WRONG_DATA_TYPE_INT');
- }
- if (!is_string($last_user['name'])) {
- fail('ORDERBY_RETURNING_WRONG_DATA_TYPE_STRING');
- }
- # groupBy() Checks
- // Generic call
- $gender_count = $db->groupBy('gender')->orderBy('cnt', 'DESC')->get('users', null, 'gender, COUNT(*) as cnt');
- checkQuery('SELECT gender, COUNT(*) AS cnt FROM "users" GROUP BY gender ORDER BY cnt DESC', 'GROUPBY_QUERY_MISMATCH');
- if (!isset($gender_count[0]['cnt'], $gender_count[1]['cnt'], $gender_count[0]['gender'], $gender_count[1]['gender'])) {
- fail('GROUPBY_RETURNING_WRONG_DATA');
- }
- if ($gender_count[0]['cnt'] !== 3 || $gender_count[1]['cnt'] !== 1 || $gender_count[0]['gender'] !== 'm' || $gender_count[1]['gender'] !== 'f') {
- fail('GROUPBY_RETURNING_WRONG_DATA');
- }
- # query() Checks
- // No bound parameters
- $first_two_users = $db->query('SELECT * FROM "users" WHERE id <= 2');
- checkQuery('SELECT * FROM "users" WHERE id <= 2', 'QUERY_QUERY_MISMATCH');
- if (!is_array($first_two_users)) {
- fail('QUERY_RETURNING_WRONG_DATA');
- }
- if (count($first_two_users) !== 2) {
- fail('QUERY_RETURNING_WRONG_DATA');
- }
- // Bound parameters
- $first_two_users = $db->query('SELECT * FROM "users" WHERE id <= ?', [2]);
- checkQuery('SELECT * FROM "users" WHERE id <= 2', 'QUERY_QUERY_MISMATCH');
- if (!is_array($first_two_users)) {
- fail('QUERY_RETURNING_WRONG_DATA');
- }
- if (count($first_two_users) !== 2) {
- fail('QUERY_RETURNING_WRONG_DATA');
- }
- # getLastError Check
- $caught = false;
- try {
- // An entry with an id of 1 already exists, we should get an exception
- $Insert = @$db->insert('users', ['id' => 1, 'name' => 'Sam', 'gender' => 'm']);
- } catch (PDOException $e) {
- $caught = true;
- }
- if (!$caught) {
- fail('INSERT_DUPE_PRIMARY_KEY_NOT_RECOGNIZED');
- }
- if (strpos($db->getLastError(), 'duplicate key value violates unique constraint') === false) {
- fail('INSERT_DUPE_PRIMARY_KEY_WRONG_ERROR_MSG');
- }
- # count() Re-check
- // Call
- $count = $db->count('users');
- if ($count !== 4) {
- fail('COUNT_RETURNING_WRONG_DATA');
- }
- # has() Checks
- // Call
- $has = $db->has('users');
- if (!is_bool($has)) {
- fail('HAS_RETURNING_WRONG_DATA_TYPE');
- }
- if ($has !== true) {
- fail('HAS_RETURNING_WRONG_DATA');
- }
- # delete() Checks
- // Call with where()
- $db->where('id', 3)->delete('users');
- checkQuery('DELETE FROM "users" WHERE id = 3', 'DELETE_QUERY_MISMATCH');
- if ($db->where('id', 3)->has('users')) {
- fail('DELETE_WHERE_NOT_DELETING');
- }
- if ($db->where('id', 3, '<')->count('users') !== 2) {
- fail('DELETE_WHERE_DELETING_WRONG_ROWS');
- }
- // Standalone call
- $db->delete('users');
- checkQuery('DELETE FROM "users"', 'DELETE_QUERY_MISMATCH');
- if ($db->has('users')) {
- fail('DELETE_NOT_DELETING');
- }
- // Array
- $db->where('id', [3, 4])->delete('users');
- checkQuery('DELETE FROM "users" WHERE id IN (3, 4)', 'DELETE_QUERY_MISMATCH');
- // Returning data
- $db->insert('users', ['id' => 10, 'name' => 'Ada', 'gender' => 'f']);
- $return = $db->where('id', 10)->delete('users', ['name','gender']);
- checkQuery('DELETE FROM "users" WHERE id = 10 RETURNING "name", gender', 'DELETE_QUERY_MISMATCH');
- if (!is_array($return)) {
- fail('DELETE_RETURNING_WRONG_DATA');
- }
- if (!isset($return['name'], $return['gender']) || $return['name'] !== 'Ada' || $return['gender'] !== 'f') {
- fail('DELETE_RETURNING_WRONG_DATA_TYPE_STRING');
- }
- # join() Checks
- $db->query('CREATE TABLE "userdata" (id SERIAL NOT NULL, somevalue INTEGER)');
- $db->insert('userdata', ['somevalue' => 1]);
- $db->join('userdata', 'userdata.id = users.id', 'LEFT')->where('users.id', 1)->get('users', null, 'users.*');
- checkQuery('SELECT "users".* FROM "users" LEFT JOIN "userdata" ON userdata.id = users.id WHERE "users".id = 1', 'JOIN_QUERY_MISMATCH');
- $db->join('userdata ud', 'ud.id = u.id', 'LEFT')->where('u.id', 1)->get('users u', null, 'u.*');
- checkQuery('SELECT "u".* FROM "users" u LEFT JOIN "userdata" ud ON ud.id = u.id WHERE "u".id = 1', 'JOIN_QUERY_ALIAS_MISMATCH');
|