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 +4 -4
- data/lib/atech/object_store.rb +10 -8
- data/lib/atech/object_store/connection.rb +43 -0
- data/lib/atech/object_store/file.rb +18 -15
- data/lib/atech/object_store/version.rb +5 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66e598ae7b0fe9b6c113a6eddb9b537a932546eb
|
4
|
+
data.tar.gz: 651558ef45223a9f6882e4c3090813b6819b25ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1901b6334397f8796f6bdbb2d7bcb1fbb3ae5c75eb7d119f3fc8c1e1445c93f80348bc6abb7f18e371870969ac818569501dbe96f11a0840c94ec971d831cbc
|
7
|
+
data.tar.gz: 2fc2609f51c372a1e9a68b7ab75f6b3be15a87aaded85f609fe376e42e3800afdfee735c61b83489ccf06da5e94fe9e01ef3f53f872e80d0adcea7f55e4348a2
|
data/lib/atech/object_store.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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.
|
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
|
-
|
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
|
-
|
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
|
-
|
72
|
+
# Encode timestamps
|
71
73
|
options[:created_at] = options[:created_at].utc
|
72
74
|
options[:updated_at] = options[:updated_at].utc
|
73
75
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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(
|
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
|
-
"'#{
|
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
|
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:
|
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:
|
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.
|
57
|
+
rubygems_version: 2.5.1
|
42
58
|
signing_key:
|
43
59
|
specification_version: 4
|
44
60
|
summary: A SQL based object store library
|