Get Database metadata PHP/PDO - php

Is there a way to get the database metadata using PHP's PDO.
I'm looking for something similar to the Java JDBC DatabaseMetadata Interface.
What I'm interested in is to retrieve the list of foreign keys of a given table, but I don't want the solution to be bound to any specific DBMS.
What I found so far is the information_schema which is ANSI/ISO SQL:2003 standrad and stores these metadata but I'm not sure all RDBMSs comply with it and generally an SQL free solution (like JAVA DatabaseMetadata) would be preferable.
Thanks for any input,

I'm not sure if they are equal but for mssql you have also a information_schema, and i don't know if other DBMS also have the same schema
http://msdn.microsoft.com/en-us/library/aa933204%28SQL.80%29.aspx
Also you got these to provide information about your database structure
http://dev.mysql.com/doc/refman/5.0/en/explain.html
http://dev.mysql.com/doc/refman/5.0/en/show-index.html
But this doesn't work for all other DBMS again (JDBS uses desc instead of DESCRIBE)
So i guess there is not a single/consistent way to retrieve database structures for multiple DBMS, maybe you can extract the structure not from the database but from your models in your application?

This does seem to be rather a serious thing to be lacking from PHP PDO... and getColumnMeta is still "experimental".
Just a thought: it's hardly elegant, but it may be something to think of in extremities, where you really really want or need as much of this dbase or column meta data as poss: use PHP exec() to run (for MySQL):
mysqldump -d -h localhost -u username -ppwd databasename > dumpfile.sql
and then examine dumpfile.sql. Obviously you'd have to find similar commands for other DBMS's...

Related

Best ways to get table names from the raw MySql query

Lets say I have a general DB class with a query method that is used all over my source code and I want to find out table names that are used in my mysql queries.
The limitation is that I'm using MySql 5.5.36.
Also lets assume that we are talking about millions of tables that I'm using and that using the mysql information schema is not going to happen.
What I would like to know is there an easy way to get table names used?
Explain is obviously good for SELECT statments but since its MySql 5.5.36 I can't use it on replace,update,insert etc.
PDOStatement::getColumnMeta might help us with getting a table name, but it won't work with the queries that return result set.
Some kind of regexp for this might might be possible but I very much doubt that is a good solution for this, my queries are big have multiple JOINS etc. the regexp would be very complicated and probably fail fair percentage of time.
Any other ideas?

Dump PgSQL db with PDO

I have no CLI access on a server, but I want to run automatic deploy releases and backup/restore data contained by multiple pgsql databases. Is there a way to do this with PDO effortless?
Effortless(ly)
No.
You'd basically have to re-implement pg_dump. This would not be fun.
You can COPY out the tables using pg_copy_from. Unsure if there's a PDO equivalent. This will let you dump the data relatively easily, combined with a query against information_schema to get a table list.
Dumping the table definitions, users, constraints, indexes, etc, however ... good luck.

Syntax differences between mysql, sqlite and pgsql

I'm creating a tiny activerecord library using PDO and I'm planning to support MySQL, Sqlite and PgSQL.
My question is how I can be sure that the query string works with all adapters? There will mostly be CRUD statements with some joins etc. Is there a standard I can follow that works for all of these?
Thanks
/ Tobias
EDIT: Thanks for all your answers but my question was more about the SQL 'syntax' differences between them.
If you want to write your own DB layer, I'd suggest you:
Use placeholders, if you aren't already. They add security too.
Use bindParam/bindValue with value type (e.g. BOOLEANS don't exist in SQLite but work if bound with PARAM_BOOL)...
Use stored procedures from MySQL, create matching names in PostgreSQL, and define them in SQLite with sqliteCreateAggregate/sqliteCreateFunction.
Do all parameter checking in PHP, because SQLite won't do any (e.g. validate date variables)...
Use InnoDB for MySQL to get transactions.
Note: By supporting these vastly different RDBMs, you're demoting the database to just a data store. Keep in mind that SQLite is very limited. It does not have native data types save from number/string. E.g. it's missing date handling and intervals, and so on. All three databases support transactions, which are essential for data integrity when the integrity is maintained outside the DB.
Edit: Removed mention of MySQL triggers, which are availabe for 5.0.
Here you have a simple introduction to zend_db_adapter - i think you want something similar (I posted this just as a example to see how others resolve the problem you have)
My choice for this kind of issues would be ADOdb. While I never actually used it with PostgreSQL, it just saved my sanity in a project that happened to be born with MySQL and then migrated to SQL Server, to SQLite and back to SQL Server.

Running a list of MySQL queries without using exec()

I've got a site that requires manual creation of the database tables on install. At the moment they are saved (along with any initial data) in a collection of .sql files.
I've tried to auto-create using exec() with CLI MySQL and while it works on a few platforms it's fairly flakey and I don't really like doing it this way, plus it is hard to debug errors and is far from bulletproof (especially if the MySQL executable isn't in the system path).
Is there a better way of doing this? The MySQL query() command only allows one sql statement per query (which is the sticking point).
MySQLi I've heard may solve some of these issues but I am fairly invested in the original MySQL library but would be willing to switch provided it's stable, compatible and is commonly supported on a standard server build and is an improvement in general.
Failing this I'd probably be willing to do some sort of creation from a PHP array/data structure - which is arguably cleaner as it would be able to update tables to match the schema in situ. I am assuming this may be a problem that has already been solved, so any links to any example implementation with pro's/con's would be useful!
Thanks in advance for any insight.
Apparently you can pass 65536 as client flag when connecting to the datebase to allow multi queries, e.g. making use of ; in one SQL string.
You could also just read in the contents of the SQL files, explode by ; if necessary and run the queries inside a transaction to make sure all queries execute properly.
Another option would be to have a look at Phing and dbdeploy to manage databases.
If you're using this to migrate data between systems, consider using the LOAD DATA INFILE syntax (http://dev.mysql.com/doc/refman/5.1/en/load-data.html) after having used SELECT ... INTO OUTFILE (http://dev.mysql.com/doc/refman/5.1/en/select.html)
You can run the schema creation/update commands via the standard mysql_* PHP functions. And if the query() command as you call it will allow only one statement, just call it many times.
I really don't get why do you require everything to be in the same call.
You should check for errors after each statement and take corrective actions if it fails (unless you are using InnoDB, in which case you can wrap all statements in a transaction and rollback if it fails.)

What databases used with PHP share the same (or most) of the SQL syntax?

I've read that although SQL is meant to be standardised, it is implemented different etc with different databases. I have only ever used MySQL for databases.
What I would like to know is what other databases share the same syntax? I am using PDO now, and I would like to set a flag to allow the user to specify which database they would like to use.
I would be interested in knowing which are the 'safe' databases that will handle most (if not all) my general MySQL queries. Mainly SELECT, INSERT, UPDATE, DROP, DELETE.
Thanks
There are several revisions of a such called ANSI SQL.
All major database engines (that is Oracle, MS SQL, PostgreSQL and MySQL) should (should) in theory support SQL-92.
This includes everything you've mentioned: SELECT, INSERT, UPDATE, DROP, DELETE, as long as you don't use complex clauses with them.
In practice:
Not all databases support the full set of SQL-92.
Writing cross-platform SQL even in SQL-92 requires lots of testing.
Platform independency in SQL ends when you insert your 1001st row and need to optimize you queries.
If you browse a little over StackOverflow questions tagged SQL, you will see that most of them say "help me to optimize this query", and most answers say "use this platform dependent hack"
You will find that some database store datatypes differently, for example, mysql stores Booleans as 1 and 0 and postgres stores them as 't' and 'f'.
As long as your database classes are aware of the need to convert data, you should be fine, probably 96.3482% of everyday CRUD will work pretty well across the board.
Even if you create database classes that directly call PDO, you can later on add some logic for data translation or query modification.
You could use the database abstraction layer ADOdb. (its got what plants crave)
I'd suggest making sure that your customers actually give a crap about which database they need to run before you spend a lot of time developing functionality you may not need.
A standardized SQL92 is pretty much the same in all RDBMS. The differences are in parts, that the standard doesn't define, like for example LIMIT or datetime handling functions and of course procedural languages.
As for DBs popular with PHP: it not that hard make SQL portable between MySQL, SQLite and PostgreSQL. It won't be that easy with Oracle, Sybase and DB/2.

Categories