From 16a60253721330323ae201032f0b852697ce2a00 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 21 Mar 2013 23:04:17 +0100 Subject: [PATCH] [ticket/11469] Add SQL insert buffer allowing easier handling of multi inserts. 1. Tries to prevent going over max packet size by flushing to the database after a certain number of rows have been added. 2. Because of 1., it is less likely to reach a connection timeout when inserting a huge number of rows. 3. By flushing the buffer when a certain size is reached, memory usage should be lower compared to building the whole insert row set first. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 111 ++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 phpBB/includes/db/sql_insert_buffer.php diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php new file mode 100644 index 0000000000..8d4b03ef53 --- /dev/null +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -0,0 +1,111 @@ +db = $db; + $this->db_supports_multi_insert = $db->multi_insert; + $this->table_name = $table_name; + $this->max_buffered_rows = $max_buffered_rows; + } + + /** + * Inserts a single row into the buffer if multi insert is supported by the + * database (otherwise an insert query is sent immediately). Then flushes + * the buffer if the number of rows in the buffer is now greater than or + * equal to $max_buffered_rows. + * + * @param array $row + * + * @return null + */ + public function insert(array $row) + { + if (!$this->db_supports_multi_insert) + { + $this->db->sql_multi_insert($this->table_name, array($row)); + } + + $this->buffer[] = $row; + + if (sizeof($this->buffer) >= $this->max_buffered_rows) + { + $this->flush(); + } + } + + /** + * Inserts a row set, i.e. an array of rows, by calling insert(). + * + * Please note that it is in most cases better to use insert() instead of + * first building a huge rowset. Or at least sizeof($rows) should be kept + * small. + * + * @param array $rows + * + * @return null + */ + public function insert_all(array $rows) + { + foreach ($rows as $row) + { + $this->insert($row); + } + } + + /** + * Flushes the buffer content to the DB and clears the buffer. + * + * @return null + */ + public function flush() + { + if (!empty($this->buffer)) + { + $this->db->sql_multi_insert($this->table_name, $this->buffer); + $this->buffer = array(); + } + } +}