Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.33% covered (success)
93.33%
28 / 30
75.00% covered (warning)
75.00%
6 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
DatabaseFlags
93.33% covered (success)
93.33%
28 / 30
75.00% covered (warning)
75.00%
6 / 8
18.10
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setFlag
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 clearFlag
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 restoreFlags
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 getFlag
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 contains
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasApplicableImplicitTrxFlag
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 hasImplicitTrxFlag
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20namespace Wikimedia\Rdbms\Database;
21
22use Wikimedia\Rdbms\DBLanguageError;
23use Wikimedia\Rdbms\Platform\ISQLPlatform;
24
25/**
26 * @ingroup Database
27 * @internal
28 * @since 1.39
29 */
30class DatabaseFlags implements IDatabaseFlags {
31    /** @var int Current bit field of class DBO_* constants */
32    protected $flags;
33    /** @var int[] Prior flags member variable values */
34    private $priorFlags = [];
35
36    /** @var string[] List of DBO_* flags that can be changed after connection */
37    protected const MUTABLE_FLAGS = [
38        'DBO_DEBUG',
39        'DBO_NOBUFFER',
40        'DBO_TRX',
41        'DBO_DDLMODE',
42    ];
43    /** @var int Bit field of all DBO_* flags that can be changed after connection */
44    protected const DBO_MUTABLE = (
45        self::DBO_DEBUG | self::DBO_NOBUFFER | self::DBO_TRX | self::DBO_DDLMODE
46    );
47
48    public function __construct( $flags ) {
49        $this->flags = $flags;
50    }
51
52    public function setFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
53        if ( $flag & ~static::DBO_MUTABLE ) {
54            throw new DBLanguageError(
55                "Got $flag (allowed: " . implode( ', ', static::MUTABLE_FLAGS ) . ')'
56            );
57        }
58
59        if ( $remember === self::REMEMBER_PRIOR ) {
60            $this->priorFlags[] = $this->flags;
61        }
62
63        $this->flags |= $flag;
64    }
65
66    public function clearFlag( $flag, $remember = self::REMEMBER_NOTHING ) {
67        if ( $flag & ~static::DBO_MUTABLE ) {
68            throw new DBLanguageError(
69                "Got $flag (allowed: " . implode( ', ', static::MUTABLE_FLAGS ) . ')'
70            );
71        }
72
73        if ( $remember === self::REMEMBER_PRIOR ) {
74            $this->priorFlags[] = $this->flags;
75        }
76
77        $this->flags &= ~$flag;
78    }
79
80    public function restoreFlags( $state = self::RESTORE_PRIOR ) {
81        if ( !$this->priorFlags ) {
82            return;
83        }
84
85        if ( $state === self::RESTORE_INITIAL ) {
86            $this->flags = reset( $this->priorFlags );
87            $this->priorFlags = [];
88        } else {
89            $this->flags = array_pop( $this->priorFlags );
90        }
91    }
92
93    public function getFlag( $flag ) {
94        return ( ( $this->flags & $flag ) === $flag );
95    }
96
97    /**
98     * @param int $flags A bit field of flags
99     * @param int $bit Bit flag constant
100     * @return bool Whether the bit field has the specified bit flag set
101     */
102    public static function contains( int $flags, int $bit ) {
103        return ( ( $flags & $bit ) === $bit );
104    }
105
106    /**
107     * @param int $queryFlags A bit field of ISQLPlatform::QUERY_* constants
108     * @return bool Whether the implicit transaction flag is set and applies to the query flags
109     */
110    public function hasApplicableImplicitTrxFlag( int $queryFlags ) {
111        return $this->hasImplicitTrxFlag() && !(
112            self::contains( $queryFlags, ISQLPlatform::QUERY_CHANGE_TRX ) ||
113            self::contains( $queryFlags, ISQLPlatform::QUERY_CHANGE_SCHEMA ) ||
114            self::contains( $queryFlags, ISQLPlatform::QUERY_CHANGE_LOCKS ) ||
115            self::contains( $queryFlags, ISQLPlatform::QUERY_IGNORE_DBO_TRX )
116        );
117    }
118
119    /**
120     * @return bool Whether the implicit transaction flag is set
121     */
122    public function hasImplicitTrxFlag() {
123        return $this->getFlag( self::DBO_TRX );
124    }
125}