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