コード例 #1
0
 /**
  * @todo Move this to SS_Database or DB
  */
 public static function hasTable($class)
 {
     // Cache the list of all table names to reduce on DB traffic
     if (empty(self::$_cache_all_tables) && DB::is_active()) {
         self::$_cache_all_tables = DB::get_schema()->tableList();
     }
     return !empty(self::$_cache_all_tables[strtolower($class)]);
 }
コード例 #2
0
 /**
  * Updates the database schema, creating tables & fields as necessary.
  *
  * @param boolean $quiet Don't show messages
  * @param boolean $populate Populate the database, as well as setting up its schema
  * @param bool $testMode
  */
 public function doBuild($quiet = false, $populate = true, $testMode = false)
 {
     if ($quiet) {
         DB::quiet();
     } else {
         $conn = DB::get_conn();
         // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database")
         $dbType = substr(get_class($conn), 0, -8);
         $dbVersion = $conn->getVersion();
         $databaseName = method_exists($conn, 'currentDatabase') ? $conn->getSelectedDatabase() : "";
         if (Director::is_cli()) {
             echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion);
         } else {
             echo sprintf("<h2>Building database %s using %s %s</h2>", $databaseName, $dbType, $dbVersion);
         }
     }
     // Set up the initial database
     if (!DB::is_active()) {
         if (!$quiet) {
             echo '<p><b>Creating database</b></p>';
         }
         // Load parameters from existing configuration
         global $databaseConfig;
         if (empty($databaseConfig) && empty($_REQUEST['db'])) {
             user_error("No database configuration available", E_USER_ERROR);
         }
         $parameters = !empty($databaseConfig) ? $databaseConfig : $_REQUEST['db'];
         // Check database name is given
         if (empty($parameters['database'])) {
             user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR);
         }
         $database = $parameters['database'];
         // Establish connection and create database in two steps
         unset($parameters['database']);
         DB::connect($parameters);
         DB::create_database($database);
     }
     // Build the database.  Most of the hard work is handled by DataObject
     $dataClasses = ClassInfo::subclassesFor('SilverStripe\\ORM\\DataObject');
     array_shift($dataClasses);
     if (!$quiet) {
         if (Director::is_cli()) {
             echo "\nCREATING DATABASE TABLES\n\n";
         } else {
             echo "\n<p><b>Creating database tables</b></p>\n\n";
         }
     }
     // Initiate schema update
     $dbSchema = DB::get_schema();
     $dbSchema->schemaUpdate(function () use($dataClasses, $testMode, $quiet) {
         foreach ($dataClasses as $dataClass) {
             // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
             if (!class_exists($dataClass)) {
                 continue;
             }
             // Check if this class should be excluded as per testing conventions
             $SNG = singleton($dataClass);
             if (!$testMode && $SNG instanceof TestOnly) {
                 continue;
             }
             // Log data
             if (!$quiet) {
                 if (Director::is_cli()) {
                     echo " * {$dataClass}\n";
                 } else {
                     echo "<li>{$dataClass}</li>\n";
                 }
             }
             // Instruct the class to apply its schema to the database
             $SNG->requireTable();
         }
     });
     ClassInfo::reset_db_cache();
     if ($populate) {
         if (!$quiet) {
             if (Director::is_cli()) {
                 echo "\nCREATING DATABASE RECORDS\n\n";
             } else {
                 echo "\n<p><b>Creating database records</b></p>\n\n";
             }
         }
         foreach ($dataClasses as $dataClass) {
             // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness
             // Test_ indicates that it's the data class is part of testing system
             if (strpos($dataClass, 'Test_') === false && class_exists($dataClass)) {
                 if (!$quiet) {
                     if (Director::is_cli()) {
                         echo " * {$dataClass}\n";
                     } else {
                         echo "<li>{$dataClass}</li>\n";
                     }
                 }
                 singleton($dataClass)->requireDefaultRecords();
             }
         }
         // Remap obsolete class names
         $schema = DataObject::getSchema();
         foreach ($this->config()->classname_value_remapping as $oldClassName => $newClassName) {
             $badRecordCount = $newClassName::get()->filter(["ClassName" => $oldClassName])->count();
             if ($badRecordCount > 0) {
                 if (Director::is_cli()) {
                     echo " * Correcting {$badRecordCount} obsolete classname values for {$newClassName}\n";
                 } else {
                     echo "<li>Correcting {$badRecordCount} obsolete classname values for {$newClassName}</li>\n";
                 }
                 $table = $schema->baseDataTable($newClassName);
                 DB::prepared_query("UPDATE \"{$table}\" SET \"ClassName\" = ? WHERE \"ClassName\" = ?", [$newClassName, $oldClassName]);
             }
         }
     }
     touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder()));
     if (isset($_REQUEST['from_installer'])) {
         echo "OK";
     }
     if (!$quiet) {
         echo Director::is_cli() ? "\n Database build completed!\n\n" : "<p>Database build completed!</p>";
     }
     ClassInfo::reset_db_cache();
 }
コード例 #3
0
 /**
  * @param string $sql The parameterised query
  * @param array $parameters The parameters to inject into the query
  *
  * @return string
  */
 public static function inline_parameters($sql, $parameters)
 {
     $segments = preg_split('/\\?/', $sql);
     $joined = '';
     $inString = false;
     $numSegments = count($segments);
     for ($i = 0; $i < $numSegments; $i++) {
         $input = $segments[$i];
         // Append next segment
         $joined .= $segments[$i];
         // Don't add placeholder after last segment
         if ($i === $numSegments - 1) {
             break;
         }
         // check string escape on previous fragment
         // Remove escaped backslashes, count them!
         $input = preg_replace('/\\\\\\\\/', '', $input);
         // Count quotes
         $totalQuotes = substr_count($input, "'");
         // Includes double quote escaped quotes
         $escapedQuotes = substr_count($input, "\\'");
         if (($totalQuotes - $escapedQuotes) % 2 !== 0) {
             $inString = !$inString;
         }
         // Append placeholder replacement
         if ($inString) {
             // Literal question mark
             $joined .= '?';
             continue;
         }
         // Encode and insert next parameter
         $next = array_shift($parameters);
         if (is_array($next) && isset($next['value'])) {
             $next = $next['value'];
         }
         if (is_bool($next)) {
             $value = $next ? '1' : '0';
         } elseif (is_int($next)) {
             $value = $next;
         } else {
             $value = DB::is_active() ? Convert::raw2sql($next, true) : $next;
         }
         $joined .= $value;
     }
     return $joined;
 }