• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

znframework / fullpack-edition / 12603164498

03 Jan 2025 07:56PM UTC coverage: 98.203% (-0.5%) from 98.707%
12603164498

push

github

zntr
Changed test.yml file.

10329 of 10518 relevant lines covered (98.2%)

16.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.42
/Internal/package-database/SQLServer/DB.php
1
<?php namespace ZN\Database\SQLServer;
2
/**
3
 * ZN PHP Web Framework
4
 * 
5
 * "Simplicity is the ultimate sophistication." ~ Da Vinci
6
 * 
7
 * @package ZN
8
 * @license MIT [http://opensource.org/licenses/MIT]
9
 * @author  Ozan UYKUN [ozan@znframework.com]
10
 */
11

12
use stdClass;
13
use ZN\Support;
14
use ZN\Security;
15
use ZN\ErrorHandling\Errors;
16
use ZN\Database\Exception\ConnectionErrorException;
17
use ZN\Database\DriverMappingAbstract;
18

19
class DB extends DriverMappingAbstract
20
{
21
    /**
22
     * Keep Operators
23
     * 
24
     * @var array
25
     */
26
    protected $operators =
27
    [
28
        'like' => '%'
29
    ];
30

31
    /**
32
     * Keep Statements
33
     * 
34
     * @var array
35
     */
36
    protected $statements =
37
    [
38
        'autoincrement' => 'IDENTITY(1,1)',
39
        'primarykey'    => 'PRIMARY KEY',
40
        'foreignkey'    => 'FOREIGN KEY',
41
        'unique'        => 'UNIQUE',
42
        'null'          => 'NULL',
43
        'notnull'       => 'NOT NULL',
44
        'exists'        => 'EXISTS',
45
        'notexists'     => 'NOT EXISTS',
46
        'constraint'    => 'CONSTRAINT',
47
        'default'       => 'DEFAULT'
48
    ];
49

50
    /**
51
     * Keep Variable Types
52
     * 
53
     * @var array
54
     */
55
    protected $variableTypes =
56
    [
57
        'int'           => ':INT',
58
        'smallint'      => ':SMALLINT',
59
        'tinyint'       => ':TINYINT',
60
        'mediumint'     => ':INT',
61
        'bigint'        => ':BIGINT',
62
        'decimal'       => 'DECIMAL',
63
        'double'        => 'FLOAT',
64
        'float'         => 'FLOAT',
65
        'char'          => 'CHAR',
66
        'varchar'       => 'VARCHAR',
67
        'tinytext'      => ':VARCHAR(255)',
68
        'text'          => ':VARCHAR(65535)',
69
        'mediumtext'    => ':VARCHAR(16277215)',
70
        'longtext'      => ':VARCHAR(16277215)',
71
        'date'          => ':DATE',
72
        'datetime'      => ':DATETIME',
73
        'time'          => ':TIME',
74
        'timestamp'     => ':TIMESTAMP'
75
    ];
76

77
    /**
78
     * Magic Constructor
79
     */
80
    public function __construct()
81
    {
82
        Support::func('sqlsrv_connect', 'SQL Server');
6✔
83
    }
6✔
84

85
    /**
86
     * Connection
87
     * 
88
     * @param array $config = []
89
     */
90
    public function connect($config = [])
91
    {
92
        $this->config = $config;
6✔
93

94
        $server =   ( ! empty($this->config['server']) )
6✔
95
                    ? $this->config['server'] // @codeCoverageIgnore
96
                    : $this->config['host'];
6✔
97

98
        if( ! empty($this->config['port']) )
6✔
99
        {
100
            $server .= ', '.$this->config['port'];
5✔
101
        }
102

103
        $charset = $this->config['charset'] === 'utf8' ? 'utf-8' : $this->config['charset'];
6✔
104

105
        $connection = 
106
        [
107
            'UID'                   => $this->config['user'],
6✔
108
            'PWD'                   => $this->config['password'],
6✔
109
            'Database'              => $this->config['database'],
6✔
110
            'ConnectionPooling'     => $this->config['pconnect'] === true ? 1 : 0,
6✔
111
            'CharacterSet'          => $charset ?: 'utf-8',
6✔
112
            'Encrypt'               => $this->config['encode'] ?: false,
6✔
113
            'ReturnDatesAsStrings'  => 1
6✔
114
        ];
115

116
        $this->connect = @sqlsrv_connect($server, $connection);
6✔
117

118
        if( empty($this->connect) )
6✔
119
        {
120
            throw new ConnectionErrorException(NULL, sqlsrv_errors(SQLSRV_ERR_ERRORS)[0]['message']); // @codeCoverageIgnore
121
        }
122
    }
×
123

124
    /**
125
     * Execute
126
     * 
127
     * @param string $query
128
     * @param array  $security = NULL
129
     * 
130
     * @return bool
131
     */
132
    public function exec($query, $security = NULL)
133
    {
134
        if( empty($query) )
×
135
        {
136
            return false; // @codeCoverageIgnore
137
        }
138

139
        return sqlsrv_query($this->connect, $query);
×
140
    }
141

142
    /**
143
     * Multiple Queries
144
     * 
145
     * @param string $query
146
     * @param array  $security = NULL
147
     * 
148
     * @return bool
149
     */
150
    public function multiQuery($query, $security = NULL)
151
    {
152
        return (bool) $this->query($query, $security);
×
153
    }
154

155
    /**
156
     * Query
157
     * 
158
     * @param string $query
159
     * @param array  $security = NULL
160
     * 
161
     * @return bool
162
     */
163
    public function query($query, $security = NULL)
164
    {
165
        return $this->query = $this->exec($query);
×
166
    }
167

168
    /**
169
     * Start Transaction Query
170
     * 
171
     * @return bool
172
     */
173
    public function transStart()
174
    {
175
        return sqlsrv_begin_transaction($this->connect);
×
176
    }
177

178
    /**
179
     * Rollback Transaction Query
180
     * 
181
     * @return bool
182
     */
183
    public function transRollback()
184
    {
185
        return sqlsrv_rollback($this->connect);
×
186
    }
187

188
    /**
189
     * Commit Transaction Query
190
     * 
191
     * @return bool
192
     */
193
    public function transCommit()
194
    {
195
        return sqlsrv_commit($this->connect);
×
196
    }
197

198
    /**
199
     * Insert Last ID
200
     * 
201
     * @return int|false
202
     */
203
    public function insertID()
204
    {
205
        $this->query('SELECT @@IDENTITY AS insert_id');
×
206
        
207
        return $this->fetchAssoc()['insert_id'];
×
208
    }
209

210
    /**
211
     * Returns column data
212
     * 
213
     * @param string $column
214
     * 
215
     * @return array|object
216
     */
217
    public function columnData($col = '')
218
    {
219
        if( empty($this->query) )
×
220
        {
221
            return false; // @codeCoverageIgnore
222
        }
223

224
        $columns = [];
×
225

226
        foreach( sqlsrv_field_metadata($this->query) as $field )
×
227
        {
228
            $fieldName = $field['Name'];
×
229

230
            $columns[$fieldName]             = new stdClass();
×
231
            $columns[$fieldName]->name       = $fieldName;
×
232
            $columns[$fieldName]->type       = $field['Type'];
×
233
            $columns[$fieldName]->maxLength  = $field['Size'];
×
234
            $columns[$fieldName]->primaryKey = NULL;
×
235
            $columns[$fieldName]->default    = NULL;
×
236
        }
237

238
        return $columns[$col] ?? $columns;
×
239
    }
240

241
    /**
242
     * Numrows
243
     * 
244
     * @return int
245
     */
246
    public function numRows()
247
    {
248
        $this->query('select @@RowCount');
×
249

250
        return $this->fetchRow()[0] ?? false;
×
251
    }
252

253
    /**
254
     * Returns columns
255
     * 
256
     * @return array
257
     */
258
    public function columns()
259
    {
260
        if( empty($this->query) )
×
261
        {
262
            return []; // @codeCoverageIgnore
263
        }
264

265
        $columns = [];
×
266

267
        $getFieldData = sqlsrv_field_metadata($this->query);
×
268

269
        foreach( $getFieldData as $field )
×
270
        {
271
            $columns[] = $field['Name'];
×
272
        }
273

274
        return $columns;
×
275
    }
276

277
    /**
278
     * Numfields
279
     * 
280
     * @return int
281
     */
282
    public function numFields()
283
    {
284
        if( ! empty($this->query) )
×
285
        {
286
            return sqlsrv_num_fields($this->query);
×
287
        }
288
        else
289
        {
290
            return 0; // @codeCoverageIgnore
291
        }
292
    }
293

294
    /**
295
     * Real Escape String 
296
     * 
297
     * @param string $data
298
     * 
299
     * @return string|false
300
     */
301
    public function realEscapeString($data)
302
    {
303
        return Security\Injection::escapeStringEncode($data);
×
304
    }
305

306
    /**
307
     * Returns a string description of the last error.
308
     * 
309
     * @return string|false
310
     */
311
    public function error()
312
    {
313
        if( ! empty($this->connect) )
×
314
        {
315
            $error = sqlsrv_errors(SQLSRV_ERR_ERRORS)[0] ?? [];
×
316

317
            return ! empty($error['code']) ? ($error['code'] === 15477 ? false : ($error['message'] ?: false)) : false;
×
318
        }
319
        else
320
        {
321
            return false; // @codeCoverageIgnore
322
        }
323
    }
324

325
    /**
326
     * Fetch a result row as an associative, a numeric array, or both
327
     * 
328
     * @return mixed
329
     */
330
    public function fetchArray()
331
    {
332
        if( ! empty($this->query) )
×
333
        {
334
            return sqlsrv_fetch_array($this->query, SQLSRV_FETCH_BOTH);
×
335
        }
336
        else
337
        {
338
            return []; // @codeCoverageIgnore
339
        }
340
    }
341

342
    /**
343
     * Fetch a result row as an associative array
344
     * 
345
     * @return mixed
346
     */
347
    public function fetchAssoc()
348
    {
349
        if( ! empty($this->query) )
×
350
        {
351
            return sqlsrv_fetch_array($this->query, SQLSRV_FETCH_ASSOC);
×
352
        }
353
        else
354
        {
355
            return []; // @codeCoverageIgnore
356
        }
357
    }
358

359
    /**
360
     * Get a result row as an enumerated array
361
     * 
362
     * @return mixed
363
     */
364
    public function fetchRow()
365
    {
366
        if( ! empty($this->query) )
×
367
        {
368
            return sqlsrv_fetch_array($this->query, SQLSRV_FETCH_NUMERIC);
×
369
        }
370
        else
371
        {
372
            return []; // @codeCoverageIgnore
373
        }
374
    }
375

376
    /**
377
     * Gets the number of affected rows in a previous MySQL operation
378
     * 
379
     * @return int
380
     */
381
    public function affectedRows()
382
    {
383
        if( ! empty($this->query) )
×
384
        {
385
            return sqlsrv_rows_affected($this->query);
×
386
        }
387
        else
388
        {
389
            return 0; // @codeCoverageIgnore
390
        }
391
    }
392

393
    /**
394
     * Returns the version of the MySQL server as an integer
395
     * 
396
     * @return int
397
     */
398
    public function version()
399
    {
400
        if( ! empty($this->connect) )
×
401
        {
402
            return sqlsrv_server_info($this->connect)['SQLServerVersion'];
×
403
        }
404
        else
405
        {
406
            return false; // @codeCoverageIgnore
407
        }
408
    }
409

410
    /**
411
     * Limit
412
     * 
413
     * @param int $start = NULL
414
     * @param int $limit = 0
415
     * 
416
     * @return DB
417
     * 
418
     * @codeCoverageIgnore
419
     */
420
    public function limit($start = NULL, int $limit = 0)
421
    {
422
        if( $limit === 0 )
423
        {
424
            $limit = $start;
425
            $start = 0;
426
        }
427

428
        return ' OFFSET ' . $start . ' ROWS FETCH NEXT ' . $limit . ' ROWS ONLY';
429
    }
430

431
    /**
432
     * Protected Clean Limit
433
     * 
434
     * @codeCoverageIgnore
435
     */
436
    public function cleanLimit($data)
437
    {
438
        return preg_replace('/OFFSET\s+[0-9]+\s+ROWS\sFETCH\sNEXT\s+[0-9]+\s+ROWS\sONLY/xi', '', $data);
439
    }
440

441
    /**
442
     * Protected Get Limit Values
443
     * 
444
     * @codeCoverageIgnore
445
     */
446
    public function getLimitValues($data)
447
    {
448
        preg_match('/OFFSET\s+(?<start>[0-9]+)\s+ROWS\sFETCH\sNEXT\s+(?<limit>[0-9]+)\s+ROWS\sONLY/xi', $data ?? '', $match);
449

450
        return $match;
451
    }
452
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc