{"id":21336817,"url":"https://github.com/dan-da/db_extractor","last_synced_at":"2026-05-08T08:34:20.059Z","repository":{"id":72068121,"uuid":"44466998","full_name":"dan-da/db_extractor","owner":"dan-da","description":null,"archived":false,"fork":false,"pushed_at":"2015-10-19T06:55:15.000Z","size":208,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-22T14:43:31.175Z","etag":null,"topics":["crud","dao","mvc","mysql","orm","pgsql"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dan-da.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-18T05:39:12.000Z","updated_at":"2019-08-27T01:42:27.000Z","dependencies_parsed_at":"2023-03-11T11:47:34.009Z","dependency_job_id":null,"html_url":"https://github.com/dan-da/db_extractor","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan-da%2Fdb_extractor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan-da%2Fdb_extractor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan-da%2Fdb_extractor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dan-da%2Fdb_extractor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dan-da","download_url":"https://codeload.github.com/dan-da/db_extractor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243814893,"owners_count":20352038,"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":["crud","dao","mvc","mysql","orm","pgsql"],"created_at":"2024-11-21T23:55:29.158Z","updated_at":"2026-05-08T08:34:15.007Z","avatar_url":"https://github.com/dan-da.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# db_extractor\n\nThe DB extractor is a standalone script that can extract schema information from\nany mysql or postgresql DB to generate PHP data model classes. It can also\ngenerate HTML UI pages with a jquery grid for full CRUD operations.\n\nUsage is pretty simple. Normally you will just specify the database parameters,\nand possibly output directories.\n\nBy default, the model classes will go into ./db_model and the crud (ui) classes\nwill go into ./db_crud. These directories will be created if not already\nexisting.\n\nThe extractor will overwrite *.dao.base.php, *.dto.base.php, daoBase.php, and\ndaoCriteria.php. It will also overwrite all files in db_crud.\n\nThese files inherit from the above and will NOT be touched if pre-existing:\n\n *.dao.php, *.dto.php, *.custom.dao.php, *.custom.dto.php.\n \nThis allows for application customizations to be placed in the inherited files\nand it will not be overwritten when the script is run and the model is\nrefreshed.\n\n# What's the point?\n\nThe point is to simplify database access and create a consistent methodology for\naccessing any table in the database.\n\nHere's a simple code example to demonstrate how an application would use these\nclasses.\n\n```php\n\u003c?php\n\nrequire_once( dirname(__FILE__) . \"/db_model/dbFactory.php\" );\n\n// Let's create, update, retrieve, and then delete a User row.\n\n$dto_user = dbFactory::dbmf()-\u003edtoNew( 'user' );\n\n// populate the new record.\n$dto_user-\u003euser_id = null;    // leave the PK blank. it will be auto-generated\n$dto_user-\u003eusername = 'santaclaus';\n$dto_user-\u003eemail = 'nick@northpole.com';\n$dto_user-\u003efname = 'Santa';\n$dto_user-\u003elname = 'Claus';\n$dto_user-\u003epassword_hash = md5( 'some secret' );\n\n$dao_user = dbFactory::dbmf()-\u003edaoInstance( 'user' );\n\n// 1. Create.  note: $dto_user-\u003euser_id will be set here.\n$dao_user-\u003esave( $dto_user );\n\n// 2. Update.  (It will be an update because PK user_id is specified.)\n$dto_user-\u003eemail = 'santaclaus@northpole.com';\n$dao_user-\u003esave( $dto_user );\n\n// 3. Query the record by primary key.\n$dto_user = $dao_user-\u003egetByPk( $dto_user-\u003euser_id );\nprint_r( $dto_user );\n\n// 4. Delete. \n$dao_user-\u003edelete( $dto_user );\n\n```\n\nOutput should look similar to:\n\n```\nuser_dto Object\n(\n    [user_id] =\u003e 3\n    [username] =\u003e santaclaus\n    [email] =\u003e santaclaus@northpole.com\n    [password_hash] =\u003e 689f843c767642541d62a2289f764524\n    [fname] =\u003e Santa\n    [lname] =\u003e Claus\n)\n```\n\nHopefully that's enough to whet your appetite.  See the examples directory\nto get started and for examples of using the DaoCriteria object to\nprogramatically construct select ... from ... where queries.\n\n\n# Running the Script\n\nWhenever a database table is added or altered, the db_extractor script should\nbe run to update the associated db_model classes.\n\nIt is recommended to create a wrapper shell script for convenience that calls\ndb_extractor.php with appropriate params for accessing your DB, etc.\n\n```\n   db_extractor.php [Options] -d \u003cdb\u003e [-h \u003chost\u003e -d \u003cdb\u003e -u \u003cuser\u003e -p \u003cpass\u003e -c \u003ccrud_dir\u003e]\n   \n   Required:\n   -d db              database name\n   \n   Options:\n   \n   -h HOST            hostname of machine running db.     default = localhost\n   -u USER            db username\n   -p PASS            db password\n   \n   -a dbtype          mysql | postgres                    default = postgres\n\n   -m model_dir       path to write db model files.       default = ./db_model.\n                                                          specify \"=NONE=\" to omit.\n                                                          \n   -c crud_dir        path to write crud files.           default = ./db_crud.\n                                                          specify \"=NONE=\" to omit.\n                                                          \n   -s sort_cols       column ordering.                    default = original\n                        original     = use ordering from database.\n                        keys_alpha   = sort by key type desc, then alphabetical asc\n                        alpha        = sort by alphabetical asc\n                        \n   -t tables         comma separated list of tables.      default = generate for all tables\n   \n   -n namespace      a prefix that will be pre-pended to all classnames.  This makes it\n                     possible to use the generated classes multiple times in the same project.\n                                                          default = no prefix.\n\n   -x                omit message about running phpunit\n   \n   -o file            Send all output to FILE\n   -v \u003cnumber\u003e        Verbosity level.  default = 1\n                        0 = silent except fatal error.\n                        1 = silent except warnings.\n                        2 = informational\n                        3 = debug. ( includes extra logging and source line numbers )\n                        \n    -?                Print this help.\n\n```\n\n# Using the generated classes.\n\n## dbFactory\n\nThis is an optional convenience class that serves two purposes:\n\n1. A place for DB config parameters.\n2. A static method for accessing the dbModelFactory class so that it does\nnot have to be passed around the application or stored in a global location.\n\nThe application will most commonly call these three methods:\n\n```\n   // access a DAO instance.  ( represents a table )\n   dbFactory::dbmf()-\u003edaoInstance($table_name)\n   \n   // instantiate a new DTO ( represents a table row )\n   dbFactory::dbmf()-\u003edtoNew( $table_name )\n\n   // instantiate a new criteria object for select ... where criteria.   \n   dbFactory::dbmf()-\u003edaoCriteriaNew()\n```\n\n## dbModelFactory\n\nThis factory class simplifies access to the DAO and DTO objects for each table.\nThe class is auto-generated and used internally by dbFactory.  Or it\ncan be instantiated manually within your app.\n\nThe dbModelFactory class instantiates a PDO object, so it can be inefficient\nto use \"new dbModelFactory\" all over the place, because each instantiation will\ncause a new database connection to be made.\n\n\n## Data Access Objects (DAO )\n\nDAO objects contain the SQL queries.  Auto generated classes are created\nfor each table. Additionally, custom user classes can be added that\nperform queries that are not necessarily tied to a given table, eg complex\njoins or stored proc calls.\n\nThe structure looks like:\n\n```\n dao          \u003c---- one file per table.  user extensible.\n   /base      \u003c---- one file per table.  do not touch.\n   /custom    \u003c---- whatever random queries you like.\n```\n\nAny queries that fit into single-table model should be placed directly\ninto the appropriate DAO class (db_model/dao).  A query fits into the\nsingle-table model if it is a single-table query, or is a join query that is\nmostly \"about\" a single table.\n\nAll other queries should be placed into a custom DAO. (dao/custom)\n\nAll DAO objects should accept and return DTO objects as params and\nresults.\n\nA DAO object representing a single table can easily be instantiated from\nanywhere by calling:\n   dbFactory::dbmf()-\u003edaoInstance( $table )\n\nA custom DAO object can easily be instantiated from anywhere by calling:\n   dbFactory::dbmf()-\u003edaoCustomNew( $dtoName )    \n\n\n## Data Transfer Objects (DTO)\n\nDTO are the primary method of encapsulating data in this db_model.\nThey are used to represent SQL result rows where we would have used\nassociative arrays in legacy code.\n\nBoth db_adapters and DAO should instantiate DTO objects for\neach row in a resultset.  If an appropriate DTO object does not\nexist for the query, then it should be created.\n\nA DTO object representing a single table can easily be instantiated from\nanywhere by calling:\n   dbFactory::dtoNew( $table )\n\nA custom DTO object can easily be instantiated from anywhere by calling:\n   dbFactory::dtoCustomNew( $dtoName )\n   \n\n# Description of generated classes\n\n## Auto Generated DB Classes\n\n### dbModelFactory\n\nThis factory class provides a simplified way to access or instantiate DAO and\nDTO objects.\n\n(Often this class is not used directly, but rather via a static wrapper,\ndbFactory.)\n\n### [table]_dto_base\n\nThese abstract classes are automatically generated and should never be manually\nmodified, and cannot be directly instantiated. They provide a public attribute\nfor each column in a table, and each object can contain data for one DB row.\n\n### [table]_dto\n\nThese classes are automatically generated and are intended to be manually\nmodified. If the class file already exists, it will be ignored by the generator.\nThese classes inherit from \u003ctable\u003e_dto_base, and it is these wrapper classes\nthat are intended to be instantiated. \n\n### [table]_custom_dto\n\nThese classes are not generated. Rather they are intended to be written by hand\nand placed in the dto/custom directory. These classes provide a place for custom\ntypes that match an SQL query, but do NOT match any table.\n\nThe use of custom DTOs is discouraged.  In a well designed application\nthey are not typically required.\n\n\n### daoBase\n\nThis is a common base class that all dao classes inherit from. It manages the\nreference to the Dal db connection and provides some common dao methods.\n\n### [table]_dao_base\n\nThese abstract classes are automatically generated and should never be manually\nmodified, and cannot be directly instantiated. They provide basic methods for\nSQL insert, delete, update, and select operations.\n\n### [table]_dao\n\nThese classes are automatically generated and are intended to be manually\nmodified. If the class file already exists, it will be ignored by the generator.\nThese classes inherit from [table]_dao_base, and it is these wrapper classes\nthat are intended to be instantiated.\n\n### [table]_custom_dao\n\nThese classes are not generated. Rather they are intended to be written by hand\nand placed in the dao/custom directory. These classes provide a place for custom\ndao containing queries that do not fit the single-table model well. examples\ninclude calls to stored procedures or queries with complex joins, eg reports.\n\nThe use of custom DAOs is discouraged.  In a well designed application\nthey are not typically required.\n\n### daoCriteria\n\nThis class is used to programatically define SQL clauses including WHERE, ORDER\nBY, GROUP BY, LIMIT and OFFSET. In particular, the WHERE clause support is nice,\nbecause it provides support for all the major SQL operators and conditionals eg:\nor_(), and_(), equals(), greaterthan(), etc.\n\nThe class supports single table queries only. It does not currently support\nqueries that involve joins. For this, you might consider defining a view inside\nthe database, or creating a custom query in your [table]_dao class.\n\nThe daoCriteria class can be passed to the following methods of every dao\nobject:\n\n* ::getByCriteria()\n* ::updateByCriteria()\n* ::deleteByCriteria()\n\nIn the case of update or delete, only the WHERE clause criteria will be used. In\nthe case of select, all specified criteria are used.\n\nThe recommended way to instantiate daoCriteria is with\ndbFactory::dbmf()-\u003edaoCriteriaNew()\n\nSee example below.\n\n## Auto Generated CRUD Classes\n\n### crudSetup\n\nImplemented in db_crud/server/config/crudSetup.php\n\nThe crudSetup.php file is auto-generated by the extractor with the db params\nused to generated the model. So everything should work out-of-the box after\ngeneration. However, this file should be modified to suit the individual\napplication. The key requirement is that it must return a useable dbModelFactory\nobject (and corresponding DAL).\n\nBy default, this file will also look for [http://www.firephp.org/ FirePHP] in\nits PEAR location, and the crud and the CRUD and DAL layers will use it if\navailable.\n\n\n### [table]Proc\n\nImplemented in db_crud/server/[table].proc.php.  \n\nThese classes implement an ajax processor for a single table. The classes are\nintended for re-use and can be used from any top-level controller.\n\n### [table].ctl.php\n\nImplemented in db_crud/server/[table].ctl.php\n\nThese files implement a very simple ajax controller for a single table. These\ncontrollers instantiate the appropriate processor class, send utf-8 headers, and\nnot much more.\n\n### [table].html\n\nImplemented in db_crud/client/[table].html\n\nThese files implement a simple ajax client that displays a jqGrid for a single\ntable. These files are intended for use as:\n\n* simple DB administrative interface for developers.  Note: the db_crud directory should be .htaccess protected in production.\n* templates for creating more interesting user-facing features.  (in a separate directory!)\n\n\n## Quick Start and Code Examples\n\nSee the examples directory for step-by-step instructions to create a simple\ndatabase for mysql or postgresql and sample code to query and manipulate it.\n\n\n## Advice and Tips\n\n### Joining multiple tables\n\nPerhaps the biggest question that the author of a new dbAdapter may have is:\n\"where do I put queries that join multiple tables?\"\n\n#### Easiest Solution\n\nIf you only need read-only access to the query, and performance is not critical,\nconsider adding a mysql view for the query. Then you can simply re-run the\ndb_extractor and you will have a full set of classes (even jqGrid UI) for the\nquery. You just won't be able to update it.\n\nJust be aware that mysql's view implementation is pretty inefficient and you\nwill likely have lousy performance for any complex joins. Check the mysql manual\nabout views.\n\n#### Manual Solution\n\nIf the query is *MOSTLY* about a single table, then put it in the DAO for that\ntable. But be sure to create a custom DTO for the results. Otherwise, create a\ncustom DAO and a custom DTO.\n\nFor example, when working with Creatives, I may need to return information from\nAdgroup, Campaign, and Product tables. But the bulk of the information is still\nabout a Creative. so it goes in the creative DAO.\n\nIf there is a many-to-many join, then there may already be an intermediate table\nthat represents the relationship, so the query could go there.\n\nAlso keep in mind that it is easy for a particular application controller to mix\nand match multiple DB adapters. So there's no need to group unrelated queries\ntogether into the same DAO.\n\n### Bulding new features that use the CRUD files\n\nWhen building a new feature, it would be nice to re-use the CRUD processor(s).\nBut where do the HTML file and controller go?\n\n#### Answer\n\nSomewhere outside the db_crud (durc) directory.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdan-da%2Fdb_extractor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdan-da%2Fdb_extractor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdan-da%2Fdb_extractor/lists"}