Skip to content

Commit cafeeb2

Browse files
committed
examples: add Simple Query example
1 parent cafe0f9 commit cafeeb2

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

examples/simple_query.cr

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env crystal
2+
require "../src/pg"
3+
4+
# A small example on how to use the underlying driver to execute Simple Query messages
5+
# https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-SIMPLE-QUERY
6+
7+
class SimpleConnection < PQ::Connection
8+
def self.connect(conninfo)
9+
new(conninfo).tap(&.connect)
10+
end
11+
12+
# Run a single query using the Postgres Simple Query protocol
13+
# - Yields each row as an Array(String?)
14+
# - Returns the row description
15+
#
16+
# NOTE: While this protocol supports more than one statement per message,
17+
# this very basic client implementaiton does not, and will error out on the
18+
# call expecting the ReadyForQuery frame.
19+
def sq(query, &) : Array(PQ::Field)
20+
send_query_message(query)
21+
fields = case (frame = read)
22+
when PQ::Frame::RowDescription
23+
read_all_data_rows { |row| yield row.map { |col| col && String.new col } }
24+
frame.fields
25+
when PQ::Frame::CommandComplete, PQ::Frame::EmptyQueryResponse
26+
[] of PQ::Field
27+
else
28+
raise "expected RowDescription or NoData, got #{frame}"
29+
end
30+
31+
expect_frame PQ::Frame::ReadyForQuery
32+
fields
33+
end
34+
35+
# ingore any rows in the results
36+
def sq(query)
37+
sq(query) { }
38+
end
39+
end
40+
41+
conn = SimpleConnection.connect PQ::ConnInfo.new
42+
43+
conn.sq("select generate_series(1,10), now()") { |row| p row }
44+
conn.sq("notify foo")
45+
conn.sq("")
46+
conn.sq("select 1/0") { |r| p r } rescue "caught error"
47+
conn.sq("select 'hello', null, 7*2, 'ok'") { |r| p r }
48+
49+
# Will not work:
50+
# conn.sq("select 1; select 2") { |r| p r }

0 commit comments

Comments
 (0)