Passed
Push — master ( f3b317...5b2bef )
by Felipe
07:25 queued 03:38
created

AggregateTrait::changeAggregateOwner()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 3
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.41
5
 */
6
7
namespace PHPPgAdmin\Database;
8
9
/**
10
 * Common trait for aggregates manipulation.
11
 */
12
trait AggregateTrait
13
{
14
    /**
15
     * Creates a new aggregate in the database.
16
     *
17
     * @param string $name     The name of the aggregate
18
     * @param string $basetype The input data type of the aggregate
19
     * @param string $sfunc    The name of the state transition function for the aggregate
20
     * @param string $stype    The data type for the aggregate's state value
21
     * @param string $ffunc    The name of the final function for the aggregate
22
     * @param string $initcond The initial setting for the state value
23
     * @param string $sortop   The sort operator for the aggregate
24
     * @param string $comment  Aggregate comment
25
     *
26
     * @return bool|int 0 success
27
     */
28
    public function createAggregate($name, $basetype, $sfunc, $stype, $ffunc, $initcond, $sortop, $comment)
29
    {
30
        $f_schema = $this->_schema;
31
        $this->fieldClean($f_schema);
32
        $this->fieldClean($name);
33
        $this->fieldClean($basetype);
34
        $this->fieldClean($sfunc);
35
        $this->fieldClean($stype);
36
        $this->fieldClean($ffunc);
37
        $this->fieldClean($initcond);
38
        $this->fieldClean($sortop);
39
40
        $this->beginTransaction();
41
42
        $sql = "CREATE AGGREGATE \"{$f_schema}\".\"{$name}\" (BASETYPE = \"{$basetype}\", SFUNC = \"{$sfunc}\", STYPE = \"{$stype}\"";
43
        if (trim($ffunc) != '') {
44
            $sql .= ", FINALFUNC = \"{$ffunc}\"";
45
        }
46
47
        if (trim($initcond) != '') {
48
            $sql .= ", INITCOND = \"{$initcond}\"";
49
        }
50
51
        if (trim($sortop) != '') {
52
            $sql .= ", SORTOP = \"{$sortop}\"";
53
        }
54
55
        $sql .= ')';
56
57
        $status = $this->execute($sql);
58
        if ($status) {
59
            $this->rollbackTransaction();
60
61
            return -1;
62
        }
63
64
        if (trim($comment) != '') {
65
            $status = $this->setComment('AGGREGATE', $name, '', $comment, $basetype);
66
            if ($status) {
67
                $this->rollbackTransaction();
68
69
                return -1;
70
            }
71
        }
72
73
        return $this->endTransaction();
74
    }
75
76
    /**
77
     * Removes an aggregate function from the database.
78
     *
79
     * @param string $aggrname The name of the aggregate
80
     * @param string $aggrtype The input data type of the aggregate
81
     * @param bool   $cascade  True to cascade drop, false to restrict
82
     *
83
     * @return int 0 if operation was successful
84
     */
85
    public function dropAggregate($aggrname, $aggrtype, $cascade)
86
    {
87
        $f_schema = $this->_schema;
88
        $this->fieldClean($f_schema);
89
        $this->fieldClean($aggrname);
90
        $this->fieldClean($aggrtype);
91
92
        $sql = "DROP AGGREGATE \"{$f_schema}\".\"{$aggrname}\" (\"{$aggrtype}\")";
93
        if ($cascade) {
94
            $sql .= ' CASCADE';
95
        }
96
97
        return $this->execute($sql);
98
    }
99
100
    /**
101
     * Gets all information for an aggregate.
102
     *
103
     * @param string $name     The name of the aggregate
104
     * @param string $basetype The input data type of the aggregate
105
     *
106
     * @return \PHPPgAdmin\ADORecordSet A recordset
107
     */
108
    public function getAggregate($name, $basetype)
109
    {
110
        $c_schema = $this->_schema;
111
        $this->clean($c_schema);
112
        $this->fieldClean($name);
113
        $this->fieldClean($basetype);
114
115
        $sql = "
116
            SELECT p.proname, CASE p.proargtypes[0]
117
                WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype THEN NULL
118
                ELSE pg_catalog.format_type(p.proargtypes[0], NULL) END AS proargtypes,
119
                a.aggtransfn, format_type(a.aggtranstype, NULL) AS aggstype, a.aggfinalfn,
120
                a.agginitval, a.aggsortop, u.usename, pg_catalog.obj_description(p.oid, 'pg_proc') AS aggrcomment
121
            FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_user u, pg_catalog.pg_aggregate a
122
            WHERE n.oid = p.pronamespace AND p.proowner=u.usesysid AND p.oid=a.aggfnoid
123
                AND p.proisagg AND n.nspname='{$c_schema}'
124
                AND p.proname='".$name."'
125
                AND CASE p.proargtypes[0]
126
                    WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype THEN ''
127
                    ELSE pg_catalog.format_type(p.proargtypes[0], NULL)
128
                END ='".$basetype."'";
129
130
        return $this->selectSet($sql);
131
    }
132
133
    /**
134
     * Gets all aggregates.
135
     *
136
     * @return \PHPPgAdmin\ADORecordSet A recordset
137
     */
138
    public function getAggregates()
139
    {
140
        $c_schema = $this->_schema;
141
        $this->clean($c_schema);
142
        $sql = "SELECT p.proname, CASE p.proargtypes[0] WHEN 'pg_catalog.\"any\"'::pg_catalog.regtype THEN NULL ELSE
143
               pg_catalog.format_type(p.proargtypes[0], NULL) END AS proargtypes, a.aggtransfn, u.usename,
144
               pg_catalog.obj_description(p.oid, 'pg_proc') AS aggrcomment
145
               FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_user u, pg_catalog.pg_aggregate a
146
               WHERE n.oid = p.pronamespace AND p.proowner=u.usesysid AND p.oid=a.aggfnoid
147
               AND p.proisagg AND n.nspname='{$c_schema}' ORDER BY 1, 2";
148
149
        return $this->selectSet($sql);
150
    }
151
152
    /**
153
     * Alters an aggregate.
154
     *
155
     * @param string $aggrname       The actual name of the aggregate
156
     * @param string $aggrtype       The actual input data type of the aggregate
157
     * @param string $aggrowner      The actual owner of the aggregate
158
     * @param string $aggrschema     The actual schema the aggregate belongs to
159
     * @param string $aggrcomment    The actual comment for the aggregate
160
     * @param string $newaggrname    The new name of the aggregate
161
     * @param string $newaggrowner   The new owner of the aggregate
162
     * @param string $newaggrschema  The new schema where the aggregate will belong to
163
     * @param string $newaggrcomment The new comment for the aggregate
164
     *
165
     * @return bool|int 0 success
166
     */
167
    public function alterAggregate(
168
        $aggrname,
169
        $aggrtype,
170
        $aggrowner,
171
        $aggrschema,
172
        $aggrcomment,
173
        $newaggrname,
174
        $newaggrowner,
175
        $newaggrschema,
176
        $newaggrcomment
177
    ) {
178
        // Clean fields
179
        $this->fieldClean($aggrname);
180
        $this->fieldClean($aggrtype);
181
        $this->fieldClean($aggrowner);
182
        $this->fieldClean($aggrschema);
183
        $this->fieldClean($newaggrname);
184
        $this->fieldClean($newaggrowner);
185
        $this->fieldClean($newaggrschema);
186
187
        $this->beginTransaction();
188
189
        // Change the owner, if it has changed
190
        if ($aggrowner != $newaggrowner) {
191
            $status = $this->changeAggregateOwner($aggrname, $aggrtype, $newaggrowner);
192
            if ($status != 0) {
193
                $this->rollbackTransaction();
194
195
                return -1;
196
            }
197
        }
198
199
        // Set the comment, if it has changed
200
        if ($aggrcomment != $newaggrcomment) {
201
            $status = $this->setComment('AGGREGATE', $aggrname, '', $newaggrcomment, $aggrtype);
202
            if ($status) {
203
                $this->rollbackTransaction();
204
205
                return -2;
206
            }
207
        }
208
209
        // Change the schema, if it has changed
210
        if ($aggrschema != $newaggrschema) {
211
            $status = $this->changeAggregateSchema($aggrname, $aggrtype, $newaggrschema);
212
            if ($status != 0) {
213
                $this->rollbackTransaction();
214
215
                return -3;
216
            }
217
        }
218
219
        // Rename the aggregate, if it has changed
220
        if ($aggrname != $newaggrname) {
221
            $status = $this->renameAggregate($newaggrschema, $aggrname, $aggrtype, $newaggrname);
222
            if ($status != 0) {
223
                $this->rollbackTransaction();
224
225
                return -4;
226
            }
227
        }
228
229
        return $this->endTransaction();
230
    }
231
232
    /**
233
     * Changes the owner of an aggregate function.
234
     *
235
     * @param string $aggrname     The name of the aggregate
236
     * @param string $aggrtype     The input data type of the aggregate
237
     * @param string $newaggrowner The new owner of the aggregate
238
     *
239
     * @return int 0 if operation was successful
240
     */
241
    public function changeAggregateOwner($aggrname, $aggrtype, $newaggrowner)
242
    {
243
        $f_schema = $this->_schema;
244
        $this->fieldClean($f_schema);
245
        $this->fieldClean($aggrname);
246
        $this->fieldClean($newaggrowner);
247
        $sql = "ALTER AGGREGATE \"{$f_schema}\".\"{$aggrname}\" (\"{$aggrtype}\") OWNER TO \"{$newaggrowner}\"";
248
249
        return $this->execute($sql);
250
    }
251
252
    /**
253
     * Changes the schema of an aggregate function.
254
     *
255
     * @param string $aggrname      The name of the aggregate
256
     * @param string $aggrtype      The input data type of the aggregate
257
     * @param string $newaggrschema The new schema for the aggregate
258
     *
259
     * @return int 0 if operation was successful
260
     */
261
    public function changeAggregateSchema($aggrname, $aggrtype, $newaggrschema)
262
    {
263
        $f_schema = $this->_schema;
264
        $this->fieldClean($f_schema);
265
        $this->fieldClean($aggrname);
266
        $this->fieldClean($newaggrschema);
267
        $sql = "ALTER AGGREGATE \"{$f_schema}\".\"{$aggrname}\" (\"{$aggrtype}\") SET SCHEMA  \"{$newaggrschema}\"";
268
269
        return $this->execute($sql);
270
    }
271
272
    /**
273
     * Renames an aggregate function.
274
     *
275
     * @param string $aggrschema  The schema of the aggregate
276
     * @param string $aggrname    The actual name of the aggregate
277
     * @param string $aggrtype    The actual input data type of the aggregate
278
     * @param string $newaggrname The new name of the aggregate
279
     *
280
     * @return int 0 if operation was successful
281
     */
282
    public function renameAggregate($aggrschema, $aggrname, $aggrtype, $newaggrname)
283
    {
284
        /* this function is called from alterAggregate where params are cleaned */
285
        $sql = "ALTER AGGREGATE \"{$aggrschema}\"".'.'."\"{$aggrname}\" (\"{$aggrtype}\") RENAME TO \"{$newaggrname}\"";
286
287
        return $this->execute($sql);
288
    }
289
290
    abstract public function fieldClean(&$str);
291
292
    abstract public function beginTransaction();
293
294
    abstract public function rollbackTransaction();
295
296
    abstract public function endTransaction();
297
298
    abstract public function execute($sql);
299
300
    abstract public function setComment($obj_type, $obj_name, $table, $comment, $basetype = null);
301
302
    abstract public function selectSet($sql);
303
304
    abstract public function clean(&$str);
305
}
306