10

I'm trying to check for the existence of a table before dropping it. I've read through the API documentation for Doctrine_Table and I can't seem to find anything like this. Is there something I'm missing?

I've got code that looks like:

$table = new Doctrine_Table('model_name', $conn);

$export = new Doctrine_Export();

$export->dropTable($table->getTableName());

And the error I get when a table doesn't exist is:

Fatal error: Uncaught exception 'Doctrine_Connection_Mysql_Exception' with message 'SQLSTATE[42S02]: Base table or view not found: 1051 Unknown table

Thanks in advance,

Casey

Casey
  • 1,802
  • 3
  • 22
  • 35

5 Answers5

32

Doctrine2 method is:

$schemaManager = $this->getDoctrine()->getConnection()->getSchemaManager();
if ($schemaManager->tablesExist(array('users')) == true) {
      // table exists! ...
}
pleerock
  • 18,322
  • 16
  • 103
  • 128
  • 1
    This way is very intuitive – manix May 19 '14 at 02:38
  • This is the simplest, and least taxing way of checking this. In my case I had to get the reference to the SchemaManager through the Doctrine EntityManager like so: $em->getConnection()->getSchemaManager(); – spetz83 Jun 25 '14 at 14:15
6

If you just want to return true/false if the table exists, this is what I did:

public function checkTable($table)
{
    $conn = Doctrine_Manager::connection();
    try { $conn->execute("DESC $table"); }
    catch (Exception $e) { return false; }
    return true;
}
targnation
  • 917
  • 11
  • 11
2

Here's what I wound up using... any suggestions for improvement are welcome:

public static function isInstalled()
{
    $installed = true;

    $q = Doctrine_Query::create($conn);
    $q->select('t.id');
    $q->from('Table t'); //the table to check

    try {
        $q->execute();
    } catch (Doctrine_Connection_Exception $e) {
        // we only want to silence 'no such table' errors
        if ($e->getPortableCode() !== Doctrine_Core::ERR_NOSUCHTABLE) {
            throw new Doctrine_Export_Exception($e->getMessage());
        }

        $installed = false;
    }

    return $installed;
}
Casey
  • 1,802
  • 3
  • 22
  • 35
  • 1
    (Sorry for the necromancy but this is relevant to what I was looking for.) Firstly, you could simply have caught the Doctrine_Connection_Mysql_Exception (or its parent, for agnosticism) thrown by dropTable() and ignore the error if it had appeared. Secondly, not free()ing the Doctrine_Query you created will cause a memory leak. – lotsoffreetime Jul 01 '11 at 14:11
1

Try this for table exist check:

 public function up(Schema $schema): void
{
    $schema->hasTable('table_name');
}

For columns check:

$schema->getTable('supply')->hasColumn('contracts')

Full example with skip:

$this->skipIf($schema->getTable('supply')->hasColumn('contracts'), 'Table order_statuses already exist');
Georgy
  • 11
  • 1
-1

I haven't tested portability, but in native SQL you can do:

DROP TABLE IF EXISTS ...

You can run native SQL queries with Doctrine as well.

takeshin
  • 49,108
  • 32
  • 120
  • 164