|
@@ -1,36 +1,89 @@
|
|
|
MySQL/OTP + Poolboy
|
|
|
===================
|
|
|
|
|
|
-Status: Not complete and is work in progress.
|
|
|
+Status: **Work in progress**. This README is written with the assumption that #2, #3, #4 and #5 are solved. Some tests should be added as well.
|
|
|
|
|
|
-MySQL/OTP + Poolboy is a wrapper for [MySQL/OTP](//github.com/mysql-otp/mysql-otp) and
|
|
|
-[Poolboy](//github.com/devinus/poolboy) where you create connection pools for the former.
|
|
|
-Each application is itself responsible for supervising the pools, i.e. MySQL/OTP + Poolboy won't
|
|
|
-do it for you.
|
|
|
+**MySQL/OTP + Poolboy** provides connection pooling for [MySQL/OTP](//github.com/mysql-otp/mysql-otp) using [Poolboy](//github.com/devinus/poolboy). It provides convenience functions for executing
|
|
|
+SQL queries on a connection in a pool and lets you choose between two methods for createing
|
|
|
+and managing connection pools:
|
|
|
|
|
|
-Features:
|
|
|
+1. Use it as a library that helps you supervise your own MySQL connection pools.
|
|
|
+2. Use it as an application that manages its own supervisor for connection pools.
|
|
|
|
|
|
-* Simple pool creation
|
|
|
-* Convenience function to do queries and transactions
|
|
|
+I want to supervise my own connection pools
|
|
|
+-------------------------------------------
|
|
|
+
|
|
|
+Use `mysql_poolboy:child_spec/3` to get a supervisor child spec for a pool that you can use for
|
|
|
+your own supervisor.
|
|
|
+
|
|
|
+```Erlang
|
|
|
+%% my own supervisor
|
|
|
+init([]) ->
|
|
|
+ MySqlOptions = [{user, "aladdin"}, {password, "sesame"}, {database, "test"}],
|
|
|
+ PoolOptions = [{size, 10}, {max_overflow, 20}],
|
|
|
+ ChildSpecs = [
|
|
|
+ %% MySQL pools
|
|
|
+ mysql_poolboy:child_spec(pool1, MySqlOptions, PoolOptions),
|
|
|
+ %% other workers...
|
|
|
+ {some_other_worker, {some_other_worker, start_link, []},
|
|
|
+ permanent, 10, worker, [some_other_worker]}
|
|
|
+ ],
|
|
|
+ {ok, {{one_for_one, 10, 10}, ChildSpecs}}.
|
|
|
+```
|
|
|
+
|
|
|
+Let MySQL/OTP + Poolboy supervise my pools
|
|
|
+------------------------------------------
|
|
|
+
|
|
|
+This approach requires you to start the application using `application:ensure_started(mysql_poolboy)` (or by letting your release tool do this for you).
|
|
|
+
|
|
|
+Pools can be added at run-time using `mysql_poolboy:add_pool/3`.
|
|
|
+
|
|
|
+Pools can also be created at start-up by defining configuration parameters for `mysql_poolboy`. The name of each configuration parameter is the pool name and the value is a pair on the form `{MySqlOptions, PoolOptions}`.
|
|
|
+
|
|
|
+Example:
|
|
|
+
|
|
|
+Start your Erlang node with `erl -config mypools.config` where mypools.config:
|
|
|
+
|
|
|
+```Erlang
|
|
|
+{mysql_poolboy, [
|
|
|
+ {pool1, {[{user, "aladdin"}, {password, "sesame"}, {database, "test"}],
|
|
|
+ [{size, 10}, {max_overflow, 20}]}
|
|
|
+]}.
|
|
|
+```
|
|
|
+
|
|
|
+Using the connection pools
|
|
|
+--------------------------
|
|
|
+
|
|
|
+The most commonly used MySQL functions are available with wrappers in mysql_poolboy.
|
|
|
|
|
|
-Examples:
|
|
|
```Erlang
|
|
|
-%% Creates a pool with 5 connections and allows another 5 if there are none available.
|
|
|
-%% Returns a supvervise:child_spec()
|
|
|
-mysql_poolboy:add_pool(
|
|
|
- {mypool, [{size, 5}, {max_overflow, 10}],
|
|
|
- [{host, "localhost"}, {user, "foo"}, {password, "hello"}, {database, "test"}]}
|
|
|
-).
|
|
|
-
|
|
|
-%% Without using the convenience functions in mysql_poolboy.
|
|
|
-Conn = mysql_poolboy:checkout_connection(mypool).
|
|
|
-Result = mysql:query(Conn, "SELECT * FROM test_table").
|
|
|
-%% Should always return the connection when done.
|
|
|
-mysql_poolboy:checkin_connection(mypool, Conn).
|
|
|
-
|
|
|
-%% Using mysql_poolboy:query/2
|
|
|
-Result1 = mysql_poolboy:query(mypool, "SELECT * FROM test_table").
|
|
|
+1> mysql_poolboy:query(pool1, "SELECT * FROM foo WHERE id=?", [42]).
|
|
|
+{ok,[<<"id">>,<<"bar">>],[[42,<<"baz">>]]}
|
|
|
+2> mysql_poolboy:execute(pool1, [42]).
|
|
|
+{ok,[<<"id">>,<<"bar">>],[[42,<<"baz">>]]}
|
|
|
+```
|
|
|
+
|
|
|
+For transactions, the connection pid is passed to the transaction fun as the first parameter.
|
|
|
|
|
|
+```Erlang
|
|
|
+3> mysql_poolboy:transaction(pool1, fun (Pid) ->
|
|
|
+ ok = mysql:query(Pid, "INSERT INTO foo VALUES (?, ?)", [1, <<"banana">>]),
|
|
|
+ ok = mysql:query(Pid, "INSERT INTO foo VALUES (?, ?)", [2, <<"kiwi">>]),
|
|
|
+ hello
|
|
|
+ end).
|
|
|
+{atomic, hello}
|
|
|
+```
|
|
|
+
|
|
|
+Sometimes you need to checkout a connection to execute multiple queries on it, without wrapping it in an SQL transaction. For this purpose you can use either a pair of `checkout/1` and `checking/2` or a call to `with/2` with a fun.
|
|
|
+
|
|
|
+```Erlang
|
|
|
+4> mysql_poolboy:with(pool1, fun (Pid) ->
|
|
|
+ {ok, _, [[OldTz]]} = mysql:query(Pid, "SELECT @@time_zone"),
|
|
|
+ ok = mysql:query(Pid, "SET time_zone = '+00:00'"),
|
|
|
+ %% Do some stuff in the UTC time zone...
|
|
|
+ ok = mysql:query(Pid, "SET time_zone = ?", [OldTz])
|
|
|
+ end).
|
|
|
+ok
|
|
|
```
|
|
|
|
|
|
License
|