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}"; }
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; }
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; }
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"); }
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(); }
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"]); }
/** * 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); }
public function clearObjectCache() { parent::clearObjectCache(); $this->autoNumberCount = 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); }
/** * 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 ""; }