db 0.8.0 → 0.10.3

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: b99d4c7411ec402a465403035740d0ecec4827992808204a2f3e6a3ef6747f5f
4
- data.tar.gz: da794cd95025fbc95034ea0a7d48853ba5c57d7c0f3f3b2b5d312139628f5c11
3
+ metadata.gz: 58899749a83841be74872890b6d8486f43edd65cd6fdf03762b9e07e215332a9
4
+ data.tar.gz: 007506f94a8916a886b6e35c46f9003b6a7610fae308c7491b260ce9f5457a80
5
5
  SHA512:
6
- metadata.gz: 32c37129983d4b02a00eb42469a5be479909c24a2777c136eb2768f7ecb848b8061dad4f73ea7d5aa984b39a22f9295546a21122da548a2f529e6b5ffefe8ee3
7
- data.tar.gz: 90919ecaa9a3ab9aa715ee9ce38cc1deb622e6c515d343e9b2a92a8b4f6c7ff1655053cd0552e4c8a9f68837366acca29d9f7d838ee597e98f41b0e4e1e948d9
6
+ metadata.gz: 1558a94c7975d20124df67b8adf0f39ff9344af6d8ec54d49cfaeddffefe5b0593987fcf604ae41a8d383a730b393b1e8091c41c6a83b412ba9fc5ff495d54bf
7
+ data.tar.gz: f2ab71979b2f5f8e75c108313c8ae74016297f7c7d93aab9b4791085467d3dc37c3b47d3e54e7e610246bc22626e12e77f99afba4a02b6ffd66de26cb1be2fc4
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,21 +83,21 @@ 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
 
85
93
  begin
86
94
  yield transaction
87
95
 
88
- transaction.commit
96
+ rescue
97
+ transaction.abort
98
+ raise
89
99
  ensure
90
- transaction.abort if $!
100
+ transaction.commit?
91
101
  end
92
102
  end
93
103
 
@@ -0,0 +1,79 @@
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 closed?
53
+ @connection.nil?
54
+ end
55
+
56
+ def query(fragment = String.new, **parameters)
57
+ if parameters.empty?
58
+ Query.new(self, fragment)
59
+ else
60
+ Query.new(self).interpolate(fragment, **parameters)
61
+ end
62
+ end
63
+
64
+ def clause(fragment = String.new)
65
+ Query.new(self, fragment)
66
+ end
67
+
68
+ # Send a query to the server.
69
+ # @parameter statement [String] The SQL query to send.
70
+ def call(statement, **options)
71
+ connection.send_query(statement, **options)
72
+
73
+ yield connection if block_given?
74
+ ensure
75
+ self.close
76
+ end
77
+ end
78
+ end
79
+ 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 = String.new, **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
@@ -31,6 +31,12 @@ module DB
31
31
  self.close
32
32
  end
33
33
 
34
+ def commit?
35
+ unless self.closed?
36
+ self.commit
37
+ end
38
+ end
39
+
34
40
  # Abort the transaction and return the connection to the connection pool.
35
41
  def abort
36
42
  self.call("ROLLBACK")
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.8.0"
24
+ VERSION = "0.10.3"
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.8.0
4
+ version: 0.10.3
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-04 00:00:00.000000000 Z
11
+ date: 2021-05-27 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
@@ -112,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
113
  - !ruby/object:Gem::Version
113
114
  version: '0'
114
115
  requirements: []
115
- rubygems_version: 3.2.3
116
+ rubygems_version: 3.1.2
116
117
  signing_key:
117
118
  specification_version: 4
118
119
  summary: A low level database access gem.