protected static function canAggregateInMySql(Repository $repository, $columnName, &$relationshipsToAutoHydrate)
 {
     $schema = $repository->getSchema();
     $columns = $schema->getColumns();
     if (isset($columns[$columnName])) {
         return true;
     }
     if (strpos($columnName, ".") !== false) {
         // If the column name contains a dot, the part before the dot is the name of a relationship to another model
         list($relationship, $columnName) = explode(".", $columnName, 2);
         $relationships = SolutionSchema::getAllRelationshipsForModel($repository->getModelClass());
         // Check for the name being that of a relationship
         if (isset($relationships[$relationship]) && $relationships[$relationship] instanceof OneToMany) {
             $targetModelName = $relationships[$relationship]->getTargetModelName();
             $targetSchema = SolutionSchema::getModelSchema($targetModelName);
             $targetColumns = $targetSchema->getColumns();
             // Check for the column name in the schema of the related model
             if (isset($targetColumns[$columnName])) {
                 $relationshipsToAutoHydrate[] = $relationship;
                 return true;
             }
         }
     }
     return false;
 }
 protected static function doFilterWithRepository(Repository $repository, Filter $originalFilter, &$params, &$relationshipsToAutoHydrate)
 {
     $relationshipsToAutoHydrate[] = $originalFilter->collectionProperty;
     // Get the relationship
     $relationships = SolutionSchema::getAllRelationshipsForModel($repository->getModelClass());
     /**
      * @var OneToMany $relationship
      */
     $relationship = $relationships[$originalFilter->collectionProperty];
     $columnName = $relationship->getNavigationPropertyName() . "`.`" . $originalFilter->columnName;
     $paramName = uniqid() . str_replace("`.`", "", $columnName);
     $params[$paramName] = $originalFilter->equalTo;
     $originalFilter->filteredByRepository = true;
     return "`{$columnName}` = :{$paramName}";
 }
예제 #3
0
 protected function initialise()
 {
     parent::initialise();
     Repository::SetDefaultRepositoryClassName(MySql::class);
     include_once "settings/site.config.php";
     SolutionSchema::registerSchema('Default', DefaultSolutionSchema::class);
 }
 /**
  * Returns a MySqlComparisonSchema reflecting the schema of a database table.
  *
  * @param $tableName
  * @return MySqlComparisonSchema
  */
 public static function fromTable($tableName)
 {
     $repos = Repository::getDefaultRepositoryClassName();
     // Get the create table syntax for the table - we'll analyse this and build our schema accordingly.
     $row = $repos::returnFirstRow("SHOW CREATE TABLE {$tableName}");
     $sql = $row["Create Table"];
     $lines = explode("\n", $sql);
     // First and last lines aren't needed
     $lines = array_slice($lines, 1, -1);
     $comparisonSchema = new MySqlComparisonSchema();
     foreach ($lines as $line) {
         $line = trim($line);
         // If the line starts with a back tick we have a column
         if ($line[0] == "`") {
             $default = null;
             preg_match("/`([^`]+)`/", rtrim($line, ','), $matches);
             $name = $matches[1];
             $comparisonSchema->columns[$name] = rtrim(trim($line), ",");
         } else {
             $words = explode(" ", $line);
             $indexKeywords = ["PRIMARY", "KEY", "UNIQUE"];
             if (in_array($words[0], $indexKeywords)) {
                 $comparisonSchema->indexes[] = preg_replace('/\\s+/', ' ', rtrim(trim($line), ","));
             }
         }
     }
     return $comparisonSchema;
 }
예제 #5
0
 protected static final function getTransformedComparisonValueForRepository($columnName, $rawComparisonValue, Repository $repository)
 {
     $exampleObject = SolutionSchema::getModel($repository->getModelClass());
     $columnSchema = $exampleObject->getColumnSchemaForColumnReference($columnName);
     if ($columnSchema != null) {
         // Transform the value first into model data. This function should sanitise the value as
         // the model data transforms expect inputs passed by unwary developers.
         $closure = $columnSchema->getTransformIntoModelData();
         if ($closure !== null) {
             $rawComparisonValue = $closure($rawComparisonValue);
         }
         $closure = $columnSchema->getTransformIntoRepository();
         if ($closure !== null) {
             $rawComparisonValue = $closure($rawComparisonValue);
         }
     }
     return $rawComparisonValue;
 }
예제 #6
0
 public function testDefaultRepositoryCanBeChanged()
 {
     Repository::setDefaultRepositoryClassName("\\Rhubarb\\Stem\\Repositories\\MySql\\MySql");
     $repository = Repository::getNewDefaultRepository(new Example());
     $this->assertInstanceOf("\\Rhubarb\\Stem\\Repositories\\MySql\\MySql", $repository);
     // Also check that non extant repositories throw an exception.
     $this->setExpectedException("\\Rhubarb\\Stem\\Exceptions\\ModelException");
     Repository::setDefaultRepositoryClassName("\\Rhubarb\\Stem\\Repositories\\Fictional\\Fictional");
     // Reset to the normal so we don't upset other unit tests.
     Repository::setDefaultRepositoryClassName("\\Rhubarb\\Stem\\Repositories\\Offline\\Offline");
 }
예제 #7
0
 public static function setUpBeforeClass()
 {
     parent::setUpBeforeClass();
     Repository::setDefaultRepositoryClassName(MySql::class);
     self::SetDefaultConnectionSettings();
     Log::DisableLogging();
     $unitTestingSolutionSchema = new UnitTestingSolutionSchema();
     $unitTestingSolutionSchema->checkModelSchemas();
     // Make sure the test model objects have the any other repository disconnected.
     Model::deleteRepositories();
 }
 protected function setUp()
 {
     parent::setUp();
     Application::current()->registerModule(new CommunicationsModule());
     Application::current()->initialiseModules();
     Model::clearAllRepositories();
     CommunicationProcessor::setProviderClassName(EmailProvider::class, UnitTestingEmailProvider::class);
     Repository::setDefaultRepositoryClassName(Offline::class);
     Communication::clearObjectCache();
     CommunicationItem::clearObjectCache();
 }
예제 #9
0
 public function testSchemaIsModified()
 {
     // Note this test relies on the previous test to leave tblExample behind.
     $schema = new MySqlModelSchema("tblExample");
     $schema->addColumn(new AutoIncrement("ID"));
     $schema->addColumn(new String("Name", 40, "StrangeDefault"));
     $schema->addColumn(new MySqlEnum("Type", "A", ["A", "B", "C"]));
     $schema->addColumn(new MySqlEnum("Type", "B", ["A", "B", "C", "D"]));
     $schema->addColumn(new String("Town", 60, null));
     $schema->addIndex(new Index("ID", Index::PRIMARY));
     $schema->checkSchema(Repository::getNewDefaultRepository(new Example()));
     $newSchema = MySqlComparisonSchema::fromTable("tblExample");
     $columns = $newSchema->columns;
     $this->assertCount(4, $columns);
     $this->assertEquals("`Town` varchar(60) DEFAULT NULL", $columns["Town"]);
     $this->assertEquals("`Type` enum('A','B','C','D') NOT NULL DEFAULT 'B'", $columns["Type"]);
 }
예제 #10
0
 /**
  * Creates the table in the back end data store.
  */
 private function createTable()
 {
     $sql = "CREATE TABLE " . $this->schemaName . " (";
     $definitions = [];
     foreach ($this->columns as $columnName => $column) {
         // The column might be using a more generic type for it's storage.
         $storageColumns = $column->createStorageColumns();
         foreach ($storageColumns as $storageColumn) {
             // And if so that column will be a generic column type - we need to upgrade it.
             $storageColumn = $storageColumn->getRepositorySpecificColumn("MySql");
             $definitions[] = $storageColumn->getDefinition();
         }
     }
     foreach ($this->indexes as $indexName => $index) {
         $definitions[] = $index->getDefinition();
     }
     $sql .= implode(",", $definitions);
     $sql .= "\n\t\t\t)";
     $repos = Repository::getDefaultRepositoryClassName();
     $repos::executeStatement($sql);
 }
예제 #11
0
 public function clearObjectCache()
 {
     parent::clearObjectCache();
     $this->autoNumberCount = 0;
 }
예제 #12
0
 /**
  * Creates the repository appropriate for this object type.
  *
  * To be overridden when necessary.
  *
  * @throws \Rhubarb\Stem\Exceptions\ModelException
  * @return \Rhubarb\Stem\Repositories\Repository
  */
 protected function createRepository()
 {
     return Repository::getNewDefaultRepository($this);
 }
예제 #13
0
 /**
  * Returns A string containing information needed for a repository to use a filter directly.
  *
  * @param \Rhubarb\Stem\Repositories\Repository $repository
  * @param array $params An array of output parameters that might be need by the repository, named parameters for PDO for example.
  * @param array $propertiesToAutoHydrate An array of properties that need auto hydrated for performance.
  * @return string
  */
 public final function filterWithRepository(Repository $repository, &$params, &$propertiesToAutoHydrate)
 {
     $namespace = $repository->getFiltersNamespace();
     if (!$namespace) {
         return "";
     }
     $parts = explode('\\', $namespace);
     // Get the provider specific implementation of the filter.
     $className = rtrim($namespace, '\\') . '\\' . $parts[count($parts) - 2] . basename(str_replace("\\", "/", get_class($this)));
     if (class_exists($className)) {
         return call_user_func_array($className . "::doFilterWithRepository", [$repository, $this, &$params, &$propertiesToAutoHydrate]);
     }
     return "";
 }