Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
f4a8be1f
Commit
f4a8be1f
authored
Nov 12, 2013
by
Paul Klimov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Sphinx MVA insert and update resolved.
parent
cbfa7e61
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
380 additions
and
20 deletions
+380
-20
ColumnSchema.php
extensions/sphinx/ColumnSchema.php
+1
-1
Command.php
extensions/sphinx/Command.php
+3
-3
Connection.php
extensions/sphinx/Connection.php
+17
-0
DataReader.php
extensions/sphinx/DataReader.php
+266
-0
QueryBuilder.php
extensions/sphinx/QueryBuilder.php
+50
-13
Schema.php
extensions/sphinx/Schema.php
+1
-1
CommandTest.php
tests/unit/extensions/sphinx/CommandTest.php
+42
-2
No files found.
extensions/sphinx/ColumnSchema.php
View file @
f4a8be1f
...
...
@@ -65,7 +65,7 @@ class ColumnSchema extends Object
if
(
$value
===
null
||
gettype
(
$value
)
===
$this
->
phpType
||
$value
instanceof
Expression
)
{
return
$value
;
}
if
(
$value
===
''
&&
$this
->
type
!==
Schema
::
TYPE_
TEXT
&&
$this
->
type
!==
Schema
::
TYPE_
STRING
)
{
if
(
$value
===
''
&&
$this
->
type
!==
Schema
::
TYPE_STRING
)
{
return
null
;
}
switch
(
$this
->
phpType
)
{
...
...
extensions/sphinx/Command.php
View file @
f4a8be1f
...
...
@@ -10,7 +10,6 @@ namespace yii\sphinx;
use
Yii
;
use
yii\base\Component
;
use
yii\caching\Cache
;
use
yii\db\DataReader
;
use
yii\db\Exception
;
/**
...
...
@@ -432,8 +431,9 @@ class Command extends Component
*/
public
function
batchInsert
(
$index
,
$columns
,
$rows
)
{
$sql
=
$this
->
db
->
getQueryBuilder
()
->
batchInsert
(
$index
,
$columns
,
$rows
);
return
$this
->
setSql
(
$sql
);
$params
=
[];
$sql
=
$this
->
db
->
getQueryBuilder
()
->
batchInsert
(
$index
,
$columns
,
$rows
,
$params
);
return
$this
->
setSql
(
$sql
)
->
bindValues
(
$params
);
}
/**
...
...
extensions/sphinx/Connection.php
View file @
f4a8be1f
...
...
@@ -48,4 +48,20 @@ class Connection extends \yii\db\Connection
{
return
$this
->
getSchema
()
->
quoteIndexName
(
$name
);
}
/**
* Creates a command for execution.
* @param string $sql the SQL statement to be executed
* @param array $params the parameters to be bound to the SQL statement
* @return Command the Sphinx command
*/
public
function
createCommand
(
$sql
=
null
,
$params
=
[])
{
$this
->
open
();
$command
=
new
Command
([
'db'
=>
$this
,
'sql'
=>
$sql
,
]);
return
$command
->
bindValues
(
$params
);
}
}
\ No newline at end of file
extensions/sphinx/DataReader.php
0 → 100644
View file @
f4a8be1f
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\sphinx
;
use
yii\base\InvalidCallException
;
use
yii\base\Object
;
/**
* DataReader represents a forward-only stream of rows from a query result set.
*
* To read the current row of data, call [[read()]]. The method [[readAll()]]
* returns all the rows in a single array. Rows of data can also be read by
* iterating through the reader. For example,
*
* ~~~
* $reader = $command->query('SELECT * FROM idx_post');
*
* while ($row = $reader->read()) {
* $rows[] = $row;
* }
*
* // equivalent to:
* foreach ($reader as $row) {
* $rows[] = $row;
* }
*
* // equivalent to:
* $rows = $reader->readAll();
* ~~~
*
* Note that since DataReader is a forward-only stream, you can only traverse it once.
* Doing it the second time will throw an exception.
*
* It is possible to use a specific mode of data fetching by setting
* [[fetchMode]]. See the [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php)
* for more details about possible fetch mode.
*
* @property integer $columnCount The number of columns in the result set. This property is read-only.
* @property integer $fetchMode Fetch mode. This property is write-only.
* @property boolean $isClosed Whether the reader is closed or not. This property is read-only.
* @property integer $rowCount Number of rows contained in the result. This property is read-only.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
DataReader
extends
Object
implements
\Iterator
,
\Countable
{
/**
* @var \PDOStatement the PDOStatement associated with the command
*/
private
$_statement
;
private
$_closed
=
false
;
private
$_row
;
private
$_index
=
-
1
;
/**
* Constructor.
* @param Command $command the command generating the query result
* @param array $config name-value pairs that will be used to initialize the object properties
*/
public
function
__construct
(
Command
$command
,
$config
=
[])
{
$this
->
_statement
=
$command
->
pdoStatement
;
$this
->
_statement
->
setFetchMode
(
\PDO
::
FETCH_ASSOC
);
parent
::
__construct
(
$config
);
}
/**
* Binds a column to a PHP variable.
* When rows of data are being fetched, the corresponding column value
* will be set in the variable. Note, the fetch mode must include PDO::FETCH_BOUND.
* @param integer|string $column Number of the column (1-indexed) or name of the column
* in the result set. If using the column name, be aware that the name
* should match the case of the column, as returned by the driver.
* @param mixed $value Name of the PHP variable to which the column will be bound.
* @param integer $dataType Data type of the parameter
* @see http://www.php.net/manual/en/function.PDOStatement-bindColumn.php
*/
public
function
bindColumn
(
$column
,
&
$value
,
$dataType
=
null
)
{
if
(
$dataType
===
null
)
{
$this
->
_statement
->
bindColumn
(
$column
,
$value
);
}
else
{
$this
->
_statement
->
bindColumn
(
$column
,
$value
,
$dataType
);
}
}
/**
* Set the default fetch mode for this statement
* @param integer $mode fetch mode
* @see http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php
*/
public
function
setFetchMode
(
$mode
)
{
$params
=
func_get_args
();
call_user_func_array
([
$this
->
_statement
,
'setFetchMode'
],
$params
);
}
/**
* Advances the reader to the next row in a result set.
* @return array the current row, false if no more row available
*/
public
function
read
()
{
return
$this
->
_statement
->
fetch
();
}
/**
* Returns a single column from the next row of a result set.
* @param integer $columnIndex zero-based column index
* @return mixed the column of the current row, false if no more rows available
*/
public
function
readColumn
(
$columnIndex
)
{
return
$this
->
_statement
->
fetchColumn
(
$columnIndex
);
}
/**
* Returns an object populated with the next row of data.
* @param string $className class name of the object to be created and populated
* @param array $fields Elements of this array are passed to the constructor
* @return mixed the populated object, false if no more row of data available
*/
public
function
readObject
(
$className
,
$fields
)
{
return
$this
->
_statement
->
fetchObject
(
$className
,
$fields
);
}
/**
* Reads the whole result set into an array.
* @return array the result set (each array element represents a row of data).
* An empty array will be returned if the result contains no row.
*/
public
function
readAll
()
{
return
$this
->
_statement
->
fetchAll
();
}
/**
* Advances the reader to the next result when reading the results of a batch of statements.
* This method is only useful when there are multiple result sets
* returned by the query. Not all DBMS support this feature.
* @return boolean Returns true on success or false on failure.
*/
public
function
nextResult
()
{
if
((
$result
=
$this
->
_statement
->
nextRowset
())
!==
false
)
{
$this
->
_index
=
-
1
;
}
return
$result
;
}
/**
* Closes the reader.
* This frees up the resources allocated for executing this SQL statement.
* Read attempts after this method call are unpredictable.
*/
public
function
close
()
{
$this
->
_statement
->
closeCursor
();
$this
->
_closed
=
true
;
}
/**
* whether the reader is closed or not.
* @return boolean whether the reader is closed or not.
*/
public
function
getIsClosed
()
{
return
$this
->
_closed
;
}
/**
* Returns the number of rows in the result set.
* Note, most DBMS may not give a meaningful count.
* In this case, use "SELECT COUNT(*) FROM tableName" to obtain the number of rows.
* @return integer number of rows contained in the result.
*/
public
function
getRowCount
()
{
return
$this
->
_statement
->
rowCount
();
}
/**
* Returns the number of rows in the result set.
* This method is required by the Countable interface.
* Note, most DBMS may not give a meaningful count.
* In this case, use "SELECT COUNT(*) FROM tableName" to obtain the number of rows.
* @return integer number of rows contained in the result.
*/
public
function
count
()
{
return
$this
->
getRowCount
();
}
/**
* Returns the number of columns in the result set.
* Note, even there's no row in the reader, this still gives correct column number.
* @return integer the number of columns in the result set.
*/
public
function
getColumnCount
()
{
return
$this
->
_statement
->
columnCount
();
}
/**
* Resets the iterator to the initial state.
* This method is required by the interface Iterator.
* @throws InvalidCallException if this method is invoked twice
*/
public
function
rewind
()
{
if
(
$this
->
_index
<
0
)
{
$this
->
_row
=
$this
->
_statement
->
fetch
();
$this
->
_index
=
0
;
}
else
{
throw
new
InvalidCallException
(
'DataReader cannot rewind. It is a forward-only reader.'
);
}
}
/**
* Returns the index of the current row.
* This method is required by the interface Iterator.
* @return integer the index of the current row.
*/
public
function
key
()
{
return
$this
->
_index
;
}
/**
* Returns the current row.
* This method is required by the interface Iterator.
* @return mixed the current row.
*/
public
function
current
()
{
return
$this
->
_row
;
}
/**
* Moves the internal pointer to the next row.
* This method is required by the interface Iterator.
*/
public
function
next
()
{
$this
->
_row
=
$this
->
_statement
->
fetch
();
$this
->
_index
++
;
}
/**
* Returns whether there is a row of data at current position.
* This method is required by the interface Iterator.
* @return boolean whether there is a row of data at current position.
*/
public
function
valid
()
{
return
$this
->
_row
!==
false
;
}
}
\ No newline at end of file
extensions/sphinx/QueryBuilder.php
View file @
f4a8be1f
...
...
@@ -103,15 +103,26 @@ class QueryBuilder extends Object
$params
[
$n
]
=
$v
;
}
}
else
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$placeholders
[]
=
$phName
;
$params
[
$phName
]
=
!
is_array
(
$value
)
&&
isset
(
$columnSchemas
[
$name
])
?
$columnSchemas
[
$name
]
->
typecast
(
$value
)
:
$value
;
if
(
is_array
(
$value
))
{
// MVA :
$placeholderParts
=
[];
foreach
(
$value
as
$subValue
)
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$placeholderParts
[]
=
$phName
;
$params
[
$phName
]
=
isset
(
$columnSchemas
[
$name
])
?
$columnSchemas
[
$name
]
->
typecast
(
$subValue
)
:
$subValue
;
}
$placeholders
[]
=
'('
.
implode
(
','
,
$placeholderParts
)
.
')'
;
}
else
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$placeholders
[]
=
$phName
;
$params
[
$phName
]
=
isset
(
$columnSchemas
[
$name
])
?
$columnSchemas
[
$name
]
->
typecast
(
$value
)
:
$value
;
}
}
}
return
'INSERT INTO '
.
$this
->
db
->
quoteIndexName
(
$index
)
.
' ('
.
implode
(
', '
,
$names
)
.
') VALUES ('
.
implode
(
', '
,
$placeholders
)
.
')'
;
.
' ('
.
implode
(
', '
,
$names
)
.
') VALUES ('
.
implode
(
', '
,
$placeholders
)
.
')'
;
}
/**
...
...
@@ -131,9 +142,11 @@ class QueryBuilder extends Object
* @param string $index the index that new rows will be inserted into.
* @param array $columns the column names
* @param array $rows the rows to be batch inserted into the index
* @param array $params the binding parameters that will be generated by this method.
* They should be bound to the DB command later.
* @return string the batch INSERT SQL statement
*/
public
function
batchInsert
(
$index
,
$columns
,
$rows
)
public
function
batchInsert
(
$index
,
$columns
,
$rows
,
&
$params
)
{
if
((
$indexSchema
=
$this
->
db
->
getIndexSchema
(
$index
))
!==
null
)
{
$columnSchemas
=
$indexSchema
->
columns
;
...
...
@@ -149,16 +162,29 @@ class QueryBuilder extends Object
foreach
(
$rows
as
$row
)
{
$vs
=
[];
foreach
(
$row
as
$i
=>
$value
)
{
if
(
!
is_array
(
$value
)
&&
isset
(
$columnSchemas
[
$columns
[
$i
]]))
{
$value
=
$columnSchemas
[
$columns
[
$i
]]
->
typecast
(
$value
);
if
(
is_array
(
$value
))
{
// MVA :
$vsParts
=
[];
foreach
(
$value
as
$subValue
)
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$vsParts
[]
=
$phName
;
$params
[
$phName
]
=
isset
(
$columnSchemas
[
$columns
[
$i
]])
?
$columnSchemas
[
$columns
[
$i
]]
->
typecast
(
$subValue
)
:
$subValue
;
}
$vs
[]
=
'('
.
implode
(
','
,
$vsParts
)
.
')'
;
}
else
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
if
(
isset
(
$columnSchemas
[
$columns
[
$i
]]))
{
$value
=
$columnSchemas
[
$columns
[
$i
]]
->
typecast
(
$value
);
}
$params
[
$phName
]
=
is_string
(
$value
)
?
$this
->
db
->
quoteValue
(
$value
)
:
$value
;
$vs
[]
=
$phName
;
}
$vs
[]
=
is_string
(
$value
)
?
$this
->
db
->
quoteValue
(
$value
)
:
$value
;
}
$values
[]
=
'('
.
implode
(
', '
,
$vs
)
.
')'
;
}
return
'INSERT INTO '
.
$this
->
db
->
quoteIndexName
(
$index
)
.
' ('
.
implode
(
', '
,
$columns
)
.
') VALUES '
.
implode
(
', '
,
$values
);
.
' ('
.
implode
(
', '
,
$columns
)
.
') VALUES '
.
implode
(
', '
,
$values
);
}
/**
...
...
@@ -196,9 +222,20 @@ class QueryBuilder extends Object
$params
[
$n
]
=
$v
;
}
}
else
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$lines
[]
=
$this
->
db
->
quoteColumnName
(
$name
)
.
'='
.
$phName
;
$params
[
$phName
]
=
!
is_array
(
$value
)
&&
isset
(
$columnSchemas
[
$name
])
?
$columnSchemas
[
$name
]
->
typecast
(
$value
)
:
$value
;
if
(
is_array
(
$value
))
{
// MVA :
$lineParts
=
[];
foreach
(
$value
as
$subValue
)
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$lineParts
[]
=
$phName
;
$params
[
$phName
]
=
isset
(
$columnSchemas
[
$name
])
?
$columnSchemas
[
$name
]
->
typecast
(
$subValue
)
:
$subValue
;
}
$lines
[]
=
$this
->
db
->
quoteColumnName
(
$name
)
.
'='
.
'('
.
implode
(
','
,
$lineParts
)
.
')'
;
}
else
{
$phName
=
self
::
PARAM_PREFIX
.
count
(
$params
);
$lines
[]
=
$this
->
db
->
quoteColumnName
(
$name
)
.
'='
.
$phName
;
$params
[
$phName
]
=
!
is_array
(
$value
)
&&
isset
(
$columnSchemas
[
$name
])
?
$columnSchemas
[
$name
]
->
typecast
(
$value
)
:
$value
;
}
}
}
...
...
extensions/sphinx/Schema.php
View file @
f4a8be1f
...
...
@@ -62,7 +62,7 @@ class Schema extends Object
'timestamp'
=>
self
::
TYPE_TIMESTAMP
,
'bool'
=>
self
::
TYPE_BOOLEAN
,
'float'
=>
self
::
TYPE_FLOAT
,
'mva'
=>
self
::
TYPE_
STRING
,
'mva'
=>
self
::
TYPE_
INTEGER
,
];
/**
...
...
tests/unit/extensions/sphinx/CommandTest.php
View file @
f4a8be1f
...
...
@@ -2,7 +2,7 @@
namespace
yiiunit\extensions\sphinx
;
use
yii\
db
\DataReader
;
use
yii\
sphinx
\DataReader
;
use
yii\db\Expression
;
/**
...
...
@@ -103,7 +103,7 @@ class CommandTest extends SphinxTestCase
'title'
=>
'Test title'
,
'content'
=>
'Test content'
,
'type_id'
=>
2
,
//'category' => [41, 4
2],
'category'
=>
[
1
,
2
],
'id'
=>
1
,
]);
$this
->
assertEquals
(
1
,
$command
->
execute
(),
'Unable to execute insert!'
);
...
...
@@ -115,6 +115,45 @@ class CommandTest extends SphinxTestCase
/**
* @depends testInsert
*/
public
function
testBatchInsert
()
{
$db
=
$this
->
getConnection
();
$command
=
$db
->
createCommand
()
->
batchInsert
(
'yii2_test_rt_index'
,
[
'title'
,
'content'
,
'type_id'
,
'category'
,
'id'
,
],
[
[
'Test title 1'
,
'Test content 1'
,
1
,
[
1
,
2
],
1
,
],
[
'Test title 2'
,
'Test content 2'
,
2
,
[
3
,
4
],
2
,
],
]
);
$this
->
assertEquals
(
2
,
$command
->
execute
(),
'Unable to execute batch insert!'
);
$rows
=
$db
->
createCommand
(
'SELECT * FROM yii2_test_rt_index'
)
->
queryAll
();
$this
->
assertEquals
(
2
,
count
(
$rows
),
'No rows inserted!'
);
}
/**
* @depends testInsert
*/
public
function
testUpdate
()
{
$db
=
$this
->
getConnection
();
...
...
@@ -131,6 +170,7 @@ class CommandTest extends SphinxTestCase
'yii2_test_rt_index'
,
[
'type_id'
=>
$newTypeId
,
'category'
=>
[
3
,
4
],
],
'id = 1'
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment