objectstore 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3236943c5074458941ff9c00a1aba785c347d641
4
- data.tar.gz: ebb78024e581576a84bde92add4a39a12d17b667
3
+ metadata.gz: 66e598ae7b0fe9b6c113a6eddb9b537a932546eb
4
+ data.tar.gz: 651558ef45223a9f6882e4c3090813b6819b25ca
5
5
  SHA512:
6
- metadata.gz: fab4ae85a925ae2f04607844934f852dce4e5c98444a9eccb21c5bf933302ab38a1f7c161dd31e3040f0c6bb6080841e266fc7d1ca0bafeecfaa83d7467d705f
7
- data.tar.gz: 133179d6e5dd12f5703fe7e55c067dcd4748636408a2afed263fe9d7d796c698fa0c99a226b41c552c9b1006b4210428a1d880f6e20df4eb9146a55953959eac
6
+ metadata.gz: a1901b6334397f8796f6bdbb2d7bcb1fbb3ae5c75eb7d119f3fc8c1e1445c93f80348bc6abb7f18e371870969ac818569501dbe96f11a0840c94ec971d831cbc
7
+ data.tar.gz: 2fc2609f51c372a1e9a68b7ab75f6b3be15a87aaded85f609fe376e42e3800afdfee735c61b83489ccf06da5e94fe9e01ef3f53f872e80d0adcea7f55e4348a2
@@ -1,21 +1,23 @@
1
1
  module Atech
2
+ # Global module, contains configuration information
2
3
  module ObjectStore
3
- VERSION = '1.1.2'
4
-
5
4
  ## Error class which all Object Store errors are inherited fro
6
5
  class Error < StandardError; end
7
-
6
+
8
7
  class << self
9
- attr_accessor :backend
8
+ # Hash to be passed to Mysql2::Client when creating a new client
9
+ attr_accessor :backend_options
10
+
11
+ # Largest file that can be uploaded to the database
10
12
  attr_accessor :maximum_file_size
11
-
13
+
12
14
  def maximum_file_size
13
- @maximum_file_size ||= 1024 * 1024 * 1024
15
+ @maximum_file_size ||= 1024 * 1024 * 1024 # 1.megabyte
14
16
  end
15
-
16
17
  end
17
-
18
18
  end
19
19
  end
20
20
 
21
+ require 'atech/object_store/connection'
21
22
  require 'atech/object_store/file'
23
+ require 'atech/object_store/version'
@@ -0,0 +1,43 @@
1
+ module Atech
2
+ module ObjectStore
3
+ # A very simple connection pool. Allows as many connections as MySQL is happy to give us. Probably not
4
+ # compatible with a truly concurrent Ruby due to the use of Array#shift, but good enough for MRI
5
+ module Connection
6
+ @free_clients = []
7
+
8
+ # Get an available connection (or create a new one) and yield it to the passed block. Places the client into
9
+ # @free_clients once done.
10
+ #
11
+ # @yield [client] Block that wishes to access database
12
+ # @yieldparam [Mysql2::Client] client A mysql2 client just for this block
13
+ #
14
+ # @return [Object] Result of the block
15
+ def self.client
16
+ client = @free_clients.shift || new_client
17
+ return_value = nil
18
+ tries = 2
19
+ begin
20
+ return_value = yield client
21
+ rescue Mysql2::Error => e
22
+ if e.message =~ /(lost connection|gone away)/i && (tries -= 1) > 0
23
+ retry
24
+ else
25
+ raise
26
+ end
27
+ ensure
28
+ @free_clients << client
29
+ end
30
+ return_value
31
+ end
32
+
33
+ private
34
+
35
+ # Build a new Mysql2 client with the options suppplied in backend_options
36
+ #
37
+ # @return [Mysql2::Client] Fresh mysql2 client
38
+ def self.new_client
39
+ Mysql2::Client.new(Atech::ObjectStore.backend_options)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,7 +1,6 @@
1
1
  module Atech
2
2
  module ObjectStore
3
3
  class File
4
-
5
4
  ## Raised when a file cannot be found
6
5
  class FileNotFound < Error; end
7
6
 
@@ -14,10 +13,14 @@ module Atech
14
13
  ## Raised if the data is larger than the maximum file size
15
14
  class FileDataTooBig < Error; end
16
15
 
17
- ## Run a query on the backend database, attempt to run the query up to 3 times
16
+ # Run a single query on a backend connection. This should only be used when running a single query. If you need
17
+ # to do multiple things on the same connection (e.g. INSERT and then get LAST_INSERT_ID) you should checkot your
18
+ # own connection using ObejctStore::Connection.client
18
19
  def self.execute_query(query)
19
20
  tries ||= 3
20
- ObjectStore.backend.query(query)
21
+ ObjectStore::Connection.client do |client|
22
+ client.query(query)
23
+ end
21
24
  rescue Mysql2::Error => e
22
25
  retry unless (tries -= 1).zero?
23
26
  raise
@@ -52,32 +55,34 @@ module Atech
52
55
  ## Inserts a new File into the database. Returns a new object if successfully inserted or raises an error.
53
56
  ## Filename & data must be provided, options options will be added automatically unless specified.
54
57
  def self.add_file(filename, data = '', options = {})
55
-
56
58
  if data.bytesize > Atech::ObjectStore.maximum_file_size
57
59
  raise FileDataTooBig, "Data provided was #{data.bytesize} and the maximum size is #{Atech::ObjectStore.maximum_file_size}"
58
60
  end
59
61
 
60
- ## Create a hash of properties to be for this class
62
+ # Create a hash of properties to be for this class
61
63
  options[:name] = filename
62
64
  options[:size] ||= data.bytesize
63
65
  options[:blob] = data
64
66
  options[:created_at] ||= Time.now
65
67
  options[:updated_at] ||= Time.now
66
68
 
67
- ## Ensure that new files have a filename & data
69
+ # Ensure that new files have a filename & data
68
70
  raise ValidationError, "A 'name' must be provided to add a new file" if options[:name].nil?
69
71
 
70
- ## Encode timestamps
72
+ # Encode timestamps
71
73
  options[:created_at] = options[:created_at].utc
72
74
  options[:updated_at] = options[:updated_at].utc
73
75
 
74
- ##Create an insert query
75
- columns = options.keys.join('`,`')
76
- data = options.values.map { |data| escape_and_quote(data) }.join(',')
77
- File.execute_query("INSERT INTO files (`#{columns}`) VALUES (#{data})")
76
+ # Create an insert query
77
+ last_insert_id = ObjectStore::Connection.client do |client|
78
+ columns = options.keys.join('`,`')
79
+ data = options.values.map { |v| escape_and_quote(v) }.join(',')
80
+ client.query("INSERT INTO files (`#{columns}`) VALUES (#{data})")
81
+ client.last_id
82
+ end
78
83
 
79
84
  ## Return a new File object
80
- self.new(options.merge({:id => ObjectStore.backend.last_id}))
85
+ self.new(options.merge(:id => last_insert_id))
81
86
  end
82
87
 
83
88
  ## Initialises a new File object with the hash of attributes from a MySQL query ensuring that
@@ -179,14 +184,12 @@ module Atech
179
184
 
180
185
  def self.escape_and_quote(string)
181
186
  string = string.strftime('%Y-%m-%d %H:%M:%S') if string.is_a?(Time)
182
- "'#{ObjectStore.backend.escape(string.to_s)}'"
187
+ "'#{Mysql2::Client.escape(string.to_s)}'"
183
188
  end
184
189
 
185
190
  def self.time_now
186
191
  Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')
187
192
  end
188
-
189
-
190
193
  end
191
194
  end
192
195
  end
@@ -0,0 +1,5 @@
1
+ module Atech
2
+ module ObjectStore
3
+ VERSION = '2.0.0'.freeze
4
+ end
5
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: objectstore
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Cooke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-02 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2017-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mysql2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
13
27
  description:
14
28
  email: adam@atechmedia.com
15
29
  executables: []
@@ -17,7 +31,9 @@ extensions: []
17
31
  extra_rdoc_files: []
18
32
  files:
19
33
  - lib/atech/object_store.rb
34
+ - lib/atech/object_store/connection.rb
20
35
  - lib/atech/object_store/file.rb
36
+ - lib/atech/object_store/version.rb
21
37
  - schema.sql
22
38
  homepage: http://www.atechmedia.com
23
39
  licenses: []
@@ -38,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
54
  version: '0'
39
55
  requirements: []
40
56
  rubyforge_project:
41
- rubygems_version: 2.2.2
57
+ rubygems_version: 2.5.1
42
58
  signing_key:
43
59
  specification_version: 4
44
60
  summary: A SQL based object store library