2010-04-21 12:01:32 +00:00
< ? php
/**
* @ author Jakub Cernohuby
* @ author Vladimir Stastka
* @ author Jakub Vrana
*/
$possible_drivers [] = " SQLSRV " ;
$possible_drivers [] = " MSSQL " ;
if ( extension_loaded ( " sqlsrv " ) || extension_loaded ( " mssql " )) {
$drivers [ " mssql " ] = " MS SQL " ;
}
if ( isset ( $_GET [ " mssql " ])) {
define ( " DRIVER " , " mssql " );
if ( extension_loaded ( " sqlsrv " )) {
class Min_DB {
var $extension = " sqlsrv " , $_link , $_result , $server_info , $affected_rows , $error ;
function _get_error () {
$this -> error = " " ;
foreach ( sqlsrv_errors () as $error ) {
$this -> error .= " $error[message] \n " ;
}
$this -> error = rtrim ( $this -> error );
}
function connect ( $server , $username , $password ) {
$this -> _link = @ sqlsrv_connect ( $server , array ( " UID " => $username , " PWD " => $password ));
if ( $this -> _link ) {
$info = sqlsrv_server_info ( $this -> _link );
$this -> server_info = $info [ 'SQLServerVersion' ];
} else {
$this -> _get_error ();
}
return ( bool ) $this -> _link ;
}
function quote ( $string ) {
return " ' " . str_replace ( " ' " , " '' " , $string ) . " ' " ;
}
function select_db ( $database ) {
return $this -> query ( " USE $database " );
}
function query ( $query , $unbuffered = false ) {
$result = sqlsrv_query ( $this -> _link , $query ); //! , array(), ($unbuffered ? array() : array("Scrollable" => "keyset"))
if ( ! $result ) {
$this -> _get_error ();
return false ;
}
return $this -> store_result ( $result );
}
function multi_query ( $query ) {
$this -> _result = sqlsrv_query ( $this -> _link , $query );
if ( ! $this -> _result ) {
$this -> _get_error ();
return false ;
}
return true ;
}
function store_result ( $result = null ) {
if ( ! $result ) {
$result = $this -> _result ;
}
if ( sqlsrv_field_metadata ( $result )) {
return new Min_Result ( $result );
}
$this -> affected_rows = sqlsrv_rows_affected ( $result );
return true ;
}
function next_result () {
return sqlsrv_next_result ( $this -> _result );
}
function result ( $query , $field = 0 ) {
$result = $this -> query ( $query );
if ( ! is_object ( $result )) {
return false ;
}
$row = $result -> fetch_row ();
return $row [ $field ];
}
}
class Min_Result {
var $_result , $_offset = 0 , $_fields , $num_rows ;
function Min_Result ( $result ) {
$this -> _result = $result ;
$this -> num_rows = sqlsrv_has_rows ( $result ); //! sqlsrv_num_rows($result)
}
function _convert ( $row ) {
foreach (( array ) $row as $key => $val ) {
if ( is_a ( $val , 'DateTime' )) {
$row [ $key ] = $val -> format ( " Y-m-d H:i:s " );
}
//! stream
}
return $row ;
}
function fetch_assoc () {
return $this -> _convert ( sqlsrv_fetch_array ( $this -> _result , SQLSRV_FETCH_ASSOC , SQLSRV_SCROLL_NEXT ));
}
function fetch_row () {
return $this -> _convert ( sqlsrv_fetch_array ( $this -> _result , SQLSRV_FETCH_NUMERIC , SQLSRV_SCROLL_NEXT ));
}
function fetch_field () {
if ( ! $this -> _fields ) {
$this -> _fields = sqlsrv_field_metadata ( $this -> _result );
}
$field = $this -> _fields [ $this -> _offset ++ ];
$return = new stdClass ;
$return -> name = $field [ " Name " ];
$return -> orgname = $field [ " Name " ];
$return -> type = ( $field [ " Type " ] == 1 ? 254 : 0 );
return $return ;
}
2010-04-23 09:04:05 +00:00
function seek ( $offset ) {
for ( $i = 0 ; $i < $offset ; $i ++ ) {
sqlsrv_fetch ( $this -> _result ); // SQLSRV_SCROLL_ABSOLUTE added in sqlsrv 1.1
}
}
2010-04-21 12:01:32 +00:00
function __destruct () {
sqlsrv_free_stmt ( $this -> _result );
}
}
} elseif ( extension_loaded ( " mssql " )) {
class Min_DB {
var $extension = " MSSQL " , $_link , $_result , $server_info , $affected_rows , $error ;
function connect ( $server , $username , $password ) {
$this -> _link = @ mssql_connect ( $server , $username , $password );
if ( $this -> _link ) {
$result = $this -> query ( " SELECT SERVERPROPERTY('ProductLevel'), SERVERPROPERTY('Edition') " );
$row = $result -> fetch_row ();
$this -> server_info = $this -> result ( " sp_server_info 2 " , 2 ) . " [ $row[0] ] $row[1] " ;
} else {
$this -> error = mssql_get_last_message ();
}
return ( bool ) $this -> _link ;
}
function quote ( $string ) {
return " ' " . str_replace ( " ' " , " '' " , $string ) . " ' " ;
}
function select_db ( $database ) {
return mssql_select_db ( $database );
}
function query ( $query , $unbuffered = false ) {
$result = mssql_query ( $query , $this -> _link ); //! $unbuffered
if ( ! $result ) {
$this -> error = mssql_get_last_message ();
return false ;
}
if ( $result === true ) {
$this -> affected_rows = mssql_rows_affected ( $this -> _link );
return true ;
}
return new Min_Result ( $result );
}
function multi_query ( $query ) {
return $this -> _result = $this -> query ( $query );
}
function store_result () {
return $this -> _result ;
}
function next_result () {
return mssql_next_result ( $this -> _result );
}
function result ( $query , $field = 0 ) {
$result = $this -> query ( $query );
if ( ! is_object ( $result )) {
return false ;
}
return mssql_result ( $result -> _result , 0 , $field );
}
}
class Min_Result {
var $_result , $_offset = 0 , $_fields , $num_rows ;
function Min_Result ( $result ) {
$this -> _result = $result ;
$this -> num_rows = mssql_num_rows ( $result );
}
function fetch_assoc () {
return mssql_fetch_assoc ( $this -> _result );
}
function fetch_row () {
return mssql_fetch_row ( $this -> _result );
}
function num_rows () {
return mssql_num_rows ( $this -> _result );
}
function fetch_field () {
$return = mssql_fetch_field ( $this -> _result );
$return -> orgtable = $return -> table ;
$return -> orgname = $return -> name ;
return $return ;
}
2010-04-23 09:04:05 +00:00
function seek ( $offset ) {
mssql_data_seek ( $this -> _result , $offset );
}
2010-04-21 12:01:32 +00:00
function __destruct () {
mssql_free_result ( $this -> _result );
}
}
}
function idf_escape ( $idf ) {
return " [ " . str_replace ( " ] " , " ]] " , $idf ) . " ] " ;
}
function connect () {
global $adminer ;
$connection = new Min_DB ;
$credentials = $adminer -> credentials ();
if ( $connection -> connect ( $credentials [ 0 ], $credentials [ 1 ], $credentials [ 2 ])) {
return $connection ;
}
return $connection -> error ;
}
function get_databases () {
return get_vals ( " EXEC sp_databases " );
}
function limit ( $query , $limit , $offset = 0 ) {
2010-04-23 09:04:05 +00:00
return ( isset ( $limit ) ? " TOP ( " . ( $limit + $offset ) . " ) " : " " ) . " $query " ; // seek later
2010-04-21 12:01:32 +00:00
}
2010-04-23 09:04:05 +00:00
function limit1 ( $query ) {
2010-04-21 12:01:32 +00:00
return limit ( $query , 1 );
}
function db_collation ( $db , $collations ) {
global $connection ;
return $connection -> result ( " SELECT collation_name FROM sys.databases WHERE name = " . $connection -> quote ( $db ));
}
function engines () {
return array ();
}
function logged_user () {
global $connection ;
return $connection -> result ( " SELECT SUSER_NAME() " );
}
function tables_list () {
return get_key_vals ( " SELECT TABLE_NAME, TABLE_TYPE FROM information_schema.TABLES " );
}
function count_tables ( $databases ) {
global $connection ;
$return = array ();
foreach ( $databases as $db ) {
$connection -> select_db ( $db );
$return [ $db ] = $connection -> result ( " SELECT COUNT(*) FROM information_schema.TABLES " );
}
return $return ;
}
function table_status ( $name = " " ) {
global $connection ;
$return = array ();
$result = $connection -> query ( " SELECT TABLE_NAME AS Name, TABLE_TYPE AS Engine FROM information_schema.TABLES " . ( $name != " " ? " WHERE TABLE_NAME = " . $connection -> quote ( $name ) : " " ));
while ( $row = $result -> fetch_assoc ()) {
if ( $name != " " ) {
return $row ;
}
$return [ $row [ " Name " ]] = $row ;
}
return $return ;
}
function fk_support ( $table_status ) {
return true ;
}
function fields ( $table ) {
global $connection ;
$return = array ();
2010-04-23 09:04:05 +00:00
$result = $connection -> query ( " SELECT i.*, c.is_identity
FROM information_schema . COLUMNS i
JOIN sys . columns c ON OBJECT_NAME ( c . object_id ) = i . TABLE_NAME AND c . name = i . COLUMN_NAME
WHERE i . TABLE_NAME = " . $connection->quote ( $table )
);
2010-04-21 12:01:32 +00:00
while ( $row = $result -> fetch_assoc ()) {
$return [ $row [ " COLUMN_NAME " ]] = array (
" field " => $row [ " COLUMN_NAME " ],
" full_type " => $row [ " DATA_TYPE " ],
" type " => $row [ " DATA_TYPE " ],
" length " => $row [ " CHARACTER_MAXIMUM_LENGTH " ], //! NUMERIC_, DATETIME_?
" default " => $row [ " COLUMN_DEFAULT " ],
" null " => ( $row [ " IS_NULLABLE " ] == " YES " ),
2010-04-23 09:04:05 +00:00
" auto_increment " => $row [ " is_identity " ],
2010-04-21 12:01:32 +00:00
" collation " => $row [ " COLLATION_NAME " ],
" privileges " => array ( " insert " => 1 , " select " => 1 , " update " => 1 ),
2010-04-23 09:04:05 +00:00
" primary " => $row [ " is_identity " ], //! or indexes.is_primary_key
2010-04-21 12:01:32 +00:00
);
}
return $return ;
}
function indexes ( $table , $connection2 = null ) {
global $connection ;
if ( ! is_object ( $connection2 )) {
$connection2 = $connection ;
}
$return = array ();
// sp_statistics doesn't return information about primary key
$result = $connection2 -> query ( " SELECT indexes.name, key_ordinal, is_unique, is_primary_key, columns.name AS column_name
FROM sys . indexes
INNER JOIN sys . index_columns ON indexes . object_id = index_columns . object_id AND indexes . index_id = index_columns . index_id
INNER JOIN sys . columns ON index_columns . object_id = columns . object_id AND index_columns . column_id = columns . column_id
2010-04-22 14:38:05 +00:00
WHERE OBJECT_NAME ( indexes . object_id ) = " . $connection2->quote ( $table )
);
2010-04-21 12:01:32 +00:00
if ( $result ) {
while ( $row = $result -> fetch_assoc ()) {
$return [ $row [ " name " ]][ " type " ] = ( $row [ " is_primary_key " ] ? " PRIMARY " : ( $row [ " is_unique " ] ? " UNIQUE " : " INDEX " ));
2010-04-22 14:38:05 +00:00
$return [ $row [ " name " ]][ " lengths " ] = array ();
2010-04-21 12:01:32 +00:00
$return [ $row [ " name " ]][ " columns " ][ $row [ " key_ordinal " ]] = $row [ " column_name " ];
}
}
return $return ;
}
function collations () {
$return = array ();
foreach ( get_vals ( " SELECT name FROM fn_helpcollations() " ) as $collation ) {
$return [ ereg_replace ( " _.* " , " " , $collation )][] = $collation ;
}
return $return ;
}
function information_schema ( $db ) {
return false ;
}
function error () {
global $connection ;
2010-04-22 14:38:05 +00:00
return nl_br ( h ( preg_replace ( '~^(\\[[^]]*])+~m' , '' , $connection -> error )));
2010-04-21 12:01:32 +00:00
}
function exact_value ( $val ) {
global $connection ;
return $connection -> quote ( $val );
}
2010-04-22 23:02:28 +00:00
function create_database ( $db , $collation ) {
return queries ( " CREATE DATABASE " . idf_escape ( $db ) . ( $collation ? " COLLATE " . idf_escape ( $collation ) : " " ));
}
function drop_databases ( $databases ) {
return queries ( " DROP DATABASE " . implode ( " , " , array_map ( 'idf_escape' , $databases )));
}
2010-04-21 12:01:32 +00:00
function rename_database ( $name , $collation ) {
if ( $collation ) {
queries ( " ALTER DATABASE " . idf_escape ( DB ) . " COLLATE " . idf_escape ( $collation ));
}
2010-04-23 09:04:05 +00:00
queries ( " ALTER DATABASE " . idf_escape ( DB ) . " MODIFY NAME = " . idf_escape ( $name ));
return true ; //! false negative "The database name 'test2' has been set."
2010-04-21 12:01:32 +00:00
}
function auto_increment () {
return " IDENTITY " ;
}
2010-04-23 09:04:05 +00:00
function insert_into ( $table , $set ) {
return queries ( " INSERT INTO " . idf_escape ( $table ) . ( $set ? " ( " . implode ( " , " , array_keys ( $set )) . " ) \n VALUES ( " . implode ( " , " , $set ) . " ) " : " DEFAULT VALUES " ));
}
2010-04-21 12:01:32 +00:00
function explain ( $connection , $query ) {
$connection -> query ( " SET SHOWPLAN_ALL ON " );
$return = $connection -> query ( $query );
$connection -> query ( " SET SHOWPLAN_ALL OFF " ); // connection is used also for indexes
return $return ;
}
2010-04-22 14:38:05 +00:00
function foreign_keys ( $table ) {
global $connection ;
$result = $connection -> query ( " EXEC sp_fkeys @fktable_name = " . $connection -> quote ( $table ));
$return = array ();
while ( $row = $result -> fetch_assoc ()) {
$foreign_key = & $return [ $row [ " FK_NAME " ]];
$foreign_key [ " table " ] = $row [ " PKTABLE_NAME " ];
$foreign_key [ " source " ][] = $row [ " FKCOLUMN_NAME " ];
$foreign_key [ " target " ][] = $row [ " PKCOLUMN_NAME " ];
}
return $return ;
}
function truncate_tables ( $tables ) {
foreach ( $tables as $table ) {
if ( ! queries ( " TRUNCATE TABLE " . idf_escape ( $table ))) {
return false ;
}
}
return true ;
}
function drop_views ( $views ) {
return queries ( " DROP VIEW " . implode ( " , " , array_map ( 'idf_escape' , $views )));
}
function drop_tables ( $tables ) {
return queries ( " DROP TABLE " . implode ( " , " , array_map ( 'idf_escape' , $tables )));
}
function trigger ( $name ) {
global $connection ;
$result = $connection -> query ( " SELECT s.name [Trigger],
CASE WHEN OBJECTPROPERTY ( s . id , 'ExecIsInsertTrigger' ) = 1 THEN 'INSERT' WHEN OBJECTPROPERTY ( s . id , 'ExecIsUpdateTrigger' ) = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY ( s . id , 'ExecIsDeleteTrigger' ) = 1 THEN 'DELETE' END [ Event ],
CASE WHEN OBJECTPROPERTY ( s . id , 'ExecIsInsteadOfTrigger' ) = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [ Timing ],
2010-04-22 15:53:42 +00:00
c . text
2010-04-22 14:38:05 +00:00
FROM sysobjects s
JOIN syscomments c ON s . id = c . id
WHERE s . xtype = 'TR' AND s . name = " . $connection->quote ( $name )
);
2010-04-22 15:53:42 +00:00
$row = $result -> fetch_assoc ();
$row [ " Statement " ] = preg_replace ( '~^.+\\s+AS\\s+~isU' , '' , $row [ " text " ]); //! identifiers, comments
return $row ;
2010-04-22 14:38:05 +00:00
}
function triggers ( $table ) {
global $connection ;
$return = array ();
$result = $connection -> query ( " SELECT sys1.name,
CASE WHEN OBJECTPROPERTY ( sys1 . id , 'ExecIsInsertTrigger' ) = 1 THEN 'INSERT' WHEN OBJECTPROPERTY ( sys1 . id , 'ExecIsUpdateTrigger' ) = 1 THEN 'UPDATE' WHEN OBJECTPROPERTY ( sys1 . id , 'ExecIsDeleteTrigger' ) = 1 THEN 'DELETE' END [ Event ],
CASE WHEN OBJECTPROPERTY ( sys1 . id , 'ExecIsInsteadOfTrigger' ) = 1 THEN 'INSTEAD OF' ELSE 'AFTER' END [ Timing ]
FROM sysobjects sys1
JOIN sysobjects sys2 ON sys1 . parent_obj = sys2 . id
WHERE sys1 . xtype = 'TR' AND sys2 . name = " . $connection->quote ( $table )
);
while ( $row = $result -> fetch_assoc ()) {
$return [ $row [ " name " ]] = array ( $row [ " Timing " ], $row [ " Event " ]);
}
return $return ;
}
2010-04-22 15:53:42 +00:00
function trigger_options () {
return array (
" Timing " => array ( " AFTER " , " INSTEAD OF " ),
" Type " => array ( " AS " ),
);
}
2010-04-21 12:01:32 +00:00
function support ( $feature ) {
return ereg ( '^(view|routine|trigger)$' , $feature );
}
$driver = " mssql " ;
$types = array ();
$structured_types = array ();
foreach ( array (
lang ( 'Numbers' ) => array ( " tinyint " => 3 , " smallint " => 5 , " int " => 10 , " bigint " => 20 , " bit " => 1 , " decimal " => 0 , " real " => 12 , " float " => 53 , " smallmoney " => 10 , " money " => 20 ),
lang ( 'Date and time' ) => array ( " date " => 10 , " smalldatetime " => 19 , " datetime " => 19 , " datetime2 " => 19 , " time " => 8 , " datetimeoffset " => 10 ),
lang ( 'Strings' ) => array ( " char " => 8000 , " varchar " => 8000 , " text " => 2147483647 , " nchar " => 4000 , " nvarchar " => 4000 , " ntext " => 1073741823 ),
lang ( 'Binary' ) => array ( " binary " => 8000 , " varbinary " => 8000 , " image " => 2147483647 ),
) as $key => $val ) {
$types += $val ;
$structured_types [ $key ] = array_keys ( $val );
}
$unsigned = array ();
$operators = array ( " = " , " < " , " > " , " <= " , " >= " , " != " , " LIKE " , " LIKE %% " , " IN " , " IS NULL " , " NOT LIKE " , " NOT IN " , " IS NOT NULL " );
$functions = array ( " len " , " lower " , " round " , " upper " );
$grouping = array ( " avg " , " count " , " count distinct " , " max " , " min " , " sum " );
$edit_functions = array (
array (
" date|time " => " getdate " ,
), array (
" int|decimal|real|float|money|datetime " => " +/- " ,
" char|text " => " + " ,
)
);
}