DbConn   B
last analyzed

Complexity

Total Complexity 48

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 109
dl 0
loc 199
rs 8.5599
c 0
b 0
f 0
wmc 48

28 Methods

Rating   Name   Duplication   Size   Complexity  
A table_exists() 0 7 3
A delete_aux() 0 3 1
A base_errno() 0 2 1
A sum() 0 3 1
A enum() 0 3 1
A count() 0 3 1
A max() 0 3 1
A lookup_id() 0 3 1
A delete() 0 3 1
A get_double() 0 7 3
A get_list() 0 10 3
A enum_fields() 0 9 2
A do_query() 0 15 3
A base_escape_string() 0 2 1
A affected_rows() 0 2 1
A replace() 0 3 1
A enum_general() 0 9 3
A update() 0 3 1
A insert() 0 3 1
A update_aux() 0 3 1
A base_error() 0 2 1
A lookup() 0 2 1
A lookup_fields() 0 9 2
A get_int() 0 7 3
A percentile() 0 6 2
A insert_id() 0 2 1
A close() 0 3 2
A init_conn() 0 23 5

How to fix   Complexity   

Complex Class

Complex classes like DbConn often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DbConn, and based on these observations, apply Extract Interface, too.

1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2008 University of California
5
//
6
// BOINC is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License
8
// as published by the Free Software Foundation,
9
// either version 3 of the License, or (at your option) any later version.
10
//
11
// BOINC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
// See the GNU Lesser General Public License for more details.
15
//
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19
require_once("../inc/db.inc");
20
21
// represents a connection to a database.
22
// Intended to be subclassed (e.g., BoincDb, BossaDb)
23
//
24
class DbConn {
25
    var $db_conn;       // a mysqli object
26
    var $db_name;       // the DB name
27
28
    function init_conn($user, $passwd, $host, $name) {
29
        $x = explode(":", $host);
30
        if (sizeof($x)>1) {
31
            $host = $x[0];
32
            $port = $x[1];
33
        } else {
34
            $port = null;
35
        }
36
        try {
37
            $this->db_conn = @new mysqli($host, $user, $passwd, $name, $port);
0 ignored issues
show
Bug introduced by
It seems like $port can also be of type string; however, parameter $port of mysqli::__construct() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

37
            $this->db_conn = @new mysqli($host, $user, $passwd, $name, /** @scrutinizer ignore-type */ $port);
Loading history...
38
        } catch(Exception $e) {
39
            return false;
40
        }
41
        if (mysqli_connect_error()) {
42
            return false;
43
        }
44
        global $mysqli;
45
        $mysqli = $this->db_conn;
46
        if (!$this->db_conn) {
47
            return false;
48
        }
49
        $this->db_name = $name;
50
        return true;
51
    }
52
53
    function close() {
54
        if ($this->db_conn) {
55
            $this->db_conn->close();
56
        }
57
    }
58
59
    // in keeping with PHP/MySQL convention, return true (nonzero) on success.
60
    // (This is the opposite of the BOINC convention)
61
    //
62
    function do_query($q) {
63
        global $generating_xml;
64
        $q = str_replace('DBNAME', $this->db_name, $q);
65
        //echo "query: $q<br>\n";
66
        $ret = $this->db_conn->query($q);
67
        if (!$ret) {
68
            if (!$generating_xml) {
69
                echo "Database Error<br>\n";
70
            }
71
            //echo ": ", $this->base_error(), "\n<pre>";
72
            //var_dump(debug_backtrace());
73
            //echo "</pre>query: $q\n";
74
            return null;
75
        }
76
        return $ret;
77
    }
78
79
    // # rows affected by last query
80
    //
81
    function affected_rows() {
82
        return $this->db_conn->affected_rows;
83
    }
84
85
    function get_list($table1, $table2, $joinfield1, $joinfield2, $classname, $fields, $where_clause, $order_clause, $limit) {
86
        $query = "select $fields from DBNAME.$table1 a join DBNAME.$table2 b on a.$joinfield1=b.$joinfield2 where $where_clause order by $order_clause desc limit $limit";
87
        $result = $this->do_query($query);
88
        if (!$result) return null;
89
        $x = array();
90
        while ($obj = $result->fetch_object($classname)) {
91
            $x[] = $obj;
92
        }
93
        $result->free();
94
        return $x;
95
    }
96
97
    function lookup_fields($table, $classname, $fields, $clause) {
98
        $query = "select $fields from DBNAME.$table where $clause";
99
        $result = $this->do_query($query);
100
        if (!$result) {
101
            return null;
102
        }
103
        $obj = $result->fetch_object($classname);
104
        $result->free();
105
        return $obj;
106
    }
107
108
    function lookup($table, $classname, $clause) {
109
        return $this->lookup_fields($table, $classname, "*", $clause);
110
    }
111
112
    function lookup_id($id, $table, $classname) {
113
        $id = (int)$id;
114
        return $this->lookup($table, $classname, "id=$id");
115
    }
116
117
    function enum_general($classname, $query) {
118
        $result = $this->do_query($query);
119
        if (!$result) return [];
120
        $x = [];
121
        while ($obj = $result->fetch_object($classname)) {
122
            $x[] = $obj;
123
        }
124
        $result->free();
125
        return $x;
126
    }
127
128
    function enum_fields(
129
        $table, $classname, $fields, $where_clause, $order_clause
0 ignored issues
show
Coding Style introduced by
Multi-line function declarations must define one parameter per line
Loading history...
130
    ) {
131
        $x = array();
132
        if ($where_clause) {
133
            $where_clause = "where $where_clause";
134
        }
135
        $query = "select $fields from DBNAME.$table $where_clause $order_clause";
136
        return $this->enum_general($classname, $query);
137
    }
138
139
    function enum($table, $classname, $where_clause=null, $order_clause=null) {
140
        return self::enum_fields(
0 ignored issues
show
Bug Best Practice introduced by
The method DbConn::enum_fields() is not static, but was called statically. ( Ignorable by Annotation )

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

140
        return self::/** @scrutinizer ignore-call */ enum_fields(
Loading history...
141
            $table, $classname, '*', $where_clause, $order_clause
142
        );
143
    }
144
145
    function update($obj, $table, $clause) {
146
        $query = "update DBNAME.$table set $clause where id=$obj->id";
147
        return $this->do_query($query);
148
    }
149
    function update_aux($table, $clause) {
150
        $query = "update DBNAME.$table set $clause";
151
        return $this->do_query($query);
152
    }
153
    function insert($table, $clause) {
154
        $query = "insert into DBNAME.$table $clause";
155
        return $this->do_query($query);
156
    }
157
    function delete($obj, $table) {
158
        $query = "delete from DBNAME.$table where id=$obj->id";
159
        return $this->do_query($query);
160
    }
161
    function delete_aux($table, $clause) {
162
        $query = "delete from DBNAME.$table where $clause";
163
        return $this->do_query($query);
164
    }
165
    function insert_id() {
166
        return $this->db_conn->insert_id;
167
    }
168
    function get_int($query, $field) {
169
        $result = $this->do_query($query);
170
        if (!$result) error_page("database error on query $query");
171
        $x = $result->fetch_object("StdClass");
172
        $result->free();
173
        if ($x) return $x->$field;
174
        return false;
175
    }
176
    function get_double($query, $field) {
177
        $result = $this->do_query($query);
178
        if (!$result) error_page("database error on query $query");
179
        $x = $result->fetch_object("StdClass");
180
        $result->free();
181
        if ($x) return (double)$x->$field;
182
        return false;
183
    }
184
    function count($table, $clause="TRUE") {
185
        $query = "select count(*) as total from DBNAME.$table where $clause";
186
        return $this->get_int($query, 'total');
187
    }
188
    function sum($table, $field, $clause="") {
189
        $query = "select sum($field) as total from DBNAME.$table $clause";
190
        return $this->get_double($query, 'total');
191
    }
192
    function max($table, $field, $clause="") {
193
        $query = "select max($field) as total from DBNAME.$table $clause";
194
        return $this->get_double($query, 'total');
195
    }
196
    function percentile($table, $field, $clause, $pct) {
197
        $n = $this->count($table, $clause);
198
        if (!$n) return false;
199
        $m = (int)($n*$pct/100);
200
        $query = "select $field from DBNAME.$table where $clause order by $field limit $m,1";
201
        return $this->get_double($query, $field);
202
    }
203
    function replace($table, $clause) {
204
        $query = "replace into DBNAME.$table set $clause";
205
        return $this->do_query($query);
206
    }
207
    function base_escape_string($string) {
208
        return $this->db_conn->escape_string($string);
209
    }
210
    function base_error() {
211
        return $this->db_conn->error;
212
    }
213
    function base_errno() {
214
        return $this->db_conn->errno;
215
    }
216
    function table_exists($table_name) {
217
        $result = $this->do_query("show tables from DBNAME like '$table_name'");
218
        if (!$result) error_page("database error on query $query");
219
        $t = _mysql_fetch_array($result);
220
        _mysql_free_result($result);
221
        if ($t[0] == "$table_name") return true;
222
        return false;
223
    }
224
}
225
226
?>
227