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
7cc182fc
Commit
7cc182fc
authored
Nov 12, 2013
by
Paul Klimov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
"yii\sphinx\IndexSchema' created.
"yii\sphinx\Schema' reworked to drop inheritance from "yii\db".
parent
5a1b526a
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
444 additions
and
21 deletions
+444
-21
IndexSchema.php
extensions/sphinx/IndexSchema.php
+83
-0
Schema.php
extensions/sphinx/Schema.php
+361
-21
No files found.
extensions/sphinx/IndexSchema.php
0 → 100644
View file @
7cc182fc
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\sphinx
;
use
yii\base\Object
;
use
yii\base\InvalidParamException
;
/**
* IndexSchema represents the metadata of a Sphinx index.
*
* @property array $columnNames List of column names. This property is read-only.
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0
*/
class
IndexSchema
extends
Object
{
/**
* @var string name of the schema that this index belongs to.
*/
public
$schemaName
;
/**
* @var string name of this index.
*/
public
$name
;
/**
* @var string[] primary keys of this index.
*/
public
$primaryKey
=
[];
/**
* @var ColumnSchema[] column metadata of this index. Each array element is a [[ColumnSchema]] object, indexed by column names.
*/
public
$columns
=
[];
/**
* Gets the named column metadata.
* This is a convenient method for retrieving a named column even if it does not exist.
* @param string $name column name
* @return ColumnSchema metadata of the named column. Null if the named column does not exist.
*/
public
function
getColumn
(
$name
)
{
return
isset
(
$this
->
columns
[
$name
])
?
$this
->
columns
[
$name
]
:
null
;
}
/**
* Returns the names of all columns in this table.
* @return array list of column names
*/
public
function
getColumnNames
()
{
return
array_keys
(
$this
->
columns
);
}
/**
* Manually specifies the primary key for this table.
* @param string|array $keys the primary key (can be composite)
* @throws InvalidParamException if the specified key cannot be found in the table.
*/
public
function
fixPrimaryKey
(
$keys
)
{
if
(
!
is_array
(
$keys
))
{
$keys
=
[
$keys
];
}
$this
->
primaryKey
=
$keys
;
foreach
(
$this
->
columns
as
$column
)
{
$column
->
isPrimaryKey
=
false
;
}
foreach
(
$keys
as
$key
)
{
if
(
isset
(
$this
->
columns
[
$key
]))
{
$this
->
columns
[
$key
]
->
isPrimaryKey
=
true
;
}
else
{
throw
new
InvalidParamException
(
"Primary key '
$key
' cannot be found in index '
{
$this
->
name
}
'."
);
}
}
}
}
\ No newline at end of file
extensions/sphinx/Schema.php
View file @
7cc182fc
...
...
@@ -7,17 +7,48 @@
namespace
yii\sphinx
;
use
yii\db\TableSchema
;
use
yii\base\Object
;
use
yii\caching\Cache
;
use
Yii
;
use
yii\caching\GroupDependency
;
/**
*
Class Schema
*
Schema represents the Sphinx schema information.
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0
*/
class
Schema
extends
\yii\db\mysql\Schema
class
Schema
extends
Object
{
/**
* The followings are the supported abstract column data types.
*/
const
TYPE_PK
=
'pk'
;
const
TYPE_STRING
=
'string'
;
const
TYPE_INTEGER
=
'integer'
;
const
TYPE_BIGINT
=
'bigint'
;
const
TYPE_FLOAT
=
'float'
;
const
TYPE_TIMESTAMP
=
'timestamp'
;
const
TYPE_BOOLEAN
=
'boolean'
;
/**
* @var Connection the Sphinx connection
*/
public
$db
;
/**
* @var array list of ALL index names in the Sphinx
*/
private
$_indexNames
=
[];
/**
* @var array list of loaded index metadata (index name => IndexSchema)
*/
private
$_indexes
=
[];
/**
* @var QueryBuilder the query builder for this Sphinx connection
*/
private
$_builder
;
/**
* @var array mapping from physical column types (keys) to abstract column types (values)
*/
public
$typeMap
=
[
...
...
@@ -35,8 +66,200 @@ class Schema extends \yii\db\mysql\Schema
];
/**
* Creates a query builder for the database.
* This method may be overridden by child classes to create a DBMS-specific query builder.
* Loads the metadata for the specified index.
* @param string $name index name
* @return IndexSchema driver dependent index metadata. Null if the index does not exist.
*/
protected
function
loadTableSchema
(
$name
)
{
$index
=
new
IndexSchema
;
$this
->
resolveIndexNames
(
$index
,
$name
);
if
(
$this
->
findColumns
(
$index
))
{
return
$index
;
}
else
{
return
null
;
}
}
/**
* Resolves the index name and schema name (if any).
* @param IndexSchema $index the index metadata object
* @param string $name the index name
*/
protected
function
resolveIndexNames
(
$index
,
$name
)
{
$parts
=
explode
(
'.'
,
str_replace
(
'`'
,
''
,
$name
));
if
(
isset
(
$parts
[
1
]))
{
$index
->
schemaName
=
$parts
[
0
];
$index
->
name
=
$parts
[
1
];
}
else
{
$index
->
name
=
$parts
[
0
];
}
}
/**
* Obtains the metadata for the named index.
* @param string $name index name. The index name may contain schema name if any. Do not quote the index name.
* @param boolean $refresh whether to reload the index schema even if it is found in the cache.
* @return IndexSchema index metadata. Null if the named index does not exist.
*/
public
function
getIndexSchema
(
$name
,
$refresh
=
false
)
{
if
(
isset
(
$this
->
_indexes
[
$name
])
&&
!
$refresh
)
{
return
$this
->
_indexes
[
$name
];
}
$db
=
$this
->
db
;
$realName
=
$this
->
getRawIndexName
(
$name
);
if
(
$db
->
enableSchemaCache
&&
!
in_array
(
$name
,
$db
->
schemaCacheExclude
,
true
))
{
/** @var $cache Cache */
$cache
=
is_string
(
$db
->
schemaCache
)
?
Yii
::
$app
->
getComponent
(
$db
->
schemaCache
)
:
$db
->
schemaCache
;
if
(
$cache
instanceof
Cache
)
{
$key
=
$this
->
getCacheKey
(
$name
);
if
(
$refresh
||
(
$index
=
$cache
->
get
(
$key
))
===
false
)
{
$index
=
$this
->
loadTableSchema
(
$realName
);
if
(
$index
!==
null
)
{
$cache
->
set
(
$key
,
$index
,
$db
->
schemaCacheDuration
,
new
GroupDependency
(
$this
->
getCacheGroup
()));
}
}
return
$this
->
_indexes
[
$name
]
=
$index
;
}
}
return
$this
->
_indexes
[
$name
]
=
$index
=
$this
->
loadTableSchema
(
$realName
);
}
/**
* Returns the cache key for the specified index name.
* @param string $name the index name
* @return mixed the cache key
*/
protected
function
getCacheKey
(
$name
)
{
return
[
__CLASS__
,
$this
->
db
->
dsn
,
$this
->
db
->
username
,
$name
,
];
}
/**
* Returns the cache group name.
* This allows [[refresh()]] to invalidate all cached index schemas.
* @return string the cache group name
*/
protected
function
getCacheGroup
()
{
return
md5
(
serialize
([
__CLASS__
,
$this
->
db
->
dsn
,
$this
->
db
->
username
,
]));
}
/**
* Returns the metadata for all indexes in the database.
* @param string $schema the schema of the indexes. Defaults to empty string, meaning the current or default schema name.
* @param boolean $refresh whether to fetch the latest available index schemas. If this is false,
* cached data may be returned if available.
* @return IndexSchema[] the metadata for all indexes in the Sphinx.
* Each array element is an instance of [[IndexSchema]] or its child class.
*/
public
function
getTableSchemas
(
$schema
=
''
,
$refresh
=
false
)
{
$indexes
=
[];
foreach
(
$this
->
getIndexNames
(
$schema
,
$refresh
)
as
$name
)
{
if
(
$schema
!==
''
)
{
$name
=
$schema
.
'.'
.
$name
;
}
if
((
$index
=
$this
->
getIndexSchema
(
$name
,
$refresh
))
!==
null
)
{
$indexes
[]
=
$index
;
}
}
return
$indexes
;
}
/**
* Returns all index names in the database.
* @param string $schema the schema of the indexes. Defaults to empty string, meaning the current or default schema name.
* If not empty, the returned index names will be prefixed with the schema name.
* @param boolean $refresh whether to fetch the latest available index names. If this is false,
* index names fetched previously (if available) will be returned.
* @return string[] all index names in the database.
*/
public
function
getIndexNames
(
$schema
=
''
,
$refresh
=
false
)
{
if
(
!
isset
(
$this
->
_indexNames
[
$schema
])
||
$refresh
)
{
$this
->
_indexNames
[
$schema
]
=
$this
->
findIndexNames
(
$schema
);
}
return
$this
->
_indexNames
[
$schema
];
}
/**
* Returns all index names in the database.
* @param string $schema the schema of the indexes. Defaults to empty string, meaning the current or default schema.
* @return array all index names in the database. The names have NO schema name prefix.
*/
protected
function
findIndexNames
(
$schema
=
''
)
{
$sql
=
'SHOW TABLES'
;
if
(
$schema
!==
''
)
{
$sql
.=
' FROM '
.
$this
->
quoteSimpleIndexName
(
$schema
);
}
return
$this
->
db
->
createCommand
(
$sql
)
->
queryColumn
();
}
/**
* @return QueryBuilder the query builder for this connection.
*/
public
function
getQueryBuilder
()
{
if
(
$this
->
_builder
===
null
)
{
$this
->
_builder
=
$this
->
createQueryBuilder
();
}
return
$this
->
_builder
;
}
/**
* Determines the PDO type for the given PHP data value.
* @param mixed $data the data whose PDO type is to be determined
* @return integer the PDO type
* @see http://www.php.net/manual/en/pdo.constants.php
*/
public
function
getPdoType
(
$data
)
{
static
$typeMap
=
[
// php type => PDO type
'boolean'
=>
\PDO
::
PARAM_BOOL
,
'integer'
=>
\PDO
::
PARAM_INT
,
'string'
=>
\PDO
::
PARAM_STR
,
'resource'
=>
\PDO
::
PARAM_LOB
,
'NULL'
=>
\PDO
::
PARAM_NULL
,
];
$type
=
gettype
(
$data
);
return
isset
(
$typeMap
[
$type
])
?
$typeMap
[
$type
]
:
\PDO
::
PARAM_STR
;
}
/**
* Refreshes the schema.
* This method cleans up all cached index schemas so that they can be re-created later
* to reflect the Sphinx schema change.
*/
public
function
refresh
()
{
/** @var $cache Cache */
$cache
=
is_string
(
$this
->
db
->
schemaCache
)
?
Yii
::
$app
->
getComponent
(
$this
->
db
->
schemaCache
)
:
$this
->
db
->
schemaCache
;
if
(
$this
->
db
->
enableSchemaCache
&&
$cache
instanceof
Cache
)
{
GroupDependency
::
invalidate
(
$cache
,
$this
->
getCacheGroup
());
}
$this
->
_indexNames
=
[];
$this
->
_indexes
=
[];
}
/**
* Creates a query builder for the Sphinx.
* @return QueryBuilder query builder instance
*/
public
function
createQueryBuilder
()
...
...
@@ -45,31 +268,148 @@ class Schema extends \yii\db\mysql\Schema
}
/**
* Loads the metadata for the specified table.
* @param string $name table name
* @return TableSchema driver dependent table metadata. Null if the table does not exist.
* Quotes a string value for use in a query.
* Note that if the parameter is not a string, it will be returned without change.
* @param string $str string to be quoted
* @return string the properly quoted string
* @see http://www.php.net/manual/en/function.PDO-quote.php
*/
p
rotected
function
loadTableSchema
(
$name
)
p
ublic
function
quoteValue
(
$str
)
{
$table
=
new
TableSchema
;
$this
->
resolveTableNames
(
$table
,
$name
);
if
(
!
is_string
(
$str
))
{
return
$str
;
}
if
(
$this
->
findColumns
(
$table
))
{
return
$table
;
$this
->
db
->
open
();
if
((
$value
=
$this
->
db
->
pdo
->
quote
(
$str
))
!==
false
)
{
return
$value
;
}
else
{
// the driver doesn't support quote (e.g. oci)
return
"'"
.
addcslashes
(
str_replace
(
"'"
,
"''"
,
$str
),
"
\000\n\r\\\032
"
)
.
"'"
;
}
}
/**
* Quotes a index name for use in a query.
* If the index name contains schema prefix, the prefix will also be properly quoted.
* If the index name is already quoted or contains '(' or '{{',
* then this method will do nothing.
* @param string $name index name
* @return string the properly quoted index name
* @see quoteSimpleTableName
*/
public
function
quoteIndexName
(
$name
)
{
if
(
strpos
(
$name
,
'('
)
!==
false
||
strpos
(
$name
,
'{{'
)
!==
false
)
{
return
$name
;
}
if
(
strpos
(
$name
,
'.'
)
===
false
)
{
return
$this
->
quoteSimpleIndexName
(
$name
);
}
$parts
=
explode
(
'.'
,
$name
);
foreach
(
$parts
as
$i
=>
$part
)
{
$parts
[
$i
]
=
$this
->
quoteSimpleIndexName
(
$part
);
}
return
implode
(
'.'
,
$parts
);
}
/**
* Quotes a column name for use in a query.
* If the column name contains prefix, the prefix will also be properly quoted.
* If the column name is already quoted or contains '(', '[[' or '{{',
* then this method will do nothing.
* @param string $name column name
* @return string the properly quoted column name
* @see quoteSimpleColumnName
*/
public
function
quoteColumnName
(
$name
)
{
if
(
strpos
(
$name
,
'('
)
!==
false
||
strpos
(
$name
,
'[['
)
!==
false
||
strpos
(
$name
,
'{{'
)
!==
false
)
{
return
$name
;
}
if
((
$pos
=
strrpos
(
$name
,
'.'
))
!==
false
)
{
$prefix
=
$this
->
quoteIndexName
(
substr
(
$name
,
0
,
$pos
))
.
'.'
;
$name
=
substr
(
$name
,
$pos
+
1
);
}
else
{
return
null
;
$prefix
=
''
;
}
return
$prefix
.
$this
->
quoteSimpleColumnName
(
$name
);
}
/**
* Quotes a index name for use in a query.
* A simple index name has no schema prefix.
* @param string $name index name
* @return string the properly quoted index name
*/
public
function
quoteSimpleIndexName
(
$name
)
{
return
strpos
(
$name
,
"`"
)
!==
false
?
$name
:
"`"
.
$name
.
"`"
;
}
/**
* Quotes a column name for use in a query.
* A simple column name has no prefix.
* @param string $name column name
* @return string the properly quoted column name
*/
public
function
quoteSimpleColumnName
(
$name
)
{
return
strpos
(
$name
,
'`'
)
!==
false
||
$name
===
'*'
?
$name
:
'`'
.
$name
.
'`'
;
}
/**
* Returns the actual name of a given index name.
* This method will strip off curly brackets from the given index name
* and replace the percentage character '%' with [[Connection::indexPrefix]].
* @param string $name the index name to be converted
* @return string the real name of the given index name
*/
public
function
getRawIndexName
(
$name
)
{
if
(
strpos
(
$name
,
'{{'
)
!==
false
)
{
$name
=
preg_replace
(
'/\\{\\{(.*?)\\}\\}/'
,
'\1'
,
$name
);
return
str_replace
(
'%'
,
$this
->
db
->
tablePrefix
,
$name
);
}
else
{
return
$name
;
}
}
/**
* Extracts the PHP type from abstract DB type.
* @param ColumnSchema $column the column schema information
* @return string PHP type name
*/
protected
function
getColumnPhpType
(
$column
)
{
static
$typeMap
=
[
// abstract type => php type
'smallint'
=>
'integer'
,
'integer'
=>
'integer'
,
'bigint'
=>
'integer'
,
'boolean'
=>
'boolean'
,
'float'
=>
'double'
,
];
if
(
isset
(
$typeMap
[
$column
->
type
]))
{
if
(
$column
->
type
===
'bigint'
)
{
return
PHP_INT_SIZE
==
8
?
'integer'
:
'string'
;
}
elseif
(
$column
->
type
===
'integer'
)
{
return
PHP_INT_SIZE
==
4
?
'string'
:
'integer'
;
}
else
{
return
$typeMap
[
$column
->
type
];
}
}
else
{
return
'string'
;
}
}
/**
* Collects the metadata of
table
columns.
* @param
TableSchema $table the table
metadata
* @return boolean whether the
table
exists in the database
* Collects the metadata of
index
columns.
* @param
IndexSchema $index the index
metadata
* @return boolean whether the
index
exists in the database
* @throws \Exception if DB query fails
*/
protected
function
findColumns
(
$
table
)
protected
function
findColumns
(
$
index
)
{
$sql
=
'DESCRIBE '
.
$this
->
quoteSimple
TableName
(
$table
->
name
);
$sql
=
'DESCRIBE '
.
$this
->
quoteSimple
IndexName
(
$index
->
name
);
try
{
$columns
=
$this
->
db
->
createCommand
(
$sql
)
->
queryAll
();
}
catch
(
\Exception
$e
)
{
...
...
@@ -82,9 +422,9 @@ class Schema extends \yii\db\mysql\Schema
}
foreach
(
$columns
as
$info
)
{
$column
=
$this
->
loadColumnSchema
(
$info
);
$
table
->
columns
[
$column
->
name
]
=
$column
;
$
index
->
columns
[
$column
->
name
]
=
$column
;
if
(
$column
->
isPrimaryKey
)
{
$
table
->
primaryKey
[]
=
$column
->
name
;
$
index
->
primaryKey
[]
=
$column
->
name
;
}
}
return
true
;
...
...
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