1Mojo::Pg(3) User Contributed Perl Documentation Mojo::Pg(3)
2
3
4
6 Mojo::Pg - Mojolicious ♥ PostgreSQL
7
9 use Mojo::Pg;
10
11 # Use a PostgreSQL connection string for configuration
12 my $pg = Mojo::Pg->new('postgresql://postgres@/test');
13
14 # Select the server version
15 say $pg->db->query('select version() as version')->hash->{version};
16
17 # Use migrations to create a table
18 $pg->migrations->name('my_names_app')->from_string(<<EOF)->migrate;
19 -- 1 up
20 create table names (id serial primary key, name text);
21 -- 1 down
22 drop table names;
23 EOF
24
25 # Use migrations to drop and recreate the table
26 $pg->migrations->migrate(0)->migrate;
27
28 # Get a database handle from the cache for multiple queries
29 my $db = $pg->db;
30
31 # Use SQL::Abstract to generate simple CRUD queries for you
32 $db->insert('names', {name => 'Isabell'});
33 my $id = $db->select('names', ['id'], {name => 'Isabell'})->hash->{id};
34 $db->update('names', {name => 'Belle'}, {id => $id});
35 $db->delete('names', {name => 'Belle'});
36
37 # Insert a few rows in a transaction with SQL and placeholders
38 eval {
39 my $tx = $db->begin;
40 $db->query('insert into names (name) values (?)', 'Sara');
41 $db->query('insert into names (name) values (?)', 'Stefan');
42 $tx->commit;
43 };
44 say $@ if $@;
45
46 # Insert another row with SQL::Abstract and return the generated id
47 say $db->insert('names', {name => 'Daniel'}, {returning => 'id'})->hash->{id};
48
49 # JSON roundtrip
50 say $db->query('select ?::json as foo', {json => {bar => 'baz'}})
51 ->expand->hash->{foo}{bar};
52
53 # Select all rows blocking with SQL::Abstract
54 say $_->{name} for $db->select('names')->hashes->each;
55
56 # Select all rows non-blocking with SQL::Abstract
57 $db->select('names' => sub {
58 my ($db, $err, $results) = @_;
59 die $err if $err;
60 say $_->{name} for $results->hashes->each;
61 });
62 Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
63
64 # Concurrent non-blocking queries (synchronized with promises)
65 my $now = $pg->db->query_p('select now() as now');
66 my $names = $pg->db->query_p('select * from names');
67 Mojo::Promise->all($now, $names)->then(sub {
68 my ($now, $names) = @_;
69 say $now->[0]->hash->{now};
70 say $_->{name} for $names->[0]->hashes->each;
71 })->catch(sub {
72 my $err = shift;
73 warn "Something went wrong: $err";
74 })->wait;
75
76 # Send and receive notifications non-blocking
77 $pg->pubsub->listen(foo => sub {
78 my ($pubsub, $payload) = @_;
79 say "foo: $payload";
80 $pubsub->notify(bar => $payload);
81 });
82 $pg->pubsub->listen(bar => sub {
83 my ($pubsub, $payload) = @_;
84 say "bar: $payload";
85 });
86 $pg->pubsub->notify(foo => 'PostgreSQL rocks!');
87 Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
88
90 Mojo::Pg is a tiny wrapper around DBD::Pg that makes PostgreSQL
91 <http://www.postgresql.org> a lot of fun to use with the Mojolicious
92 <https://mojolicious.org> real-time web framework. Perform queries
93 blocking and non-blocking, use all SQL features
94 <https://www.postgresql.org/docs/current/static/sql.html> PostgreSQL
95 has to offer, generate CRUD queries from data structures, manage your
96 database schema with migrations and build scalable real-time web
97 applications with the publish/subscribe pattern.
98
100 Database and statement handles are cached automatically, and will be
101 reused transparently to increase performance. You can handle connection
102 timeouts gracefully by holding on to them only for short amounts of
103 time.
104
105 use Mojolicious::Lite;
106 use Mojo::Pg;
107
108 helper pg => sub { state $pg = Mojo::Pg->new('postgresql://postgres@/test') };
109
110 get '/' => sub {
111 my $c = shift;
112 my $db = $c->pg->db;
113 $c->render(json => $db->query('select now() as now')->hash);
114 };
115
116 app->start;
117
118 In this example application, we create a "pg" helper to store a
119 Mojo::Pg object. Our action calls that helper and uses the method "db"
120 in Mojo::Pg to dequeue a Mojo::Pg::Database object from the connection
121 pool. Then we use the method "query" in Mojo::Pg::Database to execute
122 an SQL <http://www.postgresql.org/docs/current/static/sql.html>
123 statement, which returns a Mojo::Pg::Results object. And finally we
124 call the method "hash" in Mojo::Pg::Results to retrieve the first row
125 as a hash reference.
126
127 While all I/O operations are performed blocking, you can wait for long
128 running queries asynchronously, allowing the Mojo::IOLoop event loop to
129 perform other tasks in the meantime. Since database connections usually
130 have a very low latency, this often results in very good performance.
131
132 Every database connection can only handle one active query at a time,
133 this includes asynchronous ones. To perform multiple queries
134 concurrently, you have to use multiple connections.
135
136 # Performed concurrently (5 seconds)
137 $pg->db->query('select pg_sleep(5)' => sub {...});
138 $pg->db->query('select pg_sleep(5)' => sub {...});
139
140 All cached database handles will be reset automatically if a new
141 process has been forked, this allows multiple processes to share the
142 same Mojo::Pg object safely.
143
145 And as your application grows, you can move queries into model classes.
146
147 package MyApp::Model::Time;
148 use Mojo::Base -base;
149
150 has 'pg';
151
152 sub now { shift->pg->db->query('select now() as now')->hash }
153
154 1;
155
156 Which get integrated into your application with helpers.
157
158 use Mojolicious::Lite;
159 use Mojo::Pg;
160 use MyApp::Model::Time;
161
162 helper pg => sub { state $pg = Mojo::Pg->new('postgresql://postgres@/test') };
163 helper time => sub { state $time = MyApp::Model::Time->new(pg => shift->pg) };
164
165 get '/' => sub {
166 my $c = shift;
167 $c->render(json => $c->time->now);
168 };
169
170 app->start;
171
173 This distribution also contains two great example applications
174 <https://github.com/kraih/mojo-pg/tree/master/examples/> you can use
175 for inspiration. The minimal chat <https://github.com/kraih/mojo-
176 pg/tree/master/examples/chat.pl> application will show you how to scale
177 WebSockets to multiple servers, and the well-structured blog
178 <https://github.com/kraih/mojo-pg/tree/master/examples/blog>
179 application how to apply the MVC design pattern in practice.
180
182 Mojo::Pg inherits all events from Mojo::EventEmitter and can emit the
183 following new ones.
184
185 connection
186 $pg->on(connection => sub {
187 my ($pg, $dbh) = @_;
188 ...
189 });
190
191 Emitted when a new database connection has been established.
192
193 $pg->on(connection => sub {
194 my ($pg, $dbh) = @_;
195 $dbh->do('set search_path to my_schema');
196 });
197
199 Mojo::Pg implements the following attributes.
200
201 abstract
202 my $abstract = $pg->abstract;
203 $pg = $pg->abstract(SQL::Abstract::Pg->new);
204
205 SQL::Abstract::Pg object used to generate CRUD queries for
206 Mojo::Pg::Database, defaults to enabling "array_datatypes" and setting
207 "name_sep" to "." and "quote_char" to """.
208
209 # Generate WHERE clause and bind values
210 my($stmt, @bind) = $pg->abstract->where({foo => 'bar', baz => 'yada'});
211
212 auto_migrate
213 my $bool = $pg->auto_migrate;
214 $pg = $pg->auto_migrate($bool);
215
216 Automatically migrate to the latest database schema with "migrations",
217 as soon as "db" has been called for the first time.
218
219 database_class
220 my $class = $pg->database_class;
221 $pg = $pg->database_class('MyApp::Database');
222
223 Class to be used by "db", defaults to Mojo::Pg::Database. Note that
224 this class needs to have already been loaded before "db" is called.
225
226 dsn
227 my $dsn = $pg->dsn;
228 $pg = $pg->dsn('dbi:Pg:dbname=foo');
229
230 Data source name, defaults to "dbi:Pg:".
231
232 max_connections
233 my $max = $pg->max_connections;
234 $pg = $pg->max_connections(3);
235
236 Maximum number of idle database handles to cache for future use,
237 defaults to 1.
238
239 migrations
240 my $migrations = $pg->migrations;
241 $pg = $pg->migrations(Mojo::Pg::Migrations->new);
242
243 Mojo::Pg::Migrations object you can use to change your database schema
244 more easily.
245
246 # Load migrations from file and migrate to latest version
247 $pg->migrations->from_file('/home/sri/migrations.sql')->migrate;
248
249 options
250 my $options = $pg->options;
251 $pg = $pg->options({AutoCommit => 1, RaiseError => 1});
252
253 Options for database handles, defaults to activating "AutoCommit",
254 "AutoInactiveDestroy" as well as "RaiseError" and deactivating
255 "PrintError" as well as "PrintWarn". Note that "AutoCommit" and
256 "RaiseError" are considered mandatory, so deactivating them would be
257 very dangerous.
258
259 parent
260 my $parent = $pg->parent;
261 $pg = $pg->parent(Mojo::Pg->new);
262
263 Another Mojo::Pg object to use for connection management, instead of
264 establishing and caching our own database connections.
265
266 password
267 my $password = $pg->password;
268 $pg = $pg->password('s3cret');
269
270 Database password, defaults to an empty string.
271
272 pubsub
273 my $pubsub = $pg->pubsub;
274 $pg = $pg->pubsub(Mojo::Pg::PubSub->new);
275
276 Mojo::Pg::PubSub object you can use to send and receive notifications
277 very efficiently, by sharing a single database connection with many
278 consumers.
279
280 # Subscribe to a channel
281 $pg->pubsub->listen(news => sub {
282 my ($pubsub, $payload) = @_;
283 say "Received: $payload";
284 });
285
286 # Notify a channel
287 $pg->pubsub->notify(news => 'PostgreSQL rocks!');
288
289 search_path
290 my $path = $pg->search_path;
291 $pg = $pg->search_path(['$user', 'foo', 'public']);
292
293 Schema search path assigned to all new connections.
294
295 # Isolate tests and avoid race conditions when running them in parallel
296 my $pg = Mojo::Pg->new('postgresql:///test')->search_path(['test_one']);
297 $pg->db->query('drop schema if exists test_one cascade');
298 $pg->db->query('create schema test_one');
299 ...
300 $pg->db->query('drop schema test_one cascade');
301
302 username
303 my $username = $pg->username;
304 $pg = $pg->username('sri');
305
306 Database username, defaults to an empty string.
307
309 Mojo::Pg inherits all methods from Mojo::EventEmitter and implements
310 the following new ones.
311
312 db
313 my $db = $pg->db;
314
315 Get a database object based on "database_class" (which is usually
316 Mojo::Pg::Database) for a cached or newly established database
317 connection. The DBD::Pg database handle will be automatically cached
318 again when that object is destroyed, so you can handle problems like
319 connection timeouts gracefully by holding on to it only for short
320 amounts of time.
321
322 # Add up all the money
323 say $pg->db->select('accounts')
324 ->hashes->reduce(sub { $a->{money} + $b->{money} });
325
326 from_string
327 $pg = $pg->from_string('postgresql://postgres@/test');
328 $pg = $pg->from_string(Mojo::Pg->new);
329
330 Parse configuration from connection string or use another Mojo::Pg
331 object as "parent".
332
333 # Just a database
334 $pg->from_string('postgresql:///db1');
335
336 # Just a service
337 $pg->from_string('postgresql://?service=foo');
338
339 # Username and database
340 $pg->from_string('postgresql://sri@/db2');
341
342 # Short scheme, username, password, host and database
343 $pg->from_string('postgres://sri:s3cret@localhost/db3');
344
345 # Username, domain socket and database
346 $pg->from_string('postgresql://sri@%2ftmp%2fpg.sock/db4');
347
348 # Username, database and additional options
349 $pg->from_string('postgresql://sri@/db5?PrintError=1&pg_server_prepare=0');
350
351 # Service and additional options
352 $pg->from_string('postgresql://?service=foo&PrintError=1&RaiseError=0');
353
354 # Username, database, an option and search_path
355 $pg->from_string('postgres://sri@/db6?&PrintError=1&search_path=test_schema');
356
357 new
358 my $pg = Mojo::Pg->new;
359 my $pg = Mojo::Pg->new('postgresql://postgres@/test');
360 my $pg = Mojo::Pg->new(Mojo::Pg->new);
361
362 Construct a new Mojo::Pg object and parse connection string with
363 "from_string" if necessary.
364
365 # Customize configuration further
366 my $pg = Mojo::Pg->new->dsn('dbi:Pg:service=foo');
367
369 You can set the "DBI_TRACE" environment variable to get some advanced
370 diagnostics information printed by DBI.
371
372 DBI_TRACE=1
373 DBI_TRACE=15
374 DBI_TRACE=SQL
375
377 This is the class hierarchy of the Mojo::Pg distribution.
378
379 · Mojo::Pg
380
381 · Mojo::Pg::Database
382
383 · Mojo::Pg::Migrations
384
385 · Mojo::Pg::PubSub
386
387 · Mojo::Pg::Results
388
389 · Mojo::Pg::Transaction
390
391 · SQL::Abstract::Pg
392
394 Sebastian Riedel, "sri@cpan.org".
395
397 In alphabetical order:
398
399 Christopher Eveland
400
401 Dan Book
402
403 Flavio Poletti
404
405 Hernan Lopes
406
407 Matt S Trout
408
409 Peter Rabbitson
410
411 William Lindley
412
414 Copyright (C) 2014-2018, Sebastian Riedel and others.
415
416 This program is free software, you can redistribute it and/or modify it
417 under the terms of the Artistic License version 2.0.
418
420 <https://github.com/kraih/mojo-pg>, Mojolicious::Guides,
421 <https://mojolicious.org>.
422
423
424
425perl v5.28.0 2018-05-08 Mojo::Pg(3)