db 0.6.0 → 0.10.1

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: def9c55f80bfb45766ffd249a05f9c449432259bf15e57a8e00b59dabc75dc91
4
- data.tar.gz: 8632f9630388c98ab4587c708acf8c1506edddcd8c29284a2b66446f4dbf799e
3
+ metadata.gz: ab70e3c0b34d5ba7f9ff40ffa216ece2a56ccc2409c05101e37691e73c7082c3
4
+ data.tar.gz: d2b813fef024e46e6ef001b3d60314b80244f80474302d344b9595d9a92cb84c
5
5
  SHA512:
6
- metadata.gz: 11f1c66a99d6dec1346f890c798efa65b77a3750e581a67dbcbbf20d970b6e5c30b337a4aeafd3d8375d68151585b6d74edc6b6cafaee4c539f6e857748424c0
7
- data.tar.gz: eb43e9b1077fc237acc6cde551aeaae5299ce8fa1f6b5580b5672ae1a3ecd9d5dcee6195344b56c6b5256af817c331af39fc79a0a3a5a60e0564c21ff4b0aa62
6
+ metadata.gz: be3efecea679ff23d9e3c43a0cc28d7bd8435e84698485f277ae06ebcdcc1b162dcfdec4e9159a9043d95da684fd9513ac71e1b04c483f48fa05c0babcb52bfa
7
+ data.tar.gz: 07a608ce4c87732a5ff2ce45a9f6357085c5c144902bdd4f6d05bdc829076ec016d41062115112c45795838dd20d5edc7d9fabb89dd098443888463018048ff6
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).clause(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,30 +23,39 @@
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)
26
+ def self.coerce(name_or_identifier)
27
+ case name_or_identifier
28
+ when Identifier
29
+ name_or_identifier
30
+ when Array
31
+ self.new(name_or_identifier)
32
+ when Symbol
33
+ self[name_or_identifier]
34
+ else
35
+ self[name_or_identifier.to_sym]
36
+ end
37
+ end
38
+
39
+ def append_to(query)
40
+ query.identifier(self)
32
41
  end
33
42
  end
34
43
 
35
44
  # A mutable query builder.
36
45
  class Query
37
- # Create a new query builder attached to the specified session.
38
- # @parameter session [Context::Session] the connected session which is used for escaping arguments.
39
- def initialize(session)
40
- @session = session
41
- @connection = session.connection
42
- @buffer = String.new
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
51
+ @buffer = +buffer
43
52
  end
44
53
 
45
54
  # Append a raw textual clause to the query buffer.
46
55
  # @parameter value [String] A raw SQL string, e.g. `WHERE x > 10`.
47
56
  # @returns [Query] The mutable query itself.
48
57
  def clause(value)
49
- @buffer << ' ' unless @buffer.end_with?(' ')
58
+ @buffer << ' ' unless @buffer.end_with?(' ') || @buffer.empty?
50
59
 
51
60
  @buffer << value
52
61
 
@@ -98,15 +107,24 @@ module DB
98
107
  return self
99
108
  end
100
109
 
101
- # Send the query to the remote server to be executed. See {Context::Session#send_query} for more details.
102
- def send
103
- @session.send_query(@buffer)
110
+ def key_column(*arguments, **options)
111
+ @buffer << @connection.key_column(*arguments, **options)
112
+
113
+ return self
104
114
  end
105
115
 
106
116
  # Send the query to the remote server to be executed. See {Context::Session#call} for more details.
107
117
  # @returns [Enumerable] The resulting records.
108
- def call
109
- @session.call(@buffer)
118
+ def call(&block)
119
+ @context.call(@buffer, &block)
120
+ end
121
+
122
+ def to_s
123
+ @buffer
124
+ end
125
+
126
+ def inspect
127
+ "\#<#{self.class} #{@buffer.inspect}>"
110
128
  end
111
129
  end
112
130
  end
data/lib/db/version.rb CHANGED
@@ -21,5 +21,5 @@
21
21
  # THE SOFTWARE.
22
22
 
23
23
  module DB
24
- VERSION = "0.6.0"
24
+ VERSION = "0.10.1"
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.6.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-07 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
@@ -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.1.2
116
+ rubygems_version: 3.2.3
116
117
  signing_key:
117
118
  specification_version: 4
118
119
  summary: A low level database access gem.