소스 검색

ChadoSchema: Added column type checking.

Lacey Sanderson 6 년 전
부모
커밋
b3394cd78b
3개의 변경된 파일117개의 추가작업 그리고 3개의 파일을 삭제
  1. 7 1
      tests/tripal_chado/api/ChadoComplianceTest.php
  2. 10 1
      tests/tripal_chado/api/ChadoSchemaTest.php
  3. 100 1
      tripal_chado/api/ChadoSchema.inc

+ 7 - 1
tests/tripal_chado/api/ChadoComplianceTest.php

@@ -74,7 +74,13 @@ class ChadoComplianceTest extends TripalTestCase {
           array('!column' => $column_name, '!table' => $table_name, '!version' => $version))
       );
 
-      // @todo Check #3: The field is the type we expect.
+      // Check #3: The field is the type we expect.
+      $this->assertTrue(
+        $chado_schema->checkColumnType($table_name, $column_name, $column_details['type']),
+        t('The column "!table.!column" must be of type "!type" for chado v!version.',
+          array('!column' => $column_name, '!table' => $table_name,
+            '!version' => $version, '!type' => $column_details['type']))
+      );
     }
 
     // For each constraint on this table...

+ 10 - 1
tests/tripal_chado/api/ChadoSchemaTest.php

@@ -232,7 +232,16 @@ class ChadoSchemaTest extends TripalTestCase {
    * @group chado-schema
    */
   public function testGetCvtermMapping($version, $table_name) {
-    // @todo This should be tested...
+
+    // Ideally we would create a new chado table + mapping and then test this pulls it out
+    // since admin can re-map terms. However, that's more then I meant to bite off right
+    // now...
+
+    // @todo Test that known terms match the tables we expect.
+
+    // @todo Test that a non-existent term throws an error.
+
+    // @todo Test that an fake unmapped term returns no mapping.
   }
 
   /**

+ 100 - 1
tripal_chado/api/ChadoSchema.inc

@@ -122,7 +122,7 @@ class ChadoSchema {
         $tables[$table] = $table;
       }
     }
-    if ($this->version == '1.11' or $v == '1.11 or older') {
+    if ($this->version == '1.11' or $this->version == '1.11 or older') {
       $tables_v1_11 = tripal_chado_chado_get_v1_11_tables();
       foreach ($tables_v1_11 as $table) {
         $tables[$table] = $table;
@@ -355,6 +355,105 @@ class ChadoSchema {
     return chado_column_exists($table, $column);
   }
 
+  /**
+   * Check that any given column in a Chado table exists.
+   *
+   * This function is necessary because Drupal's db_field_exists() will not
+   * look in any other schema but the one were Drupal is installed
+   *
+   * @param $table
+   *   The name of the chado table.
+   * @param $column
+   *   The name of the column in the chado table.
+   * @param $type
+   *   (OPTIONAL) The PostgreSQL type to check for. If not supplied it will be
+   *   looked up via the schema (PREFERRED).
+   *
+   * @return
+   *   TRUE if the column type matches what we expect and
+   *   FALSE if it does not.
+   *
+   * @ingroup tripal_chado_schema_api
+   */
+  public function checkColumnType($table, $column, $expected_type = NULL) {
+
+    // Ensure this column exists before moving forward.
+    if (!$this->checkColumnExists($table, $column)) {
+      tripal_report_error(
+        'ChadoSchema',
+        TRIPAL_WARNING,
+        'Unable to check the type of !table!column since it doesn\'t appear to exist in your site database.',
+        array('!column' => $column, '!table' => $table)
+      );
+      return FALSE;
+    }
+
+    // Look up the type using the Schema array.
+    if ($expected_type === NULL) {
+      $schema = $this->getTableSchema($table, $column);
+
+      if (is_array($schema) AND isset($schema['fields'][$column])) {
+        $expected_type = $schema['fields'][$column]['type'];
+      }
+      else {
+        tripal_report_error(
+          'ChadoSchema',
+          TRIPAL_WARNING,
+          'Unable to check the type of !table!column due to being unable to find the schema definition.',
+          array('!column' => $column, '!table' => $table)
+        );
+        return FALSE;
+      }
+    }
+
+    // There is some flexibility in the expected type...
+    // Fix that here.
+    switch ($expected_type) {
+      case 'int':
+        $expected_type = 'integer';
+        break;
+      case 'serial':
+        $expected_type = 'integer';
+        break;
+      case 'varchar':
+        $expected_type = 'character varying';
+        break;
+      case 'datetime':
+        $expected_type = 'timestamp without time zone';
+        break;
+      case 'char':
+        $expected_type = 'character';
+        break;
+    }
+
+    // Grab the type from the current database.
+    $query = 'SELECT data_type
+              FROM information_schema.columns
+              WHERE
+                table_name = :table AND
+                column_name = :column AND
+                table_schema = :schema
+              ORDER  BY ordinal_position
+              LIMIT 1';
+    $type = db_query($query,
+      array(':table' => $table, ':column' => $column, ':schema' => $this->schema_name))->fetchField();
+
+    // Finally we do the check!
+    if ($type === $expected_type) {
+      return TRUE;
+    }
+    elseif (($expected_type == 'float') AND (($type == 'double precision') OR ($type == 'real'))) {
+      return TRUE;
+    }
+    elseif ($type == 'smallint' AND $expected_type == 'integer') {
+      return TRUE;
+    }
+    else {
+      print "$table.$column... Expected: $expected_type, Actual: $type.\n";
+      return FALSE;
+    }
+  }
+
   /**
    * Check that any given column in a Chado table exists.
    *