]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/drivers/adodb-mssql_n.inc.php
Upgrade adodb
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / drivers / adodb-mssql_n.inc.php
1 <?php
2
3 /// $Id $
4
5 ///////////////////////////////////////////////////////////////////////////
6 //                                                                       //
7 // NOTICE OF COPYRIGHT                                                   //
8 //                                                                       //
9 // ADOdb  - Database Abstraction Library for PHP                         //
10 //          http://adodb.sourceforge.net/                                //
11 //                                                                       //
12 // Copyright (c) 2000-2012 John Lim (jlim\@natsoft.com.my)               //
13 //          All rights reserved.                                         //
14 //          Released under both BSD license and LGPL library license.    //
15 //          Whenever there is any discrepancy between the two licenses,  //
16 //          the BSD license will take precedence                         //
17 //                                                                       //
18 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
19 //          http://moodle.com                                            //
20 //                                                                       //
21 // Copyright (C) 2001-3001 Martin Dougiamas        http://dougiamas.com  //
22 //           (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com  //
23 //                                                                       //
24 // This program is free software; you can redistribute it and/or modify  //
25 // it under the terms of the GNU General Public License as published by  //
26 // the Free Software Foundation; either version 2 of the License, or     //
27 // (at your option) any later version.                                   //
28 //                                                                       //
29 // This program is distributed in the hope that it will be useful,       //
30 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
31 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
32 // GNU General Public License for more details:                          //
33 //                                                                       //
34 //          http://www.gnu.org/copyleft/gpl.html                         //
35 //                                                                       //
36 ///////////////////////////////////////////////////////////////////////////
37
38 /**
39 *  MSSQL Driver with auto-prepended "N" for correct unicode storage
40 *  of SQL literal strings. Intended to be used with MSSQL drivers that
41 *  are sending UCS-2 data to MSSQL (FreeTDS and ODBTP) in order to get
42 *  true cross-db compatibility from the application point of view.
43 */
44
45 // security - hide paths
46 if (!defined('ADODB_DIR')) die();
47
48 // one useful constant
49 if (!defined('SINGLEQUOTE')) define('SINGLEQUOTE', "'");
50
51 include_once(ADODB_DIR.'/drivers/adodb-mssql.inc.php');
52
53 class ADODB_mssql_n extends ADODB_mssql {
54         var $databaseType = "mssql_n";
55         
56         function ADODB_mssqlpo()
57         {
58                 ADODB_mssql::ADODB_mssql();
59         }
60
61         function _query($sql,$inputarr=false)
62         {
63         $sql = $this->_appendN($sql);
64                 return ADODB_mssql::_query($sql,$inputarr);
65         }
66
67     /**
68      * This function will intercept all the literals used in the SQL, prepending the "N" char to them
69      * in order to allow mssql to store properly data sent in the correct UCS-2 encoding (by freeTDS
70      * and ODBTP) keeping SQL compatibility at ADOdb level (instead of hacking every project to add
71      * the "N" notation when working against MSSQL.
72      *
73      * Note that this hack only must be used if ALL the char-based columns in your DB are of type nchar,
74      * nvarchar and ntext
75      */
76     function _appendN($sql) {
77
78         $result = $sql;
79
80     /// Check we have some single quote in the query. Exit ok.
81         if (strpos($sql, SINGLEQUOTE) === false) {
82             return $sql;
83         }
84
85     /// Check we haven't an odd number of single quotes (this can cause problems below
86     /// and should be considered one wrong SQL). Exit with debug info.
87         if ((substr_count($sql, SINGLEQUOTE) & 1)) {
88             if ($this->debug) {
89                 ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Wrong number of quotes (odd)");
90             }
91             return $sql;
92         }
93
94     /// Check we haven't any backslash + single quote combination. It should mean wrong
95     /// backslashes use (bad magic_quotes_sybase?). Exit with debug info.
96         $regexp = '/(\\\\' . SINGLEQUOTE . '[^' . SINGLEQUOTE . '])/';
97         if (preg_match($regexp, $sql)) {
98             if ($this->debug) {
99                 ADOConnection::outp("{$this->databaseType} internal transformation: not converted. Found bad use of backslash + single quote");
100             }
101             return $sql;
102         }
103
104     /// Remove pairs of single-quotes
105         $pairs = array();
106         $regexp = '/(' . SINGLEQUOTE . SINGLEQUOTE . ')/';
107         preg_match_all($regexp, $result, $list_of_pairs);
108         if ($list_of_pairs) {
109             foreach (array_unique($list_of_pairs[0]) as $key=>$value) {
110                 $pairs['<@#@#@PAIR-'.$key.'@#@#@>'] = $value;
111             }
112             if (!empty($pairs)) {
113                 $result = str_replace($pairs, array_keys($pairs), $result);
114             }
115         }
116
117     /// Remove the rest of literals present in the query
118         $literals = array();
119         $regexp = '/(N?' . SINGLEQUOTE . '.*?' . SINGLEQUOTE . ')/is';
120         preg_match_all($regexp, $result, $list_of_literals);
121         if ($list_of_literals) {
122             foreach (array_unique($list_of_literals[0]) as $key=>$value) {
123                 $literals['<#@#@#LITERAL-'.$key.'#@#@#>'] = $value;
124             }
125             if (!empty($literals)) {
126                 $result = str_replace($literals, array_keys($literals), $result);
127             }
128         }
129
130
131     /// Analyse literals to prepend the N char to them if their contents aren't numeric
132         if (!empty($literals)) {
133             foreach ($literals as $key=>$value) {
134                 if (!is_numeric(trim($value, SINGLEQUOTE))) {
135                 /// Non numeric string, prepend our dear N
136                     $literals[$key] = 'N' . trim($value, 'N'); //Trimming potentially existing previous "N"
137                 }
138             }
139         }
140
141     /// Re-apply literals to the text
142         if (!empty($literals)) {
143             $result = str_replace(array_keys($literals), $literals, $result);
144         }
145
146     /// Any pairs followed by N' must be switched to N' followed by those pairs
147     /// (or strings beginning with single quotes will fail)
148         $result = preg_replace("/((<@#@#@PAIR-(\d+)@#@#@>)+)N'/", "N'$1", $result);
149
150     /// Re-apply pairs of single-quotes to the text
151         if (!empty($pairs)) {
152             $result = str_replace(array_keys($pairs), $pairs, $result);
153         }
154
155     /// Print transformation if debug = on
156         if ($result != $sql && $this->debug) {
157             ADOConnection::outp("{$this->databaseType} internal transformation:<br>{$sql}<br>to<br>{$result}");
158         }
159
160         return $result;
161     }
162 }
163
164 class ADORecordset_mssql_n extends ADORecordset_mssql {
165         var $databaseType = "mssql_n";
166         function ADORecordset_mssql_n($id,$mode=false)
167         {
168                 $this->ADORecordset_mssql($id,$mode);
169         }
170 }
171 ?>