{"id":19090135,"url":"https://github.com/aportela/db-wrapper","last_synced_at":"2026-05-14T07:36:42.896Z","repository":{"id":56949530,"uuid":"240764810","full_name":"aportela/db-wrapper","owner":"aportela","description":"Custom php (pdo) database wrapper","archived":false,"fork":false,"pushed_at":"2025-11-29T23:42:59.000Z","size":125,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-02T04:34:36.267Z","etag":null,"topics":["composer-package","database","pdo","php","php8","sqlite3"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aportela.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-15T18:16:11.000Z","updated_at":"2025-11-29T23:42:39.000Z","dependencies_parsed_at":"2023-10-04T04:55:05.460Z","dependency_job_id":"582a6e13-96a0-418e-92de-3ea8952f470d","html_url":"https://github.com/aportela/db-wrapper","commit_stats":{"total_commits":22,"total_committers":1,"mean_commits":22.0,"dds":0.0,"last_synced_commit":"e9296c4c588337fbed6a69ffb2481336c33dec93"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/aportela/db-wrapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aportela%2Fdb-wrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aportela%2Fdb-wrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aportela%2Fdb-wrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aportela%2Fdb-wrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aportela","download_url":"https://codeload.github.com/aportela/db-wrapper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aportela%2Fdb-wrapper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33015673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["composer-package","database","pdo","php","php8","sqlite3"],"created_at":"2024-11-09T03:02:09.527Z","updated_at":"2026-05-14T07:36:42.891Z","avatar_url":"https://github.com/aportela.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# db-wrapper\n\nCustom php PDO database wrapper\n\n## Requirements\n\n- mininum php version 8.4\n\n## Limitations\n\nAt this time only SQLite, MariaDB/MySQL, PostgreSQL adapters are supported.\n\n# install\n\n```Shell\ncomposer require \"aportela/db-wrapper\"\n```\n\n# install / initializate (SQLite) database example\n\n```php\n\u003c?php\n    require (\"vendor/autoload.php\");\n\n    $settings = array\n    (\n        \"database\" =\u003e array\n        (\n            // SQLite settings (filename \u0026 path)\n            \"filename\" =\u003e \"test.db\",\n            \"path\" =\u003e __DIR__ . DIRECTORY_SEPARATOR . \"data\" . DIRECTORY_SEPARATOR\n            // custom extra settings for other adapters (MariaDB/PostgreSQL)\n            /*\n            \"host\" =\u003e \"127.0.0.1\",\n            \"port\" = \u003e 3306,\n            \"username\" =\u003e \"foo\",\n            \"password\" =\u003e \"bar\",\n            \"db\"=\u003e \"mydb\"\n            */\n        ),\n        /* uncoment next setting \u0026 comment NullLogger constructor if you want file logs with (my) custom rotating handler*/\n        /*\n        \"logger\" =\u003e array\n        (\n            \"name\" =\u003e \"test\",\n            \"filename\" =\u003e \"test-DEBUG.log\",\n            \"path\" =\u003e __DIR__ . DIRECTORY_SEPARATOR . \"data\" . DIRECTORY_SEPARATOR . \"logs\" . DIRECTORY_SEPARATOR,\n            \"level\" =\u003e \\Monolog\\Logger::DEBUG\n        )\n        */\n    );\n\n    // create database directory if not found\n    if (! file_exists($settings[\"database\"][\"path\"]))\n    {\n        mkdir($settings[\"database\"][\"path\"]);\n    }\n\n    /*\n    // uncoment this \u0026 comment NullLogger constructor if you want file logs with (my) custom rotating handler\n    // create log directory if not found\n    if (! file_exists($settings[\"logger\"][\"path\"]))\n    {\n        mkdir($settings[\"logger\"][\"path\"]);\n    }\n\n    // logger (monolog) definition\n    $logger = new \\Monolog\\Logger($settings[\"logger\"][\"name\"]);\n    $logger-\u003epushProcessor(new \\Monolog\\Processor\\UidProcessor());\n    $handler = new \\Monolog\\Handler\\RotatingFileHandler($settings[\"logger\"][\"path\"] . $settings[\"logger\"][\"filename\"], 0, $settings[\"logger\"][\"level\"]);\n    $handler-\u003esetFilenameFormat('{date}/{filename}', \\Monolog\\Handler\\RotatingFileHandler::FILE_PER_DAY);\n    $logger-\u003epushHandler($handler);\n    */\n\n    // null logger (monolog) definition\n    $logger = new \\Psr\\Log\\NullLogger(\"\");\n\n    // we are using PDO sqlite adapter\n    $adapter = new \\aportela\\DatabaseWrapper\\Adapter\\PDOSQLiteAdapter(\n        $settings[\"database\"][\"path\"] . $settings[\"database\"][\"filename\"],\n        // PDO options\n        [\n            // turn off persistent connections\n            \\PDO::ATTR_PERSISTENT =\u003e false,\n            // enable exceptions\n            \\PDO::ATTR_ERRMODE =\u003e \\PDO::ERRMODE_EXCEPTION,\n            // emulate prepared statements\n            \\PDO::ATTR_EMULATE_PREPARES =\u003e true,\n            // set default fetch mode to array\n            \\PDO::ATTR_DEFAULT_FETCH_MODE =\u003e \\PDO::FETCH_ASSOC,\n        ],\n        // optional flags, bitmask to set \"PRAGMA journal_mode = WAL\" \u0026\u0026 \"PRAGMA foreign_keys = ON\"\n        \\aportela\\DatabaseWrapper\\Adapter\\PDOSQLiteAdapter::FLAGS_PRAGMA_JOURNAL_WAL | \\aportela\\DatabaseWrapper\\Adapter\\PDOSQLiteAdapter::FLAGS_PRAGMA_FOREIGN_KEYS_ON\n    );\n    /*\n    // MariaDB adapter\n    $adapter = new \\aportela\\DatabaseWrapper\\Adapter\\PDOMariaDBAdapter(\n        $settings[\"database\"][\"host\"],\n        $settings[\"database\"][\"port\"],\n        $settings[\"database\"][\"db\"],\n        $settings[\"database\"][\"username\"],\n        $settings[\"database\"][\"password\"],\n        // PDO options\n        [\n            // turn off persistent connections\n            \\PDO::ATTR_PERSISTENT =\u003e false,\n            // enable exceptions\n            \\PDO::ATTR_ERRMODE =\u003e \\PDO::ERRMODE_EXCEPTION,\n            // emulate prepared statements\n            \\PDO::ATTR_EMULATE_PREPARES =\u003e true,\n            // set default fetch mode to array\n            \\PDO::ATTR_DEFAULT_FETCH_MODE =\u003e \\PDO::FETCH_ASSOC,\n        ]\n    );\n    // PostgreSQL adapter\n    $adapter = new \\aportela\\DatabaseWrapper\\Adapter\\PDOPostgreSQLAdapter(\n        $settings[\"database\"][\"host\"],\n        $settings[\"database\"][\"port\"],\n        $settings[\"database\"][\"db\"],\n        $settings[\"database\"][\"username\"],\n        $settings[\"database\"][\"password\"],\n        // PDO options\n        [\n            // turn off persistent connections\n            \\PDO::ATTR_PERSISTENT =\u003e false,\n            // enable exceptions\n            \\PDO::ATTR_ERRMODE =\u003e \\PDO::ERRMODE_EXCEPTION,\n            // emulate prepared statements\n            \\PDO::ATTR_EMULATE_PREPARES =\u003e true,\n            // set default fetch mode to array\n            \\PDO::ATTR_DEFAULT_FETCH_MODE =\u003e \\PDO::FETCH_ASSOC,\n        ]\n    );\n    */\n    // main object\n    $db = new \\aportela\\DatabaseWrapper\\DB\n    (\n        $adapter,\n        $logger\n    );\n\n    $success = true;\n    // check if the database is already installed (install scheme with version table already exists)\n    if (! $db-\u003eisSchemaInstalled())\n    {\n        if ($db-\u003einstallSchema())\n        {\n            echo \"Database install success\" . PHP_EOL;\n        } else\n        {\n            echo sprintf(\"Database install error, check logs (at %s)%s\", $settings[\"logger\"][\"path\"], PHP_EOL);\n            $success = false;\n        }\n    } else\n    {\n        echo \"Database already installed\" . PHP_EOL;\n    }\n\n    if ($success)\n    {\n        $results = $db-\u003equery(\" SELECT release_number, release_date FROM VERSION; \");\n        if (is_array($results) \u0026\u0026 count($results) == 1)\n        {\n            echo sprintf(\"Current version: %s (installed on: %s)%s\", $results[0]-\u003erelease_number, $results[0]-\u003erelease_date, PHP_EOL);\n        }\n        else\n        {\n            echo \"SQL error\" . PHP_EOL;\n        }\n    }\n?\u003e\n```\n\n# upgrade (SQLite) schema \u0026 exec some queries\n\n```php\n\u003c?php\nrequire(\"vendor/autoload.php\");\n\n    $settings = array(\n        \"database\" =\u003e array(\n            // SQLite settings (filename \u0026 path)\n            \"filename\" =\u003e \"test.db\",\n            \"path\" =\u003e __DIR__ . DIRECTORY_SEPARATOR . \"data\" . DIRECTORY_SEPARATOR,\n            \"upgradeSchemaPath\" =\u003e __DIR__ . DIRECTORY_SEPARATOR . \"upgrade.sql\"\n            // custom extra settings for other adapters (MariaDB/PostgreSQL)\n            /*\n                \"host\" =\u003e \"127.0.0.1\",\n                \"port\" = \u003e 3306,\n                \"username\" =\u003e \"foo\",\n                \"password\" =\u003e \"bar\",\n                \"db\"=\u003e \"mydb\"\n                */\n        ),\n        /* uncoment next setting \u0026 comment NullLogger constructor if you want file logs with (my) custom rotating handler*/\n        /*\n            \"logger\" =\u003e array\n            (\n                \"name\" =\u003e \"test\",\n                \"filename\" =\u003e \"test-DEBUG.log\",\n                \"path\" =\u003e __DIR__ . DIRECTORY_SEPARATOR . \"data\" . DIRECTORY_SEPARATOR . \"logs\" . DIRECTORY_SEPARATOR,\n                \"level\" =\u003e \\Monolog\\Logger::DEBUG\n            )\n            */\n    );\n\n    // create database directory if not found\n    if (! file_exists($settings[\"database\"][\"path\"])) {\n        mkdir($settings[\"database\"][\"path\"]);\n    }\n\n    if (! file_exists($settings[\"database\"][\"upgradeSchemaPath\"])) {\n        die(sprintf(\"Upgrade schema not found (at %s)%s\", $settings[\"database\"][\"upgradeSchemaPath\"], PHP_EOL));\n    }\n\n    /*\n        // uncoment this \u0026 comment NullLogger constructor if you want file logs with (my) custom rotating handler\n        // create log directory if not found\n        if (! file_exists($settings[\"logger\"][\"path\"]))\n        {\n            mkdir($settings[\"logger\"][\"path\"]);\n        }\n\n        // logger (monolog) definition\n        $logger = new \\Monolog\\Logger($settings[\"logger\"][\"name\"]);\n        $logger-\u003epushProcessor(new \\Monolog\\Processor\\UidProcessor());\n        $handler = new \\Monolog\\Handler\\RotatingFileHandler($settings[\"logger\"][\"path\"] . $settings[\"logger\"][\"filename\"], 0, $settings[\"logger\"][\"level\"]);\n        $handler-\u003esetFilenameFormat('{date}/{filename}', \\Monolog\\Handler\\RotatingFileHandler::FILE_PER_DAY);\n        $logger-\u003epushHandler($handler);\n        */\n\n    // null logger (monolog) definition\n    $logger = new \\Psr\\Log\\NullLogger(\"\");\n\n    // we are using PDO sqlite adapter, also set the upgrade scheme (point to a local file)\n    $adapter = new \\aportela\\DatabaseWrapper\\Adapter\\PDOSQLiteAdapter(\n        $settings[\"database\"][\"path\"] . $settings[\"database\"][\"filename\"],\n        // PDO options\n        [\n            // turn off persistent connections\n            \\PDO::ATTR_PERSISTENT =\u003e false,\n            // enable exceptions\n            \\PDO::ATTR_ERRMODE =\u003e \\PDO::ERRMODE_EXCEPTION,\n            // emulate prepared statements\n            \\PDO::ATTR_EMULATE_PREPARES =\u003e true,\n            // set default fetch mode to array\n            \\PDO::ATTR_DEFAULT_FETCH_MODE =\u003e \\PDO::FETCH_ASSOC,\n        ],\n        // optional flags, bitmask to set \"PRAGMA journal_mode = WAL\" \u0026\u0026 \"PRAGMA foreign_keys = ON\"\n        \\aportela\\DatabaseWrapper\\Adapter\\PDOSQLiteAdapter::FLAGS_PRAGMA_JOURNAL_WAL | \\aportela\\DatabaseWrapper\\Adapter\\PDOSQLiteAdapter::FLAGS_PRAGMA_FOREIGN_KEYS_ON,\n        // READ upgrade SQL schema file definition on next block of this README.md\n        $settings[\"database\"][\"upgradeSchemaPath\"]\n    );\n\n    /*\n        // MariaDB adapter\n        $adapter = new \\aportela\\DatabaseWrapper\\Adapter\\PDOMariaDBAdapter(\n            $settings[\"database\"][\"host\"],\n            $settings[\"database\"][\"port\"],\n            $settings[\"database\"][\"db\"],\n            $settings[\"database\"][\"username\"],\n            $settings[\"database\"][\"password\"],\n            // PDO options\n            [\n                // turn off persistent connections\n                \\PDO::ATTR_PERSISTENT =\u003e false,\n                // enable exceptions\n                \\PDO::ATTR_ERRMODE =\u003e \\PDO::ERRMODE_EXCEPTION,\n                // emulate prepared statements\n                \\PDO::ATTR_EMULATE_PREPARES =\u003e true,\n                // set default fetch mode to array\n                \\PDO::ATTR_DEFAULT_FETCH_MODE =\u003e \\PDO::FETCH_ASSOC,\n            ],\n            $settings[\"database\"][\"upgradeSchemaPath\"]\n        );\n        // PostgreSQL adapter\n        $adapter = new \\aportela\\DatabaseWrapper\\Adapter\\PDOPostgreSQLAdapter(\n            $settings[\"database\"][\"host\"],\n            $settings[\"database\"][\"port\"],\n            $settings[\"database\"][\"db\"],\n            $settings[\"database\"][\"username\"],\n            $settings[\"database\"][\"password\"],\n            // PDO options\n            [\n                // turn off persistent connections\n                \\PDO::ATTR_PERSISTENT =\u003e false,\n                // enable exceptions\n                \\PDO::ATTR_ERRMODE =\u003e \\PDO::ERRMODE_EXCEPTION,\n                // emulate prepared statements\n                \\PDO::ATTR_EMULATE_PREPARES =\u003e true,\n                // set default fetch mode to array\n                \\PDO::ATTR_DEFAULT_FETCH_MODE =\u003e \\PDO::FETCH_ASSOC,\n            ],\n            $settings[\"database\"][\"upgradeSchemaPath\"]\n        );\n        */\n\n    // main object\n    $db = new \\aportela\\DatabaseWrapper\\DB(\n        $adapter,\n        $logger\n    );\n\n    // try to upgrade SQL schema to last version (making a backup before any modification, change parameter to false to skip creating the backup, NOT RECOMMENDED)\n    $currentVersion = $db-\u003eupgradeSchema(true);\n    if ($currentVersion !== -1) {\n        echo sprintf(\"Database upgrade success, current version: %s%s\", $currentVersion, PHP_EOL);\n        $db-\u003equery(\" CREATE TABLE IF NOT EXISTS MYTABLE (id INTEGER PRIMARY KEY, name VARCHAR(32)); \");\n        $db-\u003equery(\n            \" INSERT INTO MYTABLE (id, name) VALUES (:id, :name) ON CONFLICT DO UPDATE SET name = :name; \",\n            [\n                new \\aportela\\DatabaseWrapper\\Param\\IntegerParam(\":id\", 1),\n                new \\aportela\\DatabaseWrapper\\Param\\StringParam(\":name\", \"foobar-\" . uniqid())\n            ]\n        );\n\n        $results = $db-\u003equery(\" SELECT id, name FROM MYTABLE ORDER BY id DESC LIMIT 1 \");\n        if (is_array($results) \u0026\u0026 count($results) == 1) {\n            echo sprintf(\"Last row was id: %s - name: %s%s\", $results[0]-\u003eid, $results[0]-\u003ename, PHP_EOL);\n        } else {\n            echo sprintf(\"SQL error, check logs (at %s)%s\", $settings[\"logger\"][\"path\"], PHP_EOL);\n        }\n\n        // after query custom function example for \"parsing\" rows\n        $afterQueryFunction = function ($rows): void {\n            array_map(\n                function ($item) {\n                    // duplicate name property into new customField\n                    $item-\u003ecustomField = $item-\u003ename;\n                    return ($item);\n                },\n                $rows\n            );\n        };\n        // use custom params \u0026\u0026 (optional) after query function\n        $results = $db-\u003equery(\n            \" SELECT id, name FROM MYTABLE WHERE id \u003e :id ORDER BY id DESC LIMIT 1 \",\n            [\n                new \\aportela\\DatabaseWrapper\\Param\\IntegerParam(\":id\", 0),\n            ],\n            $afterQueryFunction\n        );\n        if (is_array($results) \u0026\u0026 count($results) == 1) {\n            echo sprintf(\"Last row was id: %s - name: %s - customField: $%s%s\", $results[0]-\u003eid, $results[0]-\u003ename, $results[0]-\u003ecustomField, PHP_EOL);\n        } else {\n            echo sprintf(\"SQL error, check logs (at %s)%s\", $settings[\"logger\"][\"path\"], PHP_EOL);\n        }\n    } else {\n        echo sprintf(\"Database upgrade error, check logs (at %s)%s\", $settings[\"logger\"][\"path\"], PHP_EOL);\n    }\n```\n\n# upgrade SQL schema file definition example\n\ndefined on $settings block of previous example\n\n```php\n\"upgradeSchemaPath\" =\u003e __DIR__ . DIRECTORY_SEPARATOR . \"upgrade.sql\"\n```\n\n```php\n\u003c?php\n\n    return\n    (\n        array\n        (\n            1 =\u003e array\n            (\n                \" CREATE TABLE IF NOT EXISTS TABLEV1 (id INTEGER PRIMARY KEY); \",\n                \" INSERT INTO TABLEV1 VALUES (1); \"\n            ),\n            2 =\u003e array\n            (\n                \" CREATE TABLE IF NOT EXISTS TABLEV2 (id INTEGER PRIMARY KEY); \",\n            )\n        )\n    );\n\n?\u003e\n```\n\n![PHP Composer](https://github.com/aportela/db-wrapper/actions/workflows/php.yml/badge.svg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faportela%2Fdb-wrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faportela%2Fdb-wrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faportela%2Fdb-wrapper/lists"}