summaryrefslogtreecommitdiff
path: root/www/wiki/includes/libs/rdbms/database/resultwrapper/MssqlResultWrapper.php
blob: ba79be14f0f22f4d4768f731208a80e6c040f020 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php

namespace Wikimedia\Rdbms;

use stdClass;

class MssqlResultWrapper extends ResultWrapper {
	/** @var int|null */
	private $seekTo = null;

	/**
	 * @return stdClass|bool
	 */
	public function fetchObject() {
		$res = $this->result;

		if ( $this->seekTo !== null ) {
			$result = sqlsrv_fetch_object( $res, stdClass::class, [],
				SQLSRV_SCROLL_ABSOLUTE, $this->seekTo );
			$this->seekTo = null;
		} else {
			$result = sqlsrv_fetch_object( $res );
		}

		// Return boolean false when there are no more rows instead of null
		if ( $result === null ) {
			return false;
		}

		return $result;
	}

	/**
	 * @return array|bool
	 */
	public function fetchRow() {
		$res = $this->result;

		if ( $this->seekTo !== null ) {
			$result = sqlsrv_fetch_array( $res, SQLSRV_FETCH_BOTH,
				SQLSRV_SCROLL_ABSOLUTE, $this->seekTo );
			$this->seekTo = null;
		} else {
			$result = sqlsrv_fetch_array( $res );
		}

		// Return boolean false when there are no more rows instead of null
		if ( $result === null ) {
			return false;
		}

		return $result;
	}

	/**
	 * @param int $row
	 * @return bool
	 */
	public function seek( $row ) {
		$res = $this->result;

		// check bounds
		$numRows = $this->db->numRows( $res );
		$row = intval( $row );

		if ( $numRows === 0 ) {
			return false;
		} elseif ( $row < 0 || $row > $numRows - 1 ) {
			return false;
		}

		// Unlike MySQL, the seek actually happens on the next access
		$this->seekTo = $row;
		return true;
	}
}