source: trunk/common/db/db_mysql.php @ 1184

Revision 1060, 4.4 KB checked in by bogdan2412, 3 years ago (diff)

Really fix database connection keep alive. :)

  • Property svn:eol-style set to native
Line 
1<?php
2
3// Connects to the database. Call this function if you need the database.
4// It's better than connecting when the file is included. Side-effects are bad.
5function db_connect() {
6    global $dbLink;
7    // Repetitive include guard. Is this really needed?
8    if (db_isalive()) {
9        log_warn("Already connected to the database.");
10        return true;
11    }
12
13    // log_print("Connecting to database...");
14    if (!$dbLink = @mysql_connect(IA_DB_HOST, IA_DB_USER, IA_DB_PASS)) {
15        if (IA_DB_KEEP_ALIVE) {
16            $timeout = 0;
17            do {
18                log_warn('Cannot connect to database: '.mysql_error().
19                    "\nRetrying...");
20
21                // Wait for an increasing amount of seconds to avoid
22                // strain on the mysql server if it is under heavy load
23                sleep($timeout);
24                $timeout = min(max(1, $timeout * 2), 60);
25
26                // Try and reconnect to the database server
27                $dbLink = @mysql_connect(IA_DB_HOST, IA_DB_USER, IA_DB_PASS);
28            } while (!db_isalive());
29            log_print('Connected to database.');
30        } else {
31            log_error('Cannot connect to database: '.mysql_error());
32        }
33    }
34    if (!mysql_select_db(IA_DB_NAME, $dbLink)) {
35        log_error('Cannot select database.');
36    }
37    mysql_query('SET NAMES utf8');
38    return true;
39}
40
41function db_isalive() {
42    global $dbLink;
43
44    // Are we already connected?
45    if (is_resource($dbLink) && mysql_ping($dbLink)) {
46        return true;
47    }
48    return false;
49}
50
51// Keeps the database link up and running
52function db_keepalive() {
53    global $dbLink;
54
55    if (db_isalive()) {
56        return false;
57    }
58    if (is_resource($dbLink)) {
59        mysql_close($dbLink);
60    }
61
62    return db_connect();
63}
64
65// Escapes a string to be safely included in a query.
66function db_escape($str) {
67    return mysql_real_escape_string($str);
68}
69
70// Number of rows selected by the last SELECT statement
71function db_num_rows($res) {
72    return mysql_num_rows($res);
73}
74
75// Returns last SQL inserted id
76function db_insert_id() {
77    global $dbLink;
78
79    log_assert($dbLink);
80    return mysql_insert_id($dbLink);
81}
82
83// Returns number of affected rows by the last UPDATE/INSERT statement
84function db_affected_rows() {
85    global $dbLink;
86
87    log_assert($dbLink);
88    return mysql_affected_rows($dbLink);
89}
90
91// Executes query. Outputs error messages
92// Returns native PHP mysql resource handle
93function db_query($query, $unbuffered = false) {
94    global $dbLink;
95
96    // Make sure we are connected.
97    if (IA_DB_KEEP_ALIVE) {
98        db_keepalive();
99    }
100
101    // Disable unbuffered queries.
102    if (!IA_DB_MYSQL_UNBUFFERED_QUERY) {
103        $unbuffered = false;
104    }
105
106    // Do the query.
107    if ($unbuffered) {
108        $result = mysql_unbuffered_query($query, $dbLink);
109    } else {
110        $result = mysql_query($query, $dbLink);
111    }
112
113    if (!$result) {
114        // Query falied. Have we lost connection?
115        if (IA_DB_KEEP_ALIVE && db_keepalive()) {
116            // Try query again
117            return db_query($query, $unbuffered);
118        }
119        log_print("Query: '$query'");
120        log_error("MYSQL error: ".mysql_error($dbLink));
121    } else {
122        // Print query info.
123        //log_backtrace();
124        if (IA_LOG_SQL_QUERY && strpos($query, 'EXPLAIN') !== 0) {
125            log_print("SQL QUERY: '$query'");
126            if (!$unbuffered && strpos($query, 'SELECT') === 0) {
127                log_print("SQL QUERY ROWS: ".db_num_rows($result));
128            }
129        }
130        if (IA_LOG_SQL_QUERY_EXPLAIN && !$unbuffered &&
131                strpos($query, 'SELECT') === 0) {
132            // FIXME: pipes, proper format.
133            $explanation = db_fetch_all("EXPLAIN EXTENDED $query");
134            log_print("EXPLANATION:");
135            if (count($explanation) > 0) {
136                log_print('EXP: '.implode("\t", array_keys($explanation[0])));
137                foreach ($explanation as $exprow) {
138                    log_print('EXP: '.implode("\t", array_values($exprow)));
139                }
140            }
141        }
142    }
143
144    if (IA_DEVELOPMENT_MODE) {
145        global $execution_stats;
146        $execution_stats['queries']++;
147    }
148
149    return $result;
150}
151
152// Frees mysql result
153function db_free($result) {
154    log_assert(is_resource($result));
155    mysql_free_result($result);
156}
157
158// Fetches next result row
159function db_next_row($result) {
160    return mysql_fetch_assoc($result);
161}
162
163?>
Note: See TracBrowser for help on using the repository browser.