예제 #1
0
 public function test_invalid_max_age()
 {
     \Sledgehammer\cache(__FILE__ . __FUNCTION__, array('expires' => '+1 min'), array($this, 'incrementCounter'));
     // create a cache entry. (no entry == no max_age validation)
     try {
         \Sledgehammer\cache(__FILE__ . __FUNCTION__, array('max_age' => '+1 min'), array($this, 'incrementCounter'));
         $this->fail('An max_age in the future should generate a notice');
     } catch (\PHPUnit_Framework_Error_Notice $e) {
         $this->assertSame('maxAge is 60 seconds in the future', $e->getMessage());
     }
 }
 /**
  * Create model configs based on the tables in the database schema.
  *
  * @param string $dbLink
  */
 public function inspectDatabase($dbLink = 'default', $tablePrefix = '')
 {
     // Pass 1: Retrieve and parse schema information
     $db = Connection::instance($dbLink);
     if (self::$cacheTimeout === false) {
         $schema = $this->getSchema($db, $tablePrefix);
     } else {
         $cacheIdentifier = $dbLink . ' ' . $tablePrefix . ' ';
         if (count($db->logger->entries) > 0) {
             $cacheIdentifier .= $db->logger->entries[0][0];
             // Add the connect statement to the identifier.
         }
         $backend = $this;
         $schema = \Sledgehammer\cache('DatabaseRepositoryBackend[' . md5($cacheIdentifier) . ']', self::$cacheTimeout, function () use($backend, $db, $tablePrefix) {
             return $backend->getSchema($db, $tablePrefix);
         });
     }
     $models = [];
     $junctions = [];
     foreach ($schema as $tableName => $table) {
         $name = Inflector::modelize($tableName, ['prefix' => $tablePrefix, 'singularizeLast' => true]);
         $plural = Inflector::modelize($tableName, ['prefix' => $tablePrefix, 'singularizeLast' => false]);
         $config = new ModelConfig($name, ['plural' => $plural, 'backendConfig' => $table]);
         $config->backendConfig['dbLink'] = $dbLink;
         $config->backendConfig['collection'] = ['columns' => []];
         // database collection config.
         $config->id = $table['primaryKeys'];
         foreach ($table['columns'] as $column => $info) {
             $default = @$info['default'];
             if (empty($info['foreignKeys'])) {
                 $property = Inflector::variablize($column);
                 $config->properties[$column] = $property;
                 $config->defaults[$property] = $default;
                 if (substr($info['type'], -10) === 'tinyint(1)' && $info['null'] === false) {
                     $config->readFilters[$column] = __CLASS__ . '::valueToBool';
                     $config->writeFilters[$column] = __CLASS__ . '::boolToValue';
                     $config->defaults[$property] = self::valueToBool($config->defaults[$column]);
                 }
             } else {
                 if (count($info['foreignKeys']) > 1) {
                     notice('Multiple foreign-keys per column not supported');
                 }
                 $foreignKey = $info['foreignKeys'][0];
                 $property = $this->stripIdSuffix($column);
                 if ($column !== $property && array_key_exists($property, $table['columns'])) {
                     $property = $column;
                     // restore prefix, to prevent a naming collision.
                 }
                 if (array_key_exists($property, $table['columns']) && $property != $column) {
                     notice('Unable to use belongsTo["' . $property . '"], an column with the same name exists', ['belongsTo' => $info, 'Exising column' => $table['columns'][$property]]);
                 }
                 $foreignModel = Inflector::modelize($foreignKey['table'], ['prefix' => $tablePrefix, 'singularizeLast' => true]);
                 $config->belongsTo[$property] = ['reference' => $column, 'model' => $foreignModel, 'id' => $foreignKey['column'], 'default' => $default];
             }
         }
         // Detect junction table
         if (count($config->id) === 2) {
             $primaryKeyAreForeignKeys = true;
             foreach ($config->belongsTo as $belongsTo) {
                 if (in_array($belongsTo['reference'], $config->id) === false) {
                     $primaryKeyAreForeignKeys = false;
                     break;
                 }
             }
             if ($primaryKeyAreForeignKeys) {
                 $junctions[$tableName] = $config;
                 $this->junctions[$config->name] = $config;
                 continue;
             }
         }
         $models[$tableName] = $config;
         if (isset($this->configs[$config->name])) {
             notice('Model "' . $config->name . '" (for the "' . $tableName . '" table) is defined in both "' . $this->configs[$config->name]->backendConfig['dbLink'] . '" and "' . $dbLink . '" ');
             $suffix = 2;
             while (isset($this->configs[$config->name . '_' . $suffix])) {
                 ++$suffix;
             }
             $this->configs[$config->name . '_' . $suffix] = $config;
         } else {
             $this->configs[$config->name] = $config;
         }
     }
     // Pass 2: hasMany
     foreach ($this->configs as $config) {
         $table = $schema[$config->backendConfig['table']];
         foreach ($table['referencedBy'] as $i => $reference) {
             $property = $reference['table'];
             if ($tablePrefix != '' && substr($property, 0, strlen($tablePrefix)) == $tablePrefix) {
                 $property = substr($property, strlen($tablePrefix));
                 // Strip prefix
             }
             foreach ($table['referencedBy'] as $j => $otherRef) {
                 if ($i != $j && $otherRef['table'] === $reference['table']) {
                     // The model has relations to the same table.
                     $property = $this->stripIdSuffix($reference['column']) . '_' . $property;
                 }
             }
             $property = Inflector::variablize($property);
             if (in_array($property, $config->getPropertyNames())) {
                 notice('Unable to use ' . $config->name . '->hasMany[' . $property . '] a property with the same name exists');
                 break;
             }
             if (isset($models[$reference['table']])) {
                 // One-to-many relation
                 $belongsToModel = $models[$reference['table']];
                 foreach ($belongsToModel->belongsTo as $belongsToProperty => $belongsTo) {
                     if ($belongsTo['model'] == $config->name && $belongsTo['reference'] == $reference['column']) {
                         $config->hasMany[$property] = ['model' => $belongsToModel->name, 'reference' => $reference['column'], 'belongsTo' => $belongsToProperty];
                         $config->defaults[$property] = [];
                         break;
                     }
                 }
             } elseif (empty($junctions[$reference['table']])) {
                 notice('Missing a model or relation for "' . $reference['table'] . '" in the database schema');
             }
         }
     }
     // Pass 3: hasMany junctions
     foreach ($this->configs as $config) {
         $table = $schema[$config->backendConfig['table']];
         foreach ($table['referencedBy'] as $reference) {
             if (isset($junctions[$reference['table']])) {
                 // Many-to-many realtion
                 $junction = $junctions[$reference['table']];
                 $hasMany = ['through' => $junction->name, 'fields' => $junction->properties];
                 foreach ($junction->belongsTo as $belongsToProperty => $belongsTo) {
                     if ($belongsTo['model'] === $config->name) {
                         $hasMany['reference'] = $belongsTo['reference'];
                     } else {
                         $property = Inflector::pluralize($belongsToProperty);
                         $hasMany['model'] = $belongsTo['model'];
                         $hasMany['id'] = $belongsTo['reference'];
                     }
                 }
                 if (in_array($property, $config->getPropertyNames())) {
                     $property = Inflector::variablize($reference['table']);
                 }
                 if (in_array($property, $config->getPropertyNames())) {
                     notice('Unable to use ' . $property . '->hasMany[' . $property . '] a property with the same name exists');
                     break;
                 }
                 $config->hasMany[$property] = $hasMany;
                 $config->defaults[$property] = [];
             }
         }
     }
 }
예제 #3
0
 /**
  * @return Iterator
  */
 private function cachedIterator()
 {
     if ($this->iterator !== null) {
         return $this->iterator;
     }
     $object = $this->object;
     $value = \Sledgehammer\cache($this->cachePath . ':Iterator', $this->expires, function () use($object) {
         return iterator_to_array($object);
     });
     $this->iterator = new ArrayIterator($array);
     return $this->iterator;
 }