diff --git a/docs/eng/Insert.md b/docs/eng/Insert.md index 1a1ed38..e1df9d4 100644 --- a/docs/eng/Insert.md +++ b/docs/eng/Insert.md @@ -4,7 +4,7 @@ Insert command is modifying database and can only be done through writing socket Open an index with columns `'key', 'date', 'float', 'varchar', 'text', 'set', 'union'`. -Paste the data on the index, certainly pass an array of values, where a value for insertion is also an array. +Paste the data on the index, certainly pass an array of values. ```php $writer = new \HS\Writer('localhost', 9999); @@ -16,7 +16,7 @@ $indexId = $writer->getIndexId( ); $insertQuery = $writer->insertByIndex( $indexId, - array(array('467', '0000-00-01', '1.02', 'char', 'text467', '1', '1')) + array('467', '0000-00-01', '1.02', 'char', 'text467', '1', '1') ); ``` @@ -49,7 +49,7 @@ $insertQuery = $writer->insert( $this->getDatabase(), $this->getTableName(), 'PRIMARY', - array(array('468', '0000-00-01', '1.02', 'char', 'text468', '1', '1')) + array('468', '0000-00-01', '1.02', 'char', 'text468', '1', '1') ); ``` diff --git a/docs/rus/Insert.md b/docs/rus/Insert.md index bfd8fef..b21ffc2 100644 --- a/docs/rus/Insert.md +++ b/docs/rus/Insert.md @@ -4,7 +4,7 @@ Insert в открытый индекс Открываем индекс с колонками `'key', 'date', 'float', 'varchar', 'text', 'set', 'union'`. -Вставляем данные по индексу, обязательно передаем массив значений, где значение для вставки тоже является массивом. +Вставляем данные по индексу, обязательно передаем массив значений. ```php $writer = new \HS\Writer('localhost', 9999); $indexId = $writer->getIndexId( @@ -15,7 +15,7 @@ $indexId = $writer->getIndexId( ); $insertQuery = $writer->insertByIndex( $indexId, - array(array('467', '0000-00-01', '1.02', 'char', 'text467', '1', '1')) + array('467', '0000-00-01', '1.02', 'char', 'text467', '1', '1') ); ``` Если вы полностью уверены в работоспособности вашей команды, мы можем ее просто отослать серверу и не читать ответ, тем самым сэкономить время и память: @@ -43,7 +43,7 @@ $insertQuery = $writer->insert( $this->getDatabase(), $this->getTableName(), 'PRIMARY', - array(array('468', '0000-00-01', '1.02', 'char', 'text468', '1', '1')) + array('468', '0000-00-01', '1.02', 'char', 'text468', '1', '1') ); ``` Другой способ выполнить запрос: diff --git a/src/HS/Builder/InsertQueryBuilder.php b/src/HS/Builder/InsertQueryBuilder.php index edabf0a..db39d33 100644 --- a/src/HS/Builder/InsertQueryBuilder.php +++ b/src/HS/Builder/InsertQueryBuilder.php @@ -84,28 +84,4 @@ public function getQueryClassPath() { return 'HS\Query\InsertQuery'; } - - /** - * @param int $limit - * - * @return InsertQueryBuilder - */ - public function limit($limit) - { - $this->limit = $limit; - - return $this; - } - - /** - * @param int $offset - * - * @return InsertQueryBuilder - */ - public function offset($offset) - { - $this->offset = $offset; - - return $this; - } } \ No newline at end of file diff --git a/src/HS/Builder/QueryBuilderAbstract.php b/src/HS/Builder/QueryBuilderAbstract.php index 4df79f1..d5ea837 100644 --- a/src/HS/Builder/QueryBuilderAbstract.php +++ b/src/HS/Builder/QueryBuilderAbstract.php @@ -49,13 +49,15 @@ public function getQuery($indexId, $socket, $openIndexQuery = null) $this->openIndexQuery = $openIndexQuery; $classPath = $this->getQueryClassPath(); - $query = null; + $query = array(); switch ($classPath) { case 'HS\Query\InsertQuery': - $query = new InsertQuery($indexId, $this->valueList, $socket, $openIndexQuery); + foreach ($this->valueList as $rowList) { + $query[] = new InsertQuery($indexId, $rowList, $socket, $openIndexQuery); + } break; case 'HS\Query\DeleteQuery': - $query = new DeleteQuery( + $query[] = new DeleteQuery( $indexId, $this->comparison, $this->keyList, @@ -70,7 +72,7 @@ public function getQuery($indexId, $socket, $openIndexQuery = null) ); break; case 'HS\Query\SelectQuery': - $query = new SelectQuery( + $queryTmp = new SelectQuery( $indexId, $this->comparison, $this->keyList, @@ -83,9 +85,11 @@ public function getQuery($indexId, $socket, $openIndexQuery = null) $this->filterList, null ); + $queryTmp->setReturnType($this->returnType); + $query[] = $queryTmp; break; case 'HS\Query\UpdateQuery': - $query = new UpdateQuery( + $query[] = new UpdateQuery( $indexId, $this->comparison, $this->keyList, @@ -101,7 +105,7 @@ public function getQuery($indexId, $socket, $openIndexQuery = null) ); break; default: - $query = new $classPath( + $query[] = new $classPath( $indexId, $this->comparison, $this->keyList, diff --git a/src/HS/Builder/QueryBuilderInterface.php b/src/HS/Builder/QueryBuilderInterface.php index ffc7dfa..642e7d0 100644 --- a/src/HS/Builder/QueryBuilderInterface.php +++ b/src/HS/Builder/QueryBuilderInterface.php @@ -18,24 +18,10 @@ interface QueryBuilderInterface * @param null|OpenIndexQuery $openIndexQuery * * - * @return QueryInterface + * @return QueryInterface[] */ public function getQuery($indexId, $socket, $openIndexQuery = null); - /** - * @param int $limit - * - * @return QueryBuilderInterface - */ - public function limit($limit); - - /** - * @param int $offset - * - * @return QueryBuilderInterface - */ - public function offset($offset); - /** * @return boolean */ diff --git a/src/HS/CommonClient.php b/src/HS/CommonClient.php index f68f20e..5ba99c0 100644 --- a/src/HS/CommonClient.php +++ b/src/HS/CommonClient.php @@ -54,6 +54,16 @@ abstract class CommonClient */ abstract public function authenticate($authKey); + /** + * @param string $dbName + * @param string $tableName + * @param string $indexName + * @param array $columnList + * @param bool $returnOnlyId + * @param array $filterColumnList + * + * @return int|OpenIndexQuery + */ abstract public function getIndexId( $dbName, $tableName, $indexName, array $columnList, $returnOnlyId = true, array $filterColumnList = array() ); @@ -77,7 +87,7 @@ public function __construct($url, $port, $authKey = null, $debug = false) } /** - * {@inheritdoc} + * @return boolean */ public function isDebug() { @@ -85,7 +95,9 @@ public function isDebug() } /** - * {@inheritdoc} + * @return \HS\Result\ResultAbstract[] + * @throws Exception + * @throws \Stream\Exception\StreamException */ public function getResultList() { @@ -131,7 +143,7 @@ public function getResultList() } /** - * {@inheritdoc} + * @return int */ public function getCountQueriesInQueue() { @@ -139,7 +151,7 @@ public function getCountQueriesInQueue() } /** - * {@inheritdoc} + * @return int */ public function getCountQueries() { @@ -147,7 +159,7 @@ public function getCountQueries() } /** - * {@inheritdoc} + * @return float */ public function getTimeQueries() { @@ -155,7 +167,7 @@ public function getTimeQueries() } /** - * {@inheritdoc} + * @return string */ public function getUrlConnection() { @@ -163,7 +175,10 @@ public function getUrlConnection() } /** - * {@inheritdoc} + * @param QueryBuilderInterface $queryBuilder + * + * @throws Exception + * @return \HS\Query\QueryAbstract */ public function addQueryBuilder(QueryBuilderInterface $queryBuilder) { @@ -178,19 +193,25 @@ public function addQueryBuilder(QueryBuilderInterface $queryBuilder) // if returned int if (is_int($openIndexQuery)) { - /** @var int $openIndexQuery */ - $queryForAdd = $queryBuilder->getQuery($openIndexQuery, $this); + $queryForAddList = $queryBuilder->getQuery($openIndexQuery, $this); } else { - /** @var OpenIndexQuery $openIndexQuery */ - $queryForAdd = $queryBuilder->getQuery($openIndexQuery->getIndexId(), $this, $openIndexQuery); + $queryForAddList = $queryBuilder->getQuery($openIndexQuery->getIndexId(), $this, $openIndexQuery); + } + + if (count($queryForAddList) === 0) { + throw new Exception("Returned empty list queries."); + } + + $queryForAdd = null; + foreach ($queryForAddList as $queryForAdd) { + $this->addQuery($queryForAdd); } - $this->addQuery($queryForAdd); return $queryForAdd; } /** - * {@inheritdoc} + * @param QueryInterface $query */ public function addQuery(QueryInterface $query) { @@ -208,9 +229,6 @@ public function sendQueries() } } - /** - * {@inheritdoc} - */ public function reOpen() { $this->close(); diff --git a/src/HS/Driver.php b/src/HS/Driver.php index 96c6c40..6ef948f 100644 --- a/src/HS/Driver.php +++ b/src/HS/Driver.php @@ -5,17 +5,13 @@ namespace HS; -use Stream\StreamDriverInterface; - -class Driver implements StreamDriverInterface +class Driver { const EOL = "\x0a"; // "\n" char const DELIMITER = "\x09"; // "\t" char const NULL = "\0"; private static $encodeMap = array( - // NULL is expressed as a single NUL(0x00). - null => "\x00", // A character in the range [0x00 - 0x0f] is prefixed by 0x01 and shifted by 0x40 "\x00" => "\x01\x40", "\x01" => "\x01\x41", @@ -67,14 +63,6 @@ public static function prepareSendDataStatic($data) return implode(self::DELIMITER, $encodedData); } - /** - * @{inheritdoc} - */ - public function prepareSendData($data) - { - return self::prepareSendDataStatic($data); - } - /** * @param string $data * @@ -87,14 +75,6 @@ public static function prepareReceiveDataStatic($data) return array_map('self::decodeData', $dataList); } - /** - * @{inheritdoc} - */ - public function prepareReceiveData($data) - { - return self::prepareReceiveDataStatic($data); - } - /** * @param string $data * @@ -112,10 +92,12 @@ public static function decodeData($data) */ public static function encodeData($data) { - if (false === $newStr = strtr($data, self::$encodeMap)) { - return $data; - } else { - return $newStr; + // NULL is expressed as a single NUL(0x00). + // null => "\x00", + if ($data === null) { + return "\x00"; } + + return strtr($data, self::$encodeMap); } } \ No newline at end of file diff --git a/src/HS/Query/InsertQuery.php b/src/HS/Query/InsertQuery.php index 8d69a93..c87d0c7 100644 --- a/src/HS/Query/InsertQuery.php +++ b/src/HS/Query/InsertQuery.php @@ -29,13 +29,10 @@ public function getQueryString() $queryString = sprintf( "%d" . Driver::DELIMITER . "+" . Driver::DELIMITER . "%d", $this->getIndexId(), - count($this->valueList[0]) + count($this->valueList) ); - - foreach ($this->valueList as $row) { - $queryString .= "\t" . Driver::prepareSendDataStatic($row); - } - + $queryString .= "\t" . Driver::prepareSendDataStatic($this->valueList); + return $queryString; } diff --git a/tests/HS/Builder/InsertQueryBuilderTest.php b/tests/HS/Builder/InsertQueryBuilderTest.php index f3f9b0a..2ea8eb0 100644 --- a/tests/HS/Builder/InsertQueryBuilderTest.php +++ b/tests/HS/Builder/InsertQueryBuilderTest.php @@ -15,7 +15,7 @@ public function testBuilderSingleInsert() $insertQueryBuilder = QueryBuilder::insert(); $insertQueryBuilder->toDatabase($this->getDatabase())->toTable( $this->getTableName() - )->addRow( + )->toIndex('PRIMARY')->addRow( array( 'key' => '123', 'date' => '0000-00-00', @@ -35,4 +35,42 @@ public function testBuilderSingleInsert() $this->assertTrue($insertResult->isSuccessfully(), 'Fall insertQuery is not successfully done.'); $this->assertTablesHSEqual(__METHOD__); } + + public function testBuilderMultiInsert() + { + $insertQueryBuilder = QueryBuilder::insert(); + $insertQueryBuilder->toDatabase($this->getDatabase())->toTable( + $this->getTableName() + )->addRowList( + array( + array( + 'key' => '123', + 'date' => '0000-00-00', + 'float' => '1.02', + 'varchar' => 'char', + 'text' => 'text', + 'set' => 'a', + 'union' => 'a', + // TODO fix bug with 'null' => null + ), + array( + 'key' => '124', + 'date' => '0000-00-00', + 'float' => '1.04', + 'varchar' => 'char', + 'text' => 'text', + 'set' => 'a', + 'union' => 'a', + // TODO fix bug with 'null' => null + ) + ) + ); + + $insertQuery = $this->getWriter()->addQueryBuilder($insertQueryBuilder); + $this->getWriter()->getResultList(); + + $insertResult = $insertQuery->getResult(); + $this->assertTrue($insertResult->isSuccessfully(), 'Fall insertQuery is not successfully done.'); + $this->assertTablesHSEqual(__METHOD__); + } } \ No newline at end of file diff --git a/tests/HS/Builder/SelectQueryBuilderTest.php b/tests/HS/Builder/SelectQueryBuilderTest.php index 48ddc4a..6c743c2 100644 --- a/tests/HS/Builder/SelectQueryBuilderTest.php +++ b/tests/HS/Builder/SelectQueryBuilderTest.php @@ -19,8 +19,9 @@ public function testSingleSelect() ) ->fromDataBase($this->getDatabase()) ->fromTable($this->getTableName()) - ->where(Comparison::EQUAL, array('key' => 42)); + ->where(Comparison::EQUAL, array('key' => 42))->returnAsAssoc(); + $this->assertEquals('HS\Query\SelectQuery', $selectQueryBuilder->getQueryClassPath()); $selectQuery = $this->getReader()->addQueryBuilder($selectQueryBuilder); $this->getReader()->getResultList(); @@ -45,6 +46,39 @@ public function testSingleSelect() ); } + public function testSingleSelectAsVector() + { + $selectQueryBuilder = QueryBuilder::select( + array('key', 'date', 'float', 'varchar', 'text', 'set', 'null', 'union') + ) + ->fromDataBase($this->getDatabase()) + ->fromTable($this->getTableName()) + ->where(Comparison::EQUAL, array('key' => 42))->returnAsVector(); + + $selectQuery = $this->getReader()->addQueryBuilder($selectQueryBuilder); + $this->getReader()->getResultList(); + + $selectResult = $selectQuery->getResult(); + $this->assertTrue($selectResult->isSuccessfully(), 'Fall selectQuery is not successfully done.'); + + $this->assertEquals( + array( + array( + '42', + '2010-10-29', + '3.14159', + 'variable length', + "some\r\nbig\r\ntext", + 'a,c', + null, + 'b' + ) + ), + $selectResult->getData(), + 'Fall returned data not valid.' + ); + } + public function testSingleSelectExceptionWhere() { $selectQueryBuilder = QueryBuilder::select( diff --git a/tests/HS/Component/FilterTest.php b/tests/HS/Component/FilterTest.php index 5887ee6..4fe87ab 100644 --- a/tests/HS/Component/FilterTest.php +++ b/tests/HS/Component/FilterTest.php @@ -24,6 +24,14 @@ public function testGetComparison() $this->assertEquals(Comparison::EQUAL, $this->filter->getComparison(), 'Fail returned comparison is wrong.'); } + public function testGetComparisonObject() + { + $this->assertTrue( + $this->filter->getComparisonObject() instanceof Comparison, + 'Fail returned comparisonObject is wrong.' + ); + } + public function testGetPosition() { $this->assertEquals(5, $this->filter->getPosition(), 'Fail returned position is wrong.'); @@ -38,4 +46,9 @@ public function testGetDefaultType() { $this->assertEquals('F', $this->filter->getType(), 'Fail returned type is wrong.'); } + + public function testConstructWithComparisonClass() + { + $filter = new Filter(new Comparison(Comparison::EQUAL), 5, 'key'); + } } \ No newline at end of file diff --git a/tests/HS/Writer/InsertQueryTest.php b/tests/HS/Writer/InsertQueryTest.php index ba782b4..f9f949a 100644 --- a/tests/HS/Writer/InsertQueryTest.php +++ b/tests/HS/Writer/InsertQueryTest.php @@ -22,7 +22,7 @@ public function testSingleInsertByIndexId() ); $insertQuery = $writer->insertByIndex( $indexId, - array(array('467', '0000-00-01', '1.02', 'char', 'text467', '1', '1')) + array('467', '0000-00-01', '1.02', 'char', 'text467', '1', '1') ); $writer->getResultList(); @@ -40,7 +40,7 @@ public function testSingleInsert() $this->getDatabase(), $this->getTableName(), 'PRIMARY', - array(array('468', '0000-00-01', '1.02', 'char', 'text468', '1', '1')) + array('468', '0000-00-01', '1.02', 'char', 'text468', '1', '1') ); $writer->getResultList(); diff --git a/tests/resources/fixture/testBuilderMultiInsertFixture.yml b/tests/resources/fixture/testBuilderMultiInsertFixture.yml new file mode 100644 index 0000000..95c4f9b --- /dev/null +++ b/tests/resources/fixture/testBuilderMultiInsertFixture.yml @@ -0,0 +1,198 @@ +hs: + - + key: 1 + date: "0000-00-00" + float: 1 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 0 + + - + key: 2 + date: "0000-00-00" + float: 2 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 0 + + - + key: 3 + date: "0000-00-00" + float: 3 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 0 + + - + key: 4 + date: "0000-00-00" + float: 4 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 0 + + - + key: 5 + date: "0000-00-00" + float: 5 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 0 + + - + key: 12 + date: "0000-00-00" + float: 12345 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 0 + + - + key: 42 + date: "2010-10-29" + float: 3.14159 + varchar: "variable length" + text: "some\r\nbig\r\ntext" + set: "a,c" + union: "b" + "null": + num: 0 + + - + key: 100 + date: "0000-00-00" + float: 0 + varchar: "" + text: "" + set: "" + union: "a" + "null": + num: 1 + + - + key: 101 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text101" + set: "" + union: "a" + "null": + num: 3 + + - + key: 102 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text102" + set: "" + union: "a" + "null": + num: 3 + + - + key: 103 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text103" + set: "" + union: "a" + "null": + num: 3 + + - + key: 104 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text104" + set: "" + union: "a" + "null": + num: 10 + + - + key: 105 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text105" + set: "" + union: "a" + "null": + num: 10 + + - + key: 106 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text106" + set: "" + union: "a" + "null": + num: 15 + + - + key: 107 + date: "0000-00-00" + float: 0 + varchar: "" + text: "text107" + set: "" + union: "a" + "null": + num: 15 + + - + key: 123 + date: "0000-00-00" + float: 1.02 + varchar: "char" + text: "text" + set: "a" + union: "a" + "null": 0 + num: 0 + + - + key: 124 + date: "0000-00-00" + float: 1.04 + varchar: "char" + text: "text" + set: "a" + union: "a" + "null": 0 + num: 0 + + - + key: 10001 + date: "2012-01-20" + float: 1 + varchar: "text with special chars" + text: "" + set: "" + union: "a" + "null": + num: 0 \ No newline at end of file