/**
  * Short description of method referenceInstanceTypes
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Class class
  * @return boolean
  */
 public function referenceInstanceTypes(\core_kernel_classes_Class $class)
 {
     $returnValue = (bool) false;
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     $query = "SELECT DISTINCT object FROM statements \n        \t\t\tWHERE predicate = ? \n        \t\t\tAND object != ?\n         \t\t\tAND subject IN (SELECT subject FROM statements \n        \t\t\t\t\t\tWHERE predicate = ? \n        \t\t\t\t\t\tAND object = ?)";
     $result = $dbWrapper->query($query, array(RDF_TYPE, $class->getUri(), RDF_TYPE, $class->getUri()));
     $types = array();
     while ($row = $result->fetch()) {
         $types[] = $row['object'];
     }
     $tableName = '_' . Utils::getShortName($class);
     foreach ($types as $type) {
         $this->referenceClass(new \core_kernel_classes_Class($type), array("table" => $tableName));
     }
     return (bool) $returnValue;
 }
 public function propertyDescriptor(\core_kernel_classes_Property $property, $hardRangeClassOnly = false)
 {
     $returnValue = array('name' => Utils::getShortName($property), 'isMultiple' => $property->isMultiple(), 'isLgDependent' => $property->isLgDependent(), 'range' => array());
     $range = $property->getRange();
     $rangeClassName = Utils::getShortName($range);
     if ($hardRangeClassOnly) {
         if (ResourceReferencer::singleton()->isClassReferenced($range)) {
             $returnValue[] = $rangeClassName;
         }
     } else {
         $returnValue[] = $rangeClassName;
     }
     return (array) $returnValue;
 }
    /**
     * Short description of method getPropertiesValues
     *
     * @access public
     * @author Joel Bout, <*****@*****.**>
     * @param  Resource resource
     * @param  array properties
     * @return array
     */
    public function getPropertiesValues(\core_kernel_classes_Resource $resource, $properties)
    {
        $returnValue = array();
        $referencer = ResourceReferencer::singleton();
        $table = ResourceReferencer::singleton()->resourceLocation($resource);
        if (empty($table)) {
            return $returnValue;
        }
        $tableProps = $table . 'props';
        $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
        $propertiesMain = '';
        $propertiesProps = '';
        $propertyIndexes = array();
        $propertyIndex = 0;
        foreach ($properties as $propertyMixed) {
            $property = is_object($propertyMixed) ? $propertyMixed : new \core_kernel_classes_Property($propertyMixed);
            $propertyLocation = $referencer->propertyLocation($property);
            if (in_array($tableProps, $propertyLocation) || !$referencer->isPropertyReferenced($property)) {
                if (!empty($propertiesProps)) {
                    $propertiesProps .= ", ";
                }
                $propertiesProps .= "'" . $property->getUri() . "'";
            } else {
                try {
                    $propertyAlias = HardapiUtils::getShortName($property);
                    if (!empty($propertiesMain)) {
                        $propertiesMain .= ', ';
                    }
                    $propertiesMain .= '"' . $propertyAlias . '" as "propertyValue' . $propertyIndex . '"';
                    $propertyIndexes[$propertyIndex] = $property;
                    $propertyIndex++;
                } catch (\common_exception_UnknownNamespace $e) {
                    // unknown property
                }
            }
        }
        if (!empty($propertiesProps)) {
            // Define language if required
            $lang = '';
            $defaultLg = '';
            $options = array();
            //@TODO: option to be implemented
            if (isset($options['lg'])) {
                $lang = $options['lg'];
            } else {
                $lang = \common_session_SessionManager::getSession()->getDataLanguage();
                $defaultLg = ' OR "l_language" = \'' . DEFAULT_LANG . '\' ';
            }
            $query = 'SELECT "property_uri", "property_value", "property_foreign_uri"
				FROM "' . $table . '"
				INNER JOIN "' . $tableProps . '" on "' . $table . '"."id" = "' . $tableProps . '"."instance_id"
			   	WHERE "' . $table . '"."uri" = ?
					AND "' . $tableProps . '"."property_uri" IN (' . $propertiesProps . ')
					AND ( "l_language" = ? OR "l_language" = \'\' ' . $defaultLg . ')
				ORDER BY "property_uri"';
            try {
                $result = $dbWrapper->query($query, array($resource->getUri(), $lang));
            } catch (\PDOException $e) {
                throw new Exception("Unable to get property (multiple) values for {$resource->getUri()} in {$table} : " . $e->getMessage());
            }
            $currentPredicate = null;
            while ($row = $result->fetch()) {
                if ($currentPredicate != $row['property_uri']) {
                    $currentPredicate = $row['property_uri'];
                    $returnValue[$currentPredicate] = array();
                }
                $value = $row['property_value'] != null ? $row['property_value'] : $row['property_foreign_uri'];
                $returnValue[$currentPredicate][] = \common_Utils::isUri($value) ? new \core_kernel_classes_Resource($value) : new \core_kernel_classes_Literal($value);
            }
        }
        if (!empty($propertiesMain)) {
            try {
                $query = 'SELECT ' . $propertiesMain . ' FROM "' . $table . '" WHERE "uri" = ?';
                $result = $dbWrapper->query($query, array($resource->getUri()));
                while ($row = $result->fetch()) {
                    foreach ($propertyIndexes as $propertyIndex => $property) {
                        $returnValue[$property->getUri()] = array();
                        if ($row['propertyValue' . $propertyIndex] != null) {
                            $value = $row['propertyValue' . $propertyIndex];
                            $returnValue[$property->getUri()][] = \common_Utils::isUri($value) ? new \core_kernel_classes_Resource($value) : new \core_kernel_classes_Literal($value);
                        }
                    }
                }
            } catch (\PDOException $e) {
                if ($e->getCode() == $dbWrapper->getColumnNotFoundErrorCode()) {
                    // Column doesn't exists is not an error. Try to get a property which does not exist is allowed
                } else {
                    if ($e->getCode() !== '00000') {
                        throw new Exception("Unable to get property (single) values for {$resource->getUri()} in {$table} : " . $e->getMessage());
                    }
                }
            }
        }
        return (array) $returnValue;
    }
 /**
  * Will create an Index (in the RDBMS) for all the promperties passed as
  * a parameter. This may increase the performance of the system.
  * 
  * @static
  * @access public
  * @param array $indexProperties
  * @throws Exception
  * @return boolean If it succeeds, false otherwise.
  */
 public static function createIndex($indexProperties = array())
 {
     $referencer = ResourceReferencer::singleton();
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     foreach ($indexProperties as $indexProperty) {
         $property = new \core_kernel_classes_Property($indexProperty);
         $propertyAlias = Utils::getShortName($property);
         foreach ($referencer->propertyLocation($property) as $table) {
             if (!preg_match("/props\$/", $table) && preg_match("/^_[0-9]{2,}/", $table)) {
                 try {
                     $indexName = 'idx_' . $table . '_' . $propertyAlias;
                     if (strlen($indexName) > 64) {
                         $md5 = md5($indexName);
                         $indexName = substr($indexName, 0, 30) . $md5;
                     }
                     $dbWrapper->createIndex($indexName, $dbWrapper->quoteIdentifier($table), array($dbWrapper->quoteIdentifier($propertyAlias) => 255));
                 } catch (\Exception $e) {
                     if ($e->getCode() != $dbWrapper->getIndexAlreadyExistsErrorCode() && $e->getCode() != '00000') {
                         throw new Exception("Unable to create index 'idx_{$propertyAlias}' for property alias '{$propertyAlias}' on table '{$table}': {$e->getMessage()}");
                     } else {
                         \common_Logger::e('something go wrong when creating index idx_' . $propertyAlias . ' on table ' . $table . ' : ' . $e->getMessage());
                     }
                 }
             }
         }
     }
     return true;
 }
示例#5
0
 /**
  * (non-PHPdoc)
  * @see core_kernel_persistence_ClassInterface::createInstanceWithProperties()
  */
 public function createInstanceWithProperties(\core_kernel_classes_Class $type, $properties)
 {
     $returnValue = null;
     if (isset($properties[RDF_TYPE])) {
         throw new \core_kernel_persistence_Exception('Additional types in createInstanceWithProperties not permited');
     }
     $uri = \common_Utils::getNewUri();
     $table = '_' . HardapiUtils::getShortName($type);
     // prepare properties
     $hardPropertyNames = array("uri" => $uri);
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     if (is_array($properties)) {
         if (count($properties) > 0) {
             // Get the table name
             $referencer = ResourceReferencer::singleton();
             $queryProps = array();
             foreach ($properties as $propertyUri => $value) {
                 $property = new \core_kernel_classes_Property($propertyUri);
                 $propertyLocation = $referencer->propertyLocation($property);
                 if (in_array("{$table}props", $propertyLocation) || !$referencer->isPropertyReferenced($property)) {
                     $propertyRange = $property->getRange();
                     $lang = $property->isLgDependent() ? \common_session_SessionManager::getSession()->getDataLanguage() : '';
                     $formatedValues = array();
                     if ($value instanceof \core_kernel_classes_Resource) {
                         $formatedValues[] = $dbWrapper->quote($value->getUri());
                     } else {
                         if (is_array($value)) {
                             foreach ($value as $val) {
                                 if ($val instanceof \core_kernel_classes_Resource) {
                                     $formatedValues[] = $dbWrapper->quote($val->getUri());
                                 } else {
                                     $formatedValues[] = $dbWrapper->quote($val);
                                 }
                             }
                         } else {
                             $formatedValues[] = $dbWrapper->quote($value);
                         }
                     }
                     if (is_null($propertyRange) || $propertyRange->getUri() == RDFS_LITERAL) {
                         foreach ($formatedValues as $formatedValue) {
                             $queryProps[] = "'{$property->getUri()}', {$formatedValue}, null, '{$lang}'";
                         }
                     } else {
                         foreach ($formatedValues as $formatedValue) {
                             $queryProps[] = "'{$property->getUri()}', null, {$formatedValue}, '{$lang}'";
                         }
                     }
                 } else {
                     $propertyName = HardapiUtils::getShortName($property);
                     if (is_array($value)) {
                         if (count($value) > 1) {
                             throw new Exception("try setting multivalue for the non multiple property {$property->getLabel()} ({$property->getUri()})");
                         } else {
                             $value = count($value) == 0 ? null : reset($value);
                             // take the only element
                         }
                     }
                     if ($value instanceof \core_kernel_classes_Resource) {
                         $value = $value->getUri();
                     }
                     $hardPropertyNames[$propertyName] = $value;
                 }
             }
         }
     }
     // spawn
     $returnValue = new \core_kernel_classes_Resource($uri, __METHOD__);
     $varnames = '"' . implode('","', array_keys($hardPropertyNames)) . '"';
     try {
         $query = 'INSERT INTO "' . $table . '" (' . $varnames . ') VALUES (' . implode(',', array_fill(0, count($hardPropertyNames), '?')) . ')';
         $result = $dbWrapper->exec($query, array_values($hardPropertyNames));
         // reference the newly created instance
         ResourceReferencer::singleton()->referenceResource($returnValue, $table, array($type), true);
         // @todo this shoould be retrievable without an aditional query
         $instanceId = Utils::getInstanceId($returnValue);
         // @todo Merge into a single query
         if (!empty($queryProps)) {
             $prefixed = array();
             foreach ($queryProps as $row) {
                 $prefixed[] = ' (' . $instanceId . ', ' . $row . ')';
             }
             try {
                 $query = 'INSERT INTO "' . $table . 'props" ("instance_id", "property_uri", "property_value", "property_foreign_uri", "l_language") VALUES ' . implode(',', $prefixed);
                 $result = $dbWrapper->exec($query);
             } catch (\PDOException $e) {
                 throw new Exception("Unable to set properties (multiple) Value for the instance {$returnValue->getUri()} in {$tableName} : " . $e->getMessage());
             }
         }
     } catch (\PDOException $e) {
         throw new Exception("Unable to create instance for the class {$type->getUri()} in the table {$table} : " . $e->getMessage());
     }
     return $returnValue;
 }
 /**
  * Test the referencer on properties, using the file caching mode
  * (it's the default caching mode for the properties)
  * @see oat\generisHard\models\hardapi\ResourceReferencer
  */
 public function testPropertyReferencer()
 {
     $referencer = ResourceReferencer::singleton();
     $this->assertIsA($referencer, 'oat\\generisHard\\models\\hardapi\\ResourceReferencer');
     $referencer->setPropertyCache(ResourceReferencer::CACHE_FILE);
     $referencer->clearCaches();
     $class = new core_kernel_classes_Class(CLASS_GENERIS_USER);
     $table = '_' . Utils::getShortName($class);
     // this part simulates a hardifying of the Userclass
     $myUserTblMgr = new TableManager($table);
     $this->assertFalse($myUserTblMgr->exists());
     $this->assertTrue($myUserTblMgr->create(array(array('name' => '05label'), array('name' => '05comment'), array('name' => '07login'), array('name' => '07password'), array('name' => '07userMail'), array('name' => '07userFirstName'), array('name' => '07userLastName'))));
     $this->assertTrue($myUserTblMgr->exists());
     $referencer->referenceClass($class);
     $this->assertTrue($referencer->isClassReferenced($class));
     // test start on the cache containing the simulated data
     // in case of a  fallback to the real sata (class_to_table) the tests fail
     $labelProperty = new core_kernel_classes_Property(RDFS_LABEL);
     $this->assertTrue($referencer->isPropertyReferenced($labelProperty));
     $commentProperty = new core_kernel_classes_Property(RDFS_COMMENT);
     $this->assertTrue($referencer->isPropertyReferenced($commentProperty));
     $loginProperty = new core_kernel_classes_Property(PROPERTY_USER_LOGIN);
     $this->assertTrue($referencer->isPropertyReferenced($loginProperty));
     $passwordProperty = new core_kernel_classes_Property(PROPERTY_USER_PASSWORD);
     $this->assertTrue($referencer->isPropertyReferenced($passwordProperty));
     $firstNameProperty = new core_kernel_classes_Property(PROPERTY_USER_FIRSTNAME);
     foreach ($referencer->propertyLocation($firstNameProperty) as $foundTable) {
         $this->assertEquals($foundTable, $table);
     }
     $this->assertTrue($myUserTblMgr->exists());
     $referencer->unReferenceClass($class);
     $this->assertFalse($referencer->isClassReferenced($class));
     $this->assertFalse($myUserTblMgr->exists());
     // Testing the cache...
     $cache = common_cache_FileCache::singleton();
     $serial = 'hard-api-property';
     $this->assertTrue($cache->has($serial));
     try {
         $cacheContent = $cache->get($serial);
         $this->assertTrue(is_array($cacheContent));
         $this->assertTrue(count($cacheContent) > 0);
         $this->assertTrue(array_key_exists(RDFS_LABEL, $cacheContent));
         $this->assertTrue(array_key_exists(PROPERTY_USER_LOGIN, $cacheContent));
     } catch (common_cache_Exception $e) {
         $this->fail('Cannot access hard-api-property cache.');
     }
     //clear the cache
     $cache->remove($serial);
     $this->assertFalse($cache->has($serial));
 }
 public function testHardPropertyModifications()
 {
     $this->hardify();
     $this->createData();
     $dbWrapper = core_kernel_classes_DbWrapper::singleton();
     $movieClass = $this->targetMovieClass;
     $workClass = $this->targetWorkClass;
     $authorProperty = $this->targetAuthorProperty;
     $producerProperty = $this->targetProducerProperty;
     $actorsProperty = $this->targetActorsProperty;
     $labelProperty = new core_kernel_classes_Property(RDFS_LABEL);
     $referencer = ResourceReferencer::singleton();
     $propertyProxy = PropertyProxy::singleton();
     // Retrieve interesting resources.
     $instances = $workClass->searchInstances(array($authorProperty->getUri() => 'Leonardo da Vinci'), array('like' => false, 'recursive' => false));
     $monaLisa = current($instances);
     $instances = $movieClass->searchInstances(array($labelProperty->getUri() => 'The Lord of the Rings'), array('like' => false, 'recursive' => false));
     $lordOfTheRings = current($instances);
     $instances = $movieClass->searchInstances(array($labelProperty->getUri() => 'The Hobbit'), array('like' => true, 'recursive' => false));
     $theHobbit = current($instances);
     if (empty($monaLisa) || empty($lordOfTheRings) || empty($theHobbit)) {
         $this->fail("Unable to retrieve instances that will be used in the following tests.");
     } else {
         // Try to create a new scalar property after hardification.
         $testProperty = $movieClass->createProperty('after hardify property');
         $testPropertyShortName = Utils::getShortName($testProperty);
         $testPropertyLocations = $referencer->propertyLocation($testProperty);
         $movieClassLocations = $referencer->classLocations($movieClass);
         $movieClassTable = $movieClassLocations[0]['table'];
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $workClassLocations = $referencer->classLocations($workClass);
         $workClassTable = $movieClassLocations[0]['table'];
         $workClassTableColumns = $dbWrapper->getColumnNames($workClassTable);
         $testPropertyShortName = Utils::getShortName($testProperty);
         $authorPropertyShortName = Utils::getShortName($authorProperty);
         // test delegation and presence of the column.
         $this->assertFalse($testProperty->isMultiple());
         $this->assertTrue(in_array($testPropertyShortName, $movieClassTableColumns));
         $this->assertIsA($propertyProxy->getImpToDelegateTo($testProperty), 'oat\\generisHard\\models\\hardsql\\Property');
         // set language dependency of the test property to true.
         $testProperty->setLgDependent(true);
         $this->assertTrue($testProperty->isLgDependent());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertFalse(in_array($testPropertyShortName, $movieClassTableColumns));
         // create some property values for the test property.
         $testMovie = $movieClass->createInstance('A Test Movie');
         $testMovie->setPropertyValue($testProperty, 'EN-TestPropertyValue-1');
         $testMovie->setPropertyValueByLg($testProperty, 'EN-TestPropertyValue-2', DEFAULT_LANG);
         $testMovie->setPropertyValueByLg($testProperty, 'FR-TestPropertyValue-1', 'FR');
         $testPropertyValues = $testMovie->getPropertyValues($testProperty);
         $this->assertEquals(count($testPropertyValues), 2);
         // Only EN values will come back.
         $testPropertyValues = $testMovie->getPropertyValuesByLg($testProperty, DEFAULT_LANG);
         $this->assertEquals(count($testPropertyValues->sequence), 2);
         $testPropertyValues = $testMovie->getPropertyValuesByLg($testProperty, 'FR');
         $this->assertEquals(count($testPropertyValues->sequence), 1);
         // set back the language dependency of the test property to false.
         $testProperty->setLgDependent(false);
         $this->assertFalse($testProperty->isLgDependent());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertTrue(in_array($testPropertyShortName, $movieClassTableColumns));
         $testPropertyValues = $testMovie->getPropertyValues($testProperty);
         $this->assertEquals(count($testPropertyValues), 1);
         // set the author property to multiple.
         $this->assertTrue(in_array($authorPropertyShortName, $movieClassTableColumns));
         $this->assertFalse($authorProperty->isMultiple());
         $authorProperty->setMultiple(true);
         $this->assertTrue($authorProperty->isMultiple());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertFalse(in_array($authorPropertyShortName, $movieClassTableColumns));
         // Add a fake value to make it multi valued
         $theHobbit->setPropertyValue($authorProperty, 'The Clone of Peter Jackson');
         $authors = $theHobbit->getPropertyValues($authorProperty);
         $this->assertEquals(count($authors), 2);
         $this->assertEquals(current($authors), 'Peter Jackson');
         next($authors);
         $this->assertEquals(current($authors), 'The Clone of Peter Jackson');
         $authors = $monaLisa->getPropertyValues($authorProperty);
         $this->assertEquals(count($authors), 1);
         $this->assertEquals(current($authors), 'Leonardo da Vinci');
         // reset the author property to scalar.
         $authorProperty->setMultiple(false);
         $this->assertFalse($authorProperty->isMultiple());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertTrue(in_array($authorPropertyShortName, $movieClassTableColumns));
         $authors = $theHobbit->getPropertyValues($authorProperty);
         $this->assertEquals(count($authors), 1);
         $this->assertEquals(current($authors), 'Peter Jackson');
     }
 }
 /**
  * Short description of method setLgDependent
  *
  * @access public
  * @author Jerome Bogaerts, <*****@*****.**>
  * @param  Resource resource
  * @param  boolean isLgDependent
  * @return void
  */
 public function setLgDependent(\core_kernel_classes_Resource $resource, $isLgDependent)
 {
     // First, do the same as in smooth mode.
     \core_kernel_persistence_smoothsql_Property::singleton()->setLgDependent($resource, $isLgDependent);
     // Second, we alter the relevant table(s) if needed.
     // For all the classes that have the resource as domain,
     // we have to alter the correspondent tables.
     $referencer = ResourceReferencer::singleton();
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     $propertyDescription = HardapiUtils::propertyDescriptor($resource);
     $wasMulti = $propertyDescription['isMultiple'];
     $wasLgDependent = $propertyDescription['isLgDependent'];
     // @TODO $batchSize's value is arbitrary.
     $batchSize = 100;
     // Transfer data $batchSize by $batchSize.
     if ($wasLgDependent != $isLgDependent) {
         try {
             // The multiplicity is then changing.
             // However, if the property was not 'language dependent' but 'multiple'
             // it is already stored as it should.
             if ($isLgDependent == true && $wasMulti == false && $wasLgDependent == false) {
                 // We go from single to multiple.
                 HardapiUtils::scalarToMultiple($resource, $batchSize);
             } else {
                 if ($isLgDependent == false && ($wasMulti == true || $wasLgDependent == true)) {
                     // We go from multiple to single.
                     HardapiUtils::multipleToScalar($resource, $batchSize);
                 }
             }
         } catch (HardapiException $e) {
             throw new Exception($e->getMessage());
         }
     }
 }