OraclePDODatabase::getIndexes()   A
last analyzed

Complexity

Conditions 5
Paths 9

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 17
c 1
b 0
f 0
nc 9
nop 2
dl 0
loc 34
ccs 0
cts 18
cp 0
crap 30
rs 9.3888
1
<?php
2
3
declare(strict_types=1);
4
/**
5
 * Database Access Layer.
6
 * @author Doug Wright
7
 */
8
9
namespace DVDoug\DB;
10
11
/**
12
 * Oracle database connection (PDO).
13
 * @author Doug Wright
14
 */
15
class OraclePDODatabase extends PDODatabase
16
{
17
    /**
18
     * Constructor.
19
     * @param string $aConnectionString Oracle connection string with host/port/service name etc
20
     * @param string $aUsername         connection username
21
     * @param string $aPassword         connection password
22
     * @param string $aCharset          connection character set
23
     */
24
    public function __construct($aConnectionString, $aUsername, $aPassword, $aCharset = 'AL32UTF8')
25
    {
26
        parent::__construct("oci:dbname={$aConnectionString};charset={$aCharset}", $aUsername, $aPassword);
27
        $this->exec("ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
28
    }
29
30
    /**
31
     * List of tables in a database.
32
     * @param string $aDatabase database/schema name
33
     */
34
    public function getTables($aDatabase = null): array
35
    {
36
        if ($aDatabase) {
37
            $statement = $this->prepare('SELECT OWNER, TABLE_NAME FROM ALL_TABLES WHERE OWNER = :owner ORDER BY TABLE_NAME ASC');
38
            $statement->bindParamToValue(':owner', $aDatabase);
0 ignored issues
show
Bug introduced by
The method bindParamToValue() does not exist on PDOStatement. Did you maybe mean bindParam()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

38
            $statement->/** @scrutinizer ignore-call */ 
39
                        bindParamToValue(':owner', $aDatabase);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
39
            $statement->execute();
40
        } else {
41
            $statement = $this->query('SELECT OWNER, TABLE_NAME FROM ALL_TABLES');
42
        }
43
44
        $result = $statement->fetchAssoc(true, true);
45
46
        $tables = [];
47
        foreach ($result as $database => $dbtables) {
48
            $tables[$database] = [];
49
            foreach ($dbtables as $table) {
50
                $tables[$database][] = $table['TABLE_NAME'];
51
            }
52
        }
53
54
        return $aDatabase ? $tables[$aDatabase] : $tables;
55
    }
56
57
    /**
58
     * List of columns (and types) in a table.
59
     * @param  string                $aDatabase database/schema name
60
     * @param  string                $aTable    table name
61
     * @return ColumnMetaInterface[]
62
     */
63
    public function getTableColumns($aDatabase, $aTable): array
64
    {
65
        $statement = $this->prepare('SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE OWNER = :owner AND TABLE_NAME = :table_name ORDER BY COLUMN_ID ASC');
66
        $statement->bindParamToValue(':owner', $aDatabase);
67
        $statement->bindParamToValue(':table_name', $aTable);
68
        $statement->execute();
69
70
        $result = $statement->fetchAssoc();
0 ignored issues
show
Bug introduced by
The method fetchAssoc() does not exist on PDOStatement. Did you maybe mean fetch()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

70
        /** @scrutinizer ignore-call */ 
71
        $result = $statement->fetchAssoc();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
71
72
        $columns = [];
73
        foreach ($result as $row) {
74
            $columns[$row['COLUMN_NAME']] = new OracleColumnMeta($this, $aDatabase, $aTable, $row['COLUMN_NAME']);
75
        }
76
77
        return $columns;
78
    }
79
80
    /**
81
     * Primary key column(s).
82
     * @param string $aDatabase database/schema name
83
     * @param string $aTable    table name
84
     */
85
    public function getPrimaryKey($aDatabase, $aTable): array
86
    {
87
        $columns = [];
88
        $SQL = "SELECT COLS.POSITION, COLS.COLUMN_NAME
89
                     FROM ALL_CONSTRAINTS cons
90
                          JOIN ALL_CONS_COLUMNS cols
91
                            ON cons.CONSTRAINT_NAME = cols.CONSTRAINT_NAME
92
                               AND cons.OWNER = cols.OWNER
93
                     WHERE cols.TABLE_NAME = :table_name
94
                           AND cons.CONSTRAINT_TYPE = 'P'
95
                           AND cols.OWNER = :database_name
96
                     ORDER BY cols.POSITION";
97
        $statement = $this->prepare($SQL);
98
        $statement->bindParamToValue(':table_name', $aTable);
99
        $statement->bindParamToValue(':database_name', $aDatabase);
100
        $statement->execute();
101
102
        $result = $statement->fetchAssoc();
103
        foreach ($result as $column) {
104
            $columns[] = $column['COLUMN_NAME'];
105
        }
106
107
        return $columns;
108
    }
109
110
    /**
111
     * Non-PK indexes.
112
     * @param string $aDatabase database/schema name
113
     * @param string $aTable    table name
114
     */
115
    public function getIndexes($aDatabase, $aTable): array
116
    {
117
        $indexes = [];
118
        $SQL = 'SELECT INDEX_NAME, COLUMN_NAME
119
                   FROM ALL_IND_COLUMNS
120
                   WHERE TABLE_NAME = :table_name
121
                         AND TABLE_OWNER = :database_name
122
                   ORDER BY INDEX_NAME ASC, COLUMN_POSITION ASC';
123
        $statement = $this->prepare($SQL);
124
        $statement->bindParamToValue(':table_name', $aTable);
125
        $statement->bindParamToValue(':database_name', $aDatabase);
126
        $statement->execute();
127
128
        $result = $statement->fetchAssoc(true, true);
129
130
        foreach ($result as $index => $columnList) {
131
            $indexes[$index] = [];
132
            foreach ($columnList as $col) {
133
                $indexes[$index][] = $col['COLUMN_NAME'];
134
            }
135
        }
136
137
        /*
138
         * Subtract PK if any
139
         */
140
        $PK = $this->getPrimaryKey($aDatabase, $aTable);
141
        foreach ($indexes as $name => $columns) {
142
            if ($PK === $columns) {
143
                unset($indexes[$name]);
144
                break;
145
            }
146
        }
147
148
        return $indexes;
149
    }
150
}
151