WebKitPerfMonitor: There should be a way to add all metrics of a suite without also...
[WebKit-https.git] / Websites / perf.webkit.org / public / include / db.php
1 <?php
2
3 function ends_with($str, $key) {
4     return strrpos($str, $key) == strlen($str) - strlen($key);
5 }
6
7 function ctype_alnum_underscore($str) {
8     return ctype_alnum(str_replace('_', '', $str));
9 }
10
11 function &array_ensure_item_has_array(&$array, $key) {
12     if (!array_key_exists($key, $array))
13         $array[$key] = array();
14     return $array[$key];
15 }
16
17 function array_get($array, $key, $default = NULL) {
18     if (!array_key_exists($key, $array))
19         return $default;
20     return $array[$key];
21 }
22
23 function array_set_default(&$array, $key, $default) {
24     if (!array_key_exists($key, $array))
25         $array[$key] = $default;
26 }
27
28 $_config = NULL;
29
30 function config($key) {
31     global $_config;
32     if (!$_config)
33         $_config = json_decode(file_get_contents(dirname(__FILE__) . '/../../config.json'), true);
34     return $_config[$key];
35 }
36
37 if (config('debug')) {
38     error_reporting(E_ALL | E_STRICT);
39     ini_set('display_errors', 'On');
40 } else
41     error_reporting(E_ERROR);
42
43 class Database
44 {
45     private $connection = false;
46
47     function __destruct() {
48         if ($this->connection)
49             pg_close($this->connection);
50         $this->connection = false;
51     }
52
53     function is_true($value) {
54         return $value == 't';
55     }
56
57     function connect() {
58         $databaseConfig = config('database');
59         $this->connection = pg_connect('host=' . $databaseConfig['host'] . ' port=' . $databaseConfig['port']
60             . ' dbname=' . $databaseConfig['name'] . ' user=' . $databaseConfig['username'] . ' password=' . $databaseConfig['password']);
61         return $this->connection ? true : false;
62     }
63
64     private function prefixed_column_names($columns, $prefix = NULL) {
65         if (!$prefix)
66             return join(', ', $columns);
67         return $prefix . '_' . join(', ' . $prefix . '_', $columns);
68     }
69
70     private function prefixed_name($column, $prefix = NULL) {
71         return $prefix ? $prefix . '_' . $column : $column;
72     }
73
74     private function prepare_params($params, &$placeholders, &$values) {
75         $column_names = array_keys($params);
76
77         $i = count($values) + 1;
78         foreach ($column_names as $name) {
79             assert(ctype_alnum_underscore($name));
80             array_push($placeholders, '$' . $i);
81             array_push($values, $params[$name]);
82             $i++;
83         }
84
85         return $column_names;
86     }
87
88     function insert_row($table, $prefix, $params, $returning = 'id') {
89         $placeholders = array();
90         $values = array();
91         $column_names = $this->prepare_params($params, $placeholders, $values);
92
93         assert(!$prefix || ctype_alnum_underscore($prefix));
94         $column_names = $this->prefixed_column_names($column_names, $prefix);
95         $placeholders = join(', ', $placeholders);
96
97         if ($returning) {
98             $returning_column_name = $this->prefixed_name($returning, $prefix);
99             $rows = $this->query_and_fetch_all("INSERT INTO $table ($column_names) VALUES ($placeholders) RETURNING $returning_column_name", $values);
100             return $rows ? $rows[0][$returning_column_name] : NULL;
101         }
102
103         return $this->query_and_get_affected_rows("INSERT INTO $table ($column_names) VALUES ($placeholders)", $values) == 1;
104     }
105
106     function select_or_insert_row($table, $prefix, $select_params, $insert_params = NULL, $returning = 'id') {
107         $values = array();
108
109         $select_placeholders = array();
110         $select_column_names = $this->prepare_params($select_params, $select_placeholders, $values);
111         $select_values = array_slice($values, 0);
112
113         if ($insert_params === NULL)
114             $insert_params = $select_params;
115         $insert_placeholders = array();
116         $insert_column_names = $this->prepare_params($insert_params, $insert_placeholders, $values);
117
118         assert(!!$returning);
119         assert(!$prefix || ctype_alnum_underscore($prefix));
120         $returning_column_name = $returning == '*' ? '*' : $this->prefixed_name($returning, $prefix);
121         $select_column_names = $this->prefixed_column_names($select_column_names, $prefix);
122         $select_placeholders = join(', ', $select_placeholders);
123         $query = "SELECT $returning_column_name FROM $table WHERE ($select_column_names) = ($select_placeholders)";
124
125         $insert_column_names = $this->prefixed_column_names($insert_column_names, $prefix);
126         $insert_placeholders = join(', ', $insert_placeholders);
127         $rows = $this->query_and_fetch_all("INSERT INTO $table ($insert_column_names) SELECT $insert_placeholders WHERE NOT EXISTS
128             ($query) RETURNING $returning_column_name", $values);
129         if (!$rows)
130             $rows = $this->query_and_fetch_all($query, $select_values);
131
132         return $rows ? ($returning == '*' ? $rows[0] : $rows[0][$returning_column_name]) : NULL;
133     }
134
135     function select_first_row($table, $prefix, $params, $order_by = NULL) {
136         $placeholders = array();
137         $values = array();
138         $column_names = $this->prefixed_column_names($this->prepare_params($params, $placeholders, $values), $prefix);
139         $placeholders = join(', ', $placeholders);
140         $query = "SELECT * FROM $table WHERE ($column_names) = ($placeholders)";
141         if ($order_by) {
142             assert(!ctype_alnum_underscore($order_by));
143             $query .= ' ORDER BY ' . $this->prefixed_name($order_by, $prefix);
144         }
145         $rows = $this->query_and_fetch_all($query . ' LIMIT 1', $values);
146
147         return $rows ? $rows[0] : NULL;
148     }
149
150     function query_and_get_affected_rows($query, $params = array()) {
151         if (!$this->connection)
152             return FALSE;
153         $result = pg_query_params($this->connection, $query, $params);
154         if (!$result)
155             return FALSE;
156         return pg_affected_rows($result);
157     }
158
159     function query_and_fetch_all($query, $params = array()) {
160         if (!$this->connection)
161             return false;
162         $result = pg_query_params($this->connection, $query, $params);
163         if (!$result)
164             return false;
165         return pg_fetch_all($result);
166     }
167
168     function query($query, $params = array()) {
169         if (!$this->connection)
170             return FALSE;
171         return pg_query_params($this->connection, $query, $params);
172     }
173
174     function fetch_next_row($result) {
175         return pg_fetch_assoc($result);
176     }
177
178     function fetch_table($table_name, $column_to_be_ordered_by = null) {
179         if (!$this->connection || !ctype_alnum_underscore($table_name) || ($column_to_be_ordered_by && !ctype_alnum_underscore($column_to_be_ordered_by)))
180             return false;
181         $clauses = '';
182         if ($column_to_be_ordered_by)
183             $clauses .= 'ORDER BY ' . $column_to_be_ordered_by;
184         return $this->query_and_fetch_all("SELECT * FROM $table_name $clauses");
185     }
186
187     function begin_transaction() {
188         return $this->connection and pg_query($this->connection, "BEGIN");
189     }
190
191     function commit_transaction() {
192         return $this->connection and pg_query($this->connection, 'COMMIT');
193     }
194
195     function rollback_transaction() {
196         return $this->connection and pg_query($this->connection, 'ROLLBACK');
197     }
198
199 }
200
201 ?>