db 0.7.0 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5741adecd898ba3ad01d4d2ad42b51cf88de2084ce080c8494c65bc552728f25
4
- data.tar.gz: d94a215a5db2241ad142515c31911e27eebdba154c0855aa7f1b523a499862fc
3
+ metadata.gz: bdc24fd3f82f67c2497814f94088dd293a31ea6ac31f1e4a2915208d4b93ccf1
4
+ data.tar.gz: f9f993cf1f225ca8d959a1a86b97e584dd40e17fc26a6c6f39a8e532d3957ec9
5
5
  SHA512:
6
- metadata.gz: 5be7655b2006158c711551fce4674ca60278299fcc27e91cab13b617599c9a803e338270807547c08d0e810a94984449e3090684afcf682a097c71c1f2de8344
7
- data.tar.gz: e1c6cf1c0fad9a3b9e40602f575990f674792b2995a39da336f8489832379da4987dcd0b791ef8e4fa7031dfbefb97b90fa81a7adeeb65ebce7e502d8b0fee88
6
+ metadata.gz: '0087a87a73f5ae71c9fe5b2fabb864d44a5cac11b6a3d34db73303888b285fd3c592fecb2e37369f07d298fc4096b326a1a0f963e534cceaf82b4d2ff75da7ca'
7
+ data.tar.gz: 5f22a3f4e4653864089ad85c7cfeca5e8e3bf0cd9cb383653e114761d49e14e6ffd1e648f567556942269a31ba4f36cd04398fabfc112bc4364e62e1d8793827
data/lib/db.rb CHANGED
@@ -22,3 +22,4 @@
22
22
 
23
23
  require_relative 'db/version'
24
24
  require_relative 'db/adapters'
25
+ require_relative 'db/client'
data/lib/db/client.rb CHANGED
@@ -24,6 +24,7 @@ require 'async/io'
24
24
  require 'async/io/stream'
25
25
  require 'async/pool/controller'
26
26
 
27
+ require_relative 'context/generic'
27
28
  require_relative 'context/session'
28
29
  require_relative 'context/transaction'
29
30
 
@@ -47,18 +48,27 @@ module DB
47
48
  @pool.close
48
49
  end
49
50
 
51
+ # Acquire a generic context which will acquire a connection on demand.
52
+ def context(**options)
53
+ context = Context::Generic.new(@pool, **options)
54
+
55
+ return context unless block_given?
56
+
57
+ begin
58
+ yield context
59
+ ensure
60
+ context.close
61
+ end
62
+ end
63
+
50
64
  # Acquires a connection and sends the specified statement if given.
51
65
  # @parameters statement [String | Nil] An optional statement to send.
52
66
  # @yields {|session| ...} A connected session if a block is given. Implicitly closed.
53
67
  # @parameter session [Context::Session]
54
68
  # @returns [Context::Session] A connected session if no block is given.
55
- def session(statement = nil, **options)
69
+ def session(**options)
56
70
  session = Context::Session.new(@pool, **options)
57
71
 
58
- if statement
59
- session.send_query(statement)
60
- end
61
-
62
72
  return session unless block_given?
63
73
 
64
74
  begin
@@ -73,12 +83,10 @@ module DB
73
83
  # @yields {|session| ...} A connected session if a block is given. Implicitly commits, or aborts the connnection if an exception is raised.
74
84
  # @parameter session [Context::Transaction]
75
85
  # @returns [Context::Transaction] A connected and started transaction if no block is given.
76
- def transaction(statement = "BEGIN", **options)
86
+ def transaction(**options)
77
87
  transaction = Context::Transaction.new(@pool, **options)
78
88
 
79
- if statement
80
- transaction.call("BEGIN")
81
- end
89
+ transaction.call("BEGIN")
82
90
 
83
91
  return transaction unless block_given?
84
92
 
@@ -86,8 +94,9 @@ module DB
86
94
  yield transaction
87
95
 
88
96
  transaction.commit
89
- ensure
90
- transaction.abort if $!
97
+ rescue
98
+ transaction.abort
99
+ raise
91
100
  end
92
101
  end
93
102
 
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative '../query'
24
+
25
+ module DB
26
+ module Context
27
+ # A connected context for sending queries and reading results.
28
+ class Generic
29
+ # Iniitalize the query context attached to the given connection pool.
30
+ def initialize(pool, **options)
31
+ @pool = pool
32
+ @connection = nil
33
+ end
34
+
35
+ def connection?
36
+ @connection != nil
37
+ end
38
+
39
+ # Lazy initialize underlying connection.
40
+ def connection
41
+ @connection ||= @pool.acquire
42
+ end
43
+
44
+ # Flush the connection and then return it to the connection pool.
45
+ def close
46
+ if @connection
47
+ @pool.release(@connection)
48
+ @connection = nil
49
+ end
50
+ end
51
+
52
+ def query(fragment = String.new, **parameters)
53
+ if parameters.empty?
54
+ Query.new(self, fragment)
55
+ else
56
+ Query.new(self).interpolate(fragment, **parameters)
57
+ end
58
+ end
59
+
60
+ def clause(fragment = String.new)
61
+ Query.new(self, fragment)
62
+ end
63
+
64
+ # Send a query to the server.
65
+ # @parameter statement [String] The SQL query to send.
66
+ def call(statement, **options)
67
+ connection.send_query(statement, **options)
68
+
69
+ yield connection if block_given?
70
+ ensure
71
+ self.close
72
+ end
73
+ end
74
+ end
75
+ end
@@ -25,76 +25,15 @@ require_relative '../query'
25
25
  module DB
26
26
  module Context
27
27
  # A connected context for sending queries and reading results.
28
- class Session
29
- # Iniitalize the query context attached to the given connection pool.
30
- def initialize(pool, **options)
31
- @pool = pool
32
- @connection = pool.acquire
33
- end
34
-
35
- # The underlying connection.
36
- attr :connection
37
-
38
- # Flush the connection and then return it to the connection pool.
39
- def close
40
- if @connection
41
- self.flush
42
-
43
- @pool.release(@connection)
44
-
45
- @connection = nil
46
- end
47
- end
48
-
49
- def clause(*arguments)
50
- Query.new(self).clause(*arguments)
51
- end
52
-
53
- def query(fragment, **parameters)
54
- if parameters.empty?
55
- Query.new(self, fragment)
56
- else
57
- Query.new(self).interpolate(fragment, **parameters)
58
- end
59
- end
60
-
28
+ class Session < Generic
61
29
  # Send a query to the server.
62
30
  # @parameter statement [String] The SQL query to send.
63
- def send_query(statement, **options)
64
- # Console.logger.info(self, statement)
65
- @connection.send_query(statement, **options)
66
- end
67
-
68
- # Read the next result. Sending a query usually generates 1 or more results.
69
- # @returns [Enumerable] The resulting records.
70
- def next_result
71
- @connection.next_result
72
- end
73
-
74
- # Send a query to the server and read the next result.
75
- # @returns [Enumerable] The resulting records.
76
31
  def call(statement, **options)
77
- # Console.logger.info(self, statement)
78
- @connection.send_query(statement, **options)
32
+ connection = self.connection
79
33
 
80
- return @connection.next_result
81
- end
82
-
83
- # Enumerate all results.
84
- # @yields {|result ...} The results if a block is given.
85
- # @parameter result [Enumerable]
86
- def results
87
- while result = self.next_result
88
- yield result
89
- end
34
+ connection.send_query(statement, **options)
90
35
 
91
- return nil
92
- end
93
-
94
- # Flush all outstanding results.
95
- def flush
96
- until @connection.next_result.nil?
97
- end
36
+ yield connection if block_given?
98
37
  end
99
38
  end
100
39
  end
data/lib/db/query.rb CHANGED
@@ -23,22 +23,16 @@
23
23
  module DB
24
24
  # Represents one or more identifiers for databases, tables or columns.
25
25
  class Identifier < Array
26
- # Construct an identifier from an array of names.
27
- # e.g. `DB::Identifier[:mytable, :mycolumn]`
28
- #
29
- # @parameter names [Array] The array of names.
30
- def self.[](*names)
31
- self.new(names)
32
- end
33
-
34
26
  def self.coerce(name_or_identifier)
35
27
  case name_or_identifier
36
28
  when Identifier
37
29
  name_or_identifier
38
- when Symbol
30
+ when Array
39
31
  self.new(name_or_identifier)
32
+ when Symbol
33
+ self[name_or_identifier]
40
34
  else
41
- self.new(name_or_identifier.to_sym)
35
+ self[name_or_identifier.to_sym]
42
36
  end
43
37
  end
44
38
 
@@ -49,11 +43,11 @@ module DB
49
43
 
50
44
  # A mutable query builder.
51
45
  class Query
52
- # Create a new query builder attached to the specified session.
53
- # @parameter session [Context::Session] the connected session which is used for escaping arguments.
54
- def initialize(session, buffer = String.new)
55
- @session = session
56
- @connection = session.connection
46
+ # Create a new query builder attached to the specified context.
47
+ # @parameter context [Context::Generic] the context which is used for escaping arguments.
48
+ def initialize(context, buffer = String.new)
49
+ @context = context
50
+ @connection = context.connection
57
51
  @buffer = +buffer
58
52
  end
59
53
 
@@ -61,7 +55,7 @@ module DB
61
55
  # @parameter value [String] A raw SQL string, e.g. `WHERE x > 10`.
62
56
  # @returns [Query] The mutable query itself.
63
57
  def clause(value)
64
- @buffer << ' ' unless @buffer.end_with?(' ')
58
+ @buffer << ' ' unless @buffer.end_with?(' ') || @buffer.empty?
65
59
 
66
60
  @buffer << value
67
61
 
@@ -119,15 +113,16 @@ module DB
119
113
  return self
120
114
  end
121
115
 
122
- # Send the query to the remote server to be executed. See {Context::Session#send_query} for more details.
123
- def send
124
- @session.send_query(@buffer)
125
- end
126
-
127
116
  # Send the query to the remote server to be executed. See {Context::Session#call} for more details.
128
117
  # @returns [Enumerable] The resulting records.
129
- def call
130
- @session.call(@buffer)
118
+ def call(&block)
119
+ if block_given?
120
+ @context.call(@buffer, &block)
121
+ else
122
+ @context.call(@buffer) do |connection|
123
+ return connection.next_result
124
+ end
125
+ end
131
126
  end
132
127
 
133
128
  def to_s
data/lib/db/version.rb CHANGED
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module DB
24
- VERSION = "0.7.0"
24
+ VERSION = "0.10.2"
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-01 00:00:00.000000000 Z
11
+ date: 2021-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-io
@@ -89,6 +89,7 @@ files:
89
89
  - lib/db.rb
90
90
  - lib/db/adapters.rb
91
91
  - lib/db/client.rb
92
+ - lib/db/context/generic.rb
92
93
  - lib/db/context/session.rb
93
94
  - lib/db/context/transaction.rb
94
95
  - lib/db/query.rb