Пример #1
0
 public function __construct(FileInterface $file, TableSchemaInterface $tableSchema, IndexSchema $indexPage = null, $forkRate = 33)
 {
     $keyLength = 0;
     foreach ($indexPage->getColumns() as $columnId) {
         /* @var $columnPage ColumnSchema */
         $columnPage = $tableSchema->getColumn($columnId);
         assert(!is_null($columnPage));
         $keyLength += $columnPage->getCellSize();
     }
     if ($keyLength < 4) {
         $keyLength = 4;
     }
     if (!is_numeric($forkRate)) {
         throw new \ErrorException("Forkrate has to specified as integer!");
     }
     $forkRate = (int) $forkRate;
     $this->file = $file;
     $this->setKeyLength($keyLength);
     $this->forkRate = $forkRate;
     $this->tableSchema = $tableSchema;
     $this->indexPage = $indexPage;
     // if file is empty, initialize it
     if ($file->getLength() <= 1) {
         $file->setData(str_pad("", $keyLength * 8, ""));
         $rootNode = new BTreeNodePage();
         $rootNode->setKeyLength($keyLength);
         $rootNode->setForkRate($this->forkRate);
         // make sure root-reference is in index 1, not 0.
         // that way we can use reference 0 as 'not defined'/'not used'
         $this->setRootReference(1);
         $this->writeNode($rootNode, 1);
     }
 }
Пример #2
0
 public function setUp()
 {
     $forkRate = 16;
     $file = new FileResourceProxy(fopen("php://memory", "w"));
     $doublesFile = new FileResourceProxy(fopen("php://memory", "w"));
     $tableSchemaFile = new FileResourceProxy(fopen("php://memory", "w"));
     $indexSchemaFile = new FileResourceProxy(fopen("php://memory", "w"));
     $tableSchema = new TableSchema($tableSchemaFile, $indexSchemaFile);
     $columnPageA = new ColumnSchema();
     $columnPageA->setName("columnB");
     $columnPageA->setIndex(0);
     $columnPageA->setDataType(DataType::INT());
     $columnPageA->setLength(4);
     $tableSchema->addColumnSchema($columnPageA);
     $columnPageB = new ColumnSchema();
     $columnPageB->setName("columnC");
     $columnPageB->setIndex(1);
     $columnPageB->setDataType(DataType::VARCHAR());
     $columnPageB->setLength(4);
     $tableSchema->addColumnSchema($columnPageB);
     $indexPage = new IndexSchema();
     $indexPage->setName("test-index");
     $indexPage->setColumns([0, 1]);
     $indexPage->setType(Type::INDEX());
     $indexPage->setEngine(IndexEngine::BTREE());
     $this->btree = new BTree($file, $tableSchema, $indexPage, $forkRate);
     $this->btree->setDoublesFile($doublesFile);
     $this->btree->setIsDevelopmentMode(true);
 }
Пример #3
0
 public function createIndex($schemaId, $tableId, $indexId, TableSchemaInterface $tableSchema, IndexSchema $indexSchema)
 {
     $indexDataFilepath = sprintf(FilePathes::FILEPATH_INDEX_DATA, $schemaId, $tableId, $indexId);
     $indexDataFile = $this->filesystem->getFile($indexDataFilepath);
     $filePath = sprintf(FilePathes::FILEPATH_TABLE_COLUMN_INDEX, $schemaId, $tableId, $indexId);
     $indexDoublesFilepath = "";
     $indexDoublesFile = null;
     if (!$indexSchema->isUnique()) {
         $indexDoublesFilepath = sprintf(FilePathes::FILEPATH_INDEX_DOUBLES, $schemaId, $tableId, $indexId);
         $indexDoublesFile = $this->filesystem->getFile($indexDoublesFilepath);
     }
     $engine = $indexSchema->getEngine();
     /* @var $index IndexInterface */
     $index = null;
     if ($this->hasIndexFactory($engine)) {
         /* @var $indexFactory IndexFactoryInterface */
         $indexFactory = $this->getIndexFactory($engine);
         $index = $indexFactory->createIndex($schemaId, $tableId, $indexId, $tableSchema, $indexSchema);
     } else {
         switch ($engine) {
             default:
             case IndexEngine::RTREE():
                 $engineName = "UNKNOWN";
                 if (is_object($indexSchema->getEngine())) {
                     $engineName = $indexSchema->getEngine()->getName();
                 }
                 trigger_error("Requested unimplemented INDEX-ENGINE {$engineName}, using B-TREE instead!", E_USER_NOTICE);
                 # Use B-TREE instead of unimplemented index-engine
             # Use B-TREE instead of unimplemented index-engine
             case IndexEngine::BTREE():
                 $index = new BTree($indexDataFile, $tableSchema, $indexSchema);
                 if (!$indexSchema->isUnique()) {
                     $index->setDoublesFile($indexDoublesFile);
                 }
                 break;
             case IndexEngine::HASH():
                 $index = new HashTable($indexDataFile, $indexSchema->getKeyLength());
                 if (!$indexSchema->isUnique()) {
                     $index->setDoublesFile($indexDoublesFile);
                 }
                 break;
         }
     }
     return $index;
 }
Пример #4
0
 public function setUp()
 {
     $columnSchemaA = new ColumnSchema();
     $columnSchemaA->setName("foo");
     $columnSchemaA->setDataType(DataType::INTEGER());
     $columnSchemaA->setLength(4);
     $columnSchemaA->setExtraFlags(ColumnSchema::EXTRA_PRIMARY_KEY);
     $columnSchemaB = new ColumnSchema();
     $columnSchemaB->setName("baz");
     $columnSchemaB->setDataType(DataType::VARCHAR());
     $columnSchemaB->setLength(12);
     $columnSchemaC = new ColumnSchema();
     $columnSchemaC->setName("bar");
     $columnSchemaC->setDataType(DataType::DATETIME());
     $columnSchemaC->setLength(19);
     $indexSchema = new IndexSchema();
     $indexSchema->setName("idx_foo");
     $indexSchema->setColumns([0]);
     # n'th index in $columnData's
     $indexSchema->setEngine(IndexEngine::BTREE());
     $indexSchema->setType(Type::UNIQUE());
     $indexSchema->setKeyLength(4);
     $tableSchema = new TableSchema(new FileResourceProxy(fopen("php://memory", "w")), new FileResourceProxy(fopen("php://memory", "w")));
     $tableSchema->addColumnSchema($columnSchemaA);
     $tableSchema->addColumnSchema($columnSchemaB);
     $tableSchema->addColumnSchema($columnSchemaC);
     $tableSchema->addIndexSchema($indexSchema);
     $this->table = new Table($tableSchema, [new ColumnData(new FileResourceProxy(fopen("php://memory", "w")), $columnSchemaA), new ColumnData(new FileResourceProxy(fopen("php://memory", "w")), $columnSchemaB), new ColumnData(new FileResourceProxy(fopen("php://memory", "w")), $columnSchemaC)], [new BTree(new FileResourceProxy(fopen("php://memory", "w")), $tableSchema, $indexSchema)], new FileResourceProxy(fopen("php://memory", "w")), new FileResourceProxy(fopen("php://memory", "w")));
 }
Пример #5
0
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement CreateTableStatement */
     $context = new ExecutionContext($this->schemaManager, $statement, $parameters);
     /* @var $databaseSchema Schema */
     $databaseSchema = $this->schemaManager->getSchema();
     $schemaId = $this->schemaManager->getCurrentlyUsedDatabaseId();
     $tableName = $this->valueResolver->resolveValue($statement->getName(), $context);
     $schemaPage = new DatabaseSchemaPage();
     $schemaPage->setName($tableName);
     $schemaPage->setType(Type::TABLE());
     $schemaPage->setEngine(Engine::factory($statement->getEngine()->getName()));
     $schemaPage->setCollation(strtoupper($statement->getCollate()));
     $schemaPage->setUseChecksum($statement->getUseChecksum());
     $schemaPage->setMaxRows($statement->getMaximumRows());
     $schemaPage->setMinRows($statement->getMinimumRows());
     $schemaPage->setPackKeys($statement->getPackKeys());
     $schemaPage->setDelayKeyWrite($statement->getDelayKeyWrite());
     $schemaPage->setRowFormat(RowFormat::factory($statement->getRowFormat()));
     $schemaPage->setInsertMethod(InsertMethod::factory($statement->getInsertMethod()));
     $databaseSchema->registerTableSchema($schemaPage);
     /* @var $tableSchema TableSchema */
     $tableSchema = $this->schemaManager->getTableSchema($tableName);
     assert($tableSchema instanceof TableSchema);
     ### WRITE COLUMNS
     switch (true) {
         case is_array($statement->getColumnDefinition()):
             foreach ($statement->getColumnDefinition() as $name => $column) {
                 /* @var $column ColumnDefinition */
                 $columnPage = new ColumnSchema();
                 $columnPage->setName($name);
                 $columnPage->setDataType(DataType::factory($column->getDataType()->getName()));
                 /* @var $dataType DataType */
                 $dataType = $columnPage->getDataType();
                 $flags = 0;
                 if ($column->getIsPrimaryKey()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_PRIMARY_KEY;
                 }
                 if ($column->getIsUnique()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_UNIQUE_KEY;
                 }
                 if (!$column->getIsNullable()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_NOT_NULL;
                 }
                 if ($column->getIsAutoIncrement()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_AUTO_INCREMENT;
                 }
                 $columnPage->setExtraFlags($flags);
                 /* @var $dataType DataType */
                 $dataType = $column->getDataType();
                 $columnPage->setLength($dataType->getByteLength());
                 $columnPage->setSecondLength($dataType->getSecondByteLength());
                 if (!is_null($column->getDataTypeLength())) {
                     $columnPage->setLength($column->getDataTypeLength());
                 }
                 if (!is_null($column->getDataTypeSecondLength())) {
                     $columnPage->setSecondLength($column->getDataTypeSecondLength());
                 }
                 if (!is_null($column->getDefaultValue()) && !$columnPage->isDefaultValueInFile()) {
                     $columnPage->setDefaultValue($column->getDefaultValue());
                 }
                 $columnIndex = $tableSchema->addColumnSchema($columnPage);
                 if (!is_null($column->getDefaultValue()) && $columnPage->isDefaultValueInFile()) {
                     $defaultValueFilepath = sprintf(FilePathes::FILEPATH_DEFAULT_VALUE, $schemaId, $tableName, $columnIndex);
                     $this->tableManager->getFilesystem()->putFileContents($defaultValueFilepath, $column->getDefaultValue());
                 }
             }
             break;
         case $statement->getColumnDefinition() instanceof Select:
             break;
         case $statement->getColumnDefinition() instanceof TableInterface:
             break;
     }
     foreach ($statement->getIndexes() as $indexName => $index) {
         /* @var $index Index */
         $indexSchemaPage = new IndexSchema();
         $indexSchemaPage->setName($indexName);
         $indexSchemaPage->setEngine(IndexEngine::BTREE());
         switch (true) {
             case $index->getIsPrimary():
                 $indexSchemaPage->setType(IndexType::PRIMARY());
                 break;
             case $index->getIsUnique():
                 $indexSchemaPage->setType(IndexType::UNIQUE());
                 break;
             default:
                 $indexSchemaPage->setType(IndexType::INDEX());
                 break;
         }
         $method = ForeignKeyMethod::factory($index->getForeignKeyOnDeleteReferenceOption()->getName());
         $indexSchemaPage->setForeignKeyOnDeleteMethod($method);
         $method = ForeignKeyMethod::factory($index->getForeignKeyOnUpdateReferenceOption()->getName());
         $indexSchemaPage->setForeignKeyOnUpdateMethod($method);
         $keyLength = 0;
         $columns = array();
         foreach ($index->getColumns() as $indexColumnName) {
             $indexColumnId = $tableSchema->getColumnIndex((string) $indexColumnName);
             if (strlen($indexColumnId) <= 0) {
                 throw new ErrorException("Could not find index column '{$indexColumnName}' in table-schema!");
             }
             $columns[] = $indexColumnId;
             $keyLength += $statement->getColumnDefinition()[(string) $indexColumnName]->getDataSize();
         }
         $indexSchemaPage->setColumns($columns);
         $indexSchemaPage->setKeyLength($keyLength);
         $tableSchema->addIndexSchema($indexSchemaPage);
     }
     foreach ($this->tableManager->getTableFactories() as $tableFactory) {
         /* @var $tableFactory TableFactoryInterface */
         if ($tableFactory instanceof InformationSchemaTableFactory) {
             $tableFactory->clearCache();
         }
     }
     ### RESULT
     $result = new TemporaryResult();
     $result->setIsSuccess(true);
     return $result;
 }
Пример #6
0
 public function getIndexSchema($index)
 {
     $file = $this->getIndexFile();
     $file->seek($index * IndexSchema::PAGE_SIZE, SEEK_SET);
     $data = $file->read(IndexSchema::PAGE_SIZE);
     if (strlen($data) !== IndexSchema::PAGE_SIZE) {
         return null;
     }
     $indexSchema = new IndexSchema();
     $indexSchema->setData($data);
     $indexSchema->setId($index);
     return $indexSchema;
 }