Esempio n. 1
0
 /**
  * (non-PHPdoc)
  * @see core_kernel_persistence_ClassInterface::createProperty()
  */
 public function createProperty(\core_kernel_classes_Class $resource, $label = '', $comment = '', $isLgDependent = false)
 {
     $returnValue = null;
     // First we reference the property in smooth mode because meta models always remain there.
     $smoothReturnValue = \core_kernel_persistence_smoothsql_Class::singleton()->createProperty($resource, $label, $comment, $isLgDependent);
     if ($smoothReturnValue) {
         $property = new \core_kernel_classes_Property($resource->getUri());
         $column = array('name' => HardapiUtils::getShortName($smoothReturnValue));
         $column['multi'] = $isLgDependent ? true : false;
         // If no range set, we assume it is a literal.
         $column['foreign'] = false;
         // We do not know the range yet.
         $referencer = ResourceReferencer::singleton();
         $classLocations = $referencer->classLocations($resource);
         foreach ($classLocations as $loc) {
             $tblmgr = new TableManager($loc['table']);
             $tblmgr->addColumn($column);
         }
         $returnValue = $smoothReturnValue;
         $referencer->clearCaches();
     } else {
         $uri = $resource->getUri();
         throw new Exception("An error occured when creating property in smooth mode '{$uri}' before handling the hard sql aspect.");
     }
     return $returnValue;
 }
Esempio n. 2
0
 /**
  * Change a multi-valued property to a single-valued one.
  *
  * @access public
  * @author Jerome Bogaerts, <*****@*****.**>
  * @param  Resource property The property to modifiy.
  * @param  int batchSize Data must be transfered from the properties table to a given column. This parameter indicates the size of each pack of data transfered from the properties table to the column.
  * @return void
  */
 public static function multipleToScalar(\core_kernel_classes_Resource $property, $batchSize = 100)
 {
     $referencer = ResourceReferencer::singleton();
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     $propertyDescription = self::propertyDescriptor($property);
     $propertyLocations = $referencer->propertyLocation($property);
     $propName = $propertyDescription['name'];
     $propUri = $property->getUri();
     $propRanges = array();
     foreach ($propertyDescription['range'] as $range) {
         // If no range provided, we assume it is a Literal.
         $propRanges[] = !empty($range) ? $range->getUri() : RDFS_LITERAL;
     }
     $offset = 0;
     foreach ($propertyLocations as $tblname) {
         $tblmgr = new TableManager($tblname);
         if ($tblmgr->exists()) {
             // Reset offset.
             $offset = 0;
             try {
                 // We go from multiple to single.
                 $toDelete = array();
                 // will contain ids of rows to delete in the 'properties table' after data transfer.
                 // Add a column to the base table to receive single value.
                 $baseTableName = str_replace('props', '', $tblname);
                 $tblmgr->setName($baseTableName);
                 $shortName = self::getShortName($property);
                 $columnAdded = $tblmgr->addColumn(array('name' => $shortName, 'multi' => false));
                 if ($columnAdded == true) {
                     // Now get the values in the props table. Group by instance ID in order to get only
                     // one value to put in the target column.
                     do {
                         $hasResult = false;
                         $retrievePropertyValue = empty($propRanges) || in_array(RDFS_LITERAL, $propRanges) ? true : false;
                         $sql = 'SELECT "a"."id", "a"."instance_id", "a"."property_value", "a"."property_foreign_uri" FROM "' . $tblname . '" "a" ';
                         $sql .= 'RIGHT JOIN (SELECT "instance_id", MIN("id") AS "id" FROM "' . $tblname . '" WHERE "property_uri" = ? ';
                         $sql .= 'GROUP BY "instance_id") AS "b" ON ("a"."id" = "b"."id")';
                         $sql = $dbWrapper->limitStatement($sql, $batchSize, $offset);
                         $result = $dbWrapper->query($sql, array($propUri));
                         // prepare the update statement.
                         $sql = 'UPDATE "' . $baseTableName . '" SET "' . $shortName . '" = ? WHERE "id" = ?';
                         while ($row = $result->fetch()) {
                             // Transfer to the 'base table'.
                             $hasResult = true;
                             $propertyValue = $retrievePropertyValue == true ? $row['property_value'] : $row['property_foreign_uri'];
                             $dbWrapper->exec($sql, array($propertyValue, $row['instance_id']));
                             $toDelete[] = $row['id'];
                         }
                         $offset += $batchSize;
                     } while ($hasResult === true);
                     $inData = implode(',', $toDelete);
                     $sql = 'DELETE FROM "' . $tblname . '" WHERE "id" IN (' . $inData . ')';
                     if ($dbWrapper->exec($sql) == 0) {
                         // If an error occured or no rows removed, we
                         // have a problem.
                         $msg = "Cannot set multiplicity of Property '{$propUri}' because data transfered to the 'base table' could not be deleted";
                         throw new Exception($msg);
                     }
                 } else {
                     $msg = "Cannot set multiplicity of Property '{$propUri}' because the corresponding 'base table' column could not be created.";
                     throw new Exception($msg);
                 }
             } catch (\PDOException $e) {
                 $msg = "Cannot set multiplicity of Property '{$propUri}': " . $e->getMessage();
                 throw new Exception($msg);
             }
         } else {
             $msg = "Cannot set multiplicity of Property '{$propUri}' because the corresponding database location '{$tblname}' does not exist.";
             throw new Exception($msg);
         }
     }
     $referencer->clearCaches();
 }