objectstore 1.0.1 → 1.1.1
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 +7 -0
- data/lib/atech/object_store.rb +1 -1
- data/lib/atech/object_store/file.rb +49 -40
- metadata +9 -11
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5b01afd45b0b361d4516aa18767c132e93401fab
|
4
|
+
data.tar.gz: a46fdd53752e7a97eb61c4fc52e7240bb3c840aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f338aadabbe06fba2f9f33d8f306e26be7b35c204b0bed4fc98237a4643e1a13c4322750943b7ff82569681ad08d333b4b19d861869a9a4c7087fdb6bf5e96ba
|
7
|
+
data.tar.gz: 73103c73d496ac13040360a41fbd8692c602f2e321cf22fe07032f74e58a82ab0b82b57f6765ce96f96fc10e594565d65178f3c2490f79af32e39c95f3e49b4d
|
data/lib/atech/object_store.rb
CHANGED
@@ -1,26 +1,35 @@
|
|
1
1
|
module Atech
|
2
2
|
module ObjectStore
|
3
3
|
class File
|
4
|
-
|
4
|
+
|
5
5
|
## Raised when a file cannot be found
|
6
6
|
class FileNotFound < Error; end
|
7
|
-
|
7
|
+
|
8
8
|
## Raised if a file cannot be added
|
9
9
|
class ValidationError < Error; end
|
10
|
-
|
10
|
+
|
11
11
|
## Raised if a frozen file is editted
|
12
12
|
class CannotEditFrozenFile < Error; end
|
13
|
-
|
13
|
+
|
14
14
|
## Raised if the data is larger than the maximum file size
|
15
15
|
class FileDataTooBig < Error; end
|
16
|
-
|
16
|
+
|
17
|
+
## Run a query on the backend database, attempt to run the query up to 3 times
|
18
|
+
def self.execute_query(query)
|
19
|
+
tries ||= 3
|
20
|
+
ObjectStore.backend.query(query)
|
21
|
+
rescue Mysql2::Error => e
|
22
|
+
retry unless (tries -= 1).zero?
|
23
|
+
raise
|
24
|
+
end
|
25
|
+
|
17
26
|
## Returns a new file object for the given ID. If no file is found a FileNotFound exception will be raised
|
18
27
|
## otherwise the File object will be returned.
|
19
28
|
def self.find_by_id(id)
|
20
|
-
result =
|
29
|
+
result = File.execute_query("SELECT * FROM files WHERE id = #{id.to_i}").first || raise(FileNotFound, "File not found with id '#{id.to_i}'")
|
21
30
|
self.new(result)
|
22
31
|
end
|
23
|
-
|
32
|
+
|
24
33
|
## Imports a new file by passing a path and returning a new File object once it has been added to the database.
|
25
34
|
## If the file does not exist a ValidationError will be raised.
|
26
35
|
def self.add_local_file(path)
|
@@ -33,145 +42,145 @@ module Atech
|
|
33
42
|
raise ValidationError, "File does not exist at '#{path}' to add"
|
34
43
|
end
|
35
44
|
end
|
36
|
-
|
45
|
+
|
37
46
|
## Inserts a new File into the database. Returns a new object if successfully inserted or raises an error.
|
38
47
|
## Filename & data must be provided, options options will be added automatically unless specified.
|
39
48
|
def self.add_file(filename, data = '', options = {})
|
40
|
-
|
49
|
+
|
41
50
|
if data.bytesize > Atech::ObjectStore.maximum_file_size
|
42
51
|
raise FileDataTooBig, "Data provided was #{data.bytesize} and the maximum size is #{Atech::ObjectStore.maximum_file_size}"
|
43
52
|
end
|
44
|
-
|
53
|
+
|
45
54
|
## Create a hash of properties to be for this class
|
46
55
|
options[:name] = filename
|
47
56
|
options[:size] ||= data.bytesize
|
48
57
|
options[:blob] = data
|
49
58
|
options[:created_at] ||= Time.now
|
50
59
|
options[:updated_at] ||= Time.now
|
51
|
-
|
60
|
+
|
52
61
|
## Ensure that new files have a filename & data
|
53
62
|
raise ValidationError, "A 'name' must be provided to add a new file" if options[:name].nil?
|
54
|
-
|
63
|
+
|
55
64
|
## Encode timestamps
|
56
65
|
options[:created_at] = options[:created_at].utc
|
57
66
|
options[:updated_at] = options[:updated_at].utc
|
58
|
-
|
67
|
+
|
59
68
|
##Create an insert query
|
60
69
|
columns = options.keys.join('`,`')
|
61
70
|
data = options.values.map { |data| escape_and_quote(data) }.join(',')
|
62
|
-
|
71
|
+
File.execute_query("INSERT INTO files (`#{columns}`) VALUES (#{data})")
|
63
72
|
|
64
73
|
## Return a new File object
|
65
74
|
self.new(options.merge({:id => ObjectStore.backend.last_id}))
|
66
75
|
end
|
67
|
-
|
76
|
+
|
68
77
|
## Initialises a new File object with the hash of attributes from a MySQL query ensuring that
|
69
78
|
## all symbols are strings
|
70
79
|
def initialize(attributes)
|
71
80
|
@attributes = parsed_attributes(attributes)
|
72
81
|
end
|
73
|
-
|
82
|
+
|
74
83
|
## Returns details about the file
|
75
84
|
def inspect
|
76
85
|
"#<Atech::ObjectStore::File[#{id}] name=#{name}>"
|
77
86
|
end
|
78
|
-
|
87
|
+
|
79
88
|
## Returns the ID of the file
|
80
89
|
def id
|
81
90
|
@attributes['id']
|
82
91
|
end
|
83
|
-
|
92
|
+
|
84
93
|
## Returns the name of the file
|
85
94
|
def name
|
86
95
|
@attributes['name']
|
87
96
|
end
|
88
|
-
|
97
|
+
|
89
98
|
## Returns the size of the file as an integer
|
90
99
|
def size
|
91
100
|
@attributes['size'].to_i
|
92
101
|
end
|
93
|
-
|
102
|
+
|
94
103
|
## Returns the date the file was created
|
95
104
|
def created_at
|
96
105
|
@attributes['created_at']
|
97
106
|
end
|
98
|
-
|
107
|
+
|
99
108
|
## Returns the date the file was last updated
|
100
109
|
def updated_at
|
101
110
|
@attributes['updated_at']
|
102
111
|
end
|
103
|
-
|
112
|
+
|
104
113
|
## Returns the blob data
|
105
114
|
def blob
|
106
115
|
@attributes['blob']
|
107
116
|
end
|
108
|
-
|
117
|
+
|
109
118
|
## Returns whether this objec tis frozen or not
|
110
119
|
def frozen?
|
111
120
|
!!@frozen
|
112
121
|
end
|
113
|
-
|
122
|
+
|
114
123
|
## Downloads the current file to a path on your local server. If a file already exists at
|
115
124
|
## the path entered, it will be overriden.
|
116
125
|
def copy(path)
|
117
126
|
::File.open(path, 'w') { |f| f.write(blob) }
|
118
127
|
end
|
119
|
-
|
128
|
+
|
120
129
|
## Appends data to the end of the current blob and updates the size and update time as appropriate.
|
121
130
|
def append(data)
|
122
131
|
raise CannotEditFrozenFile, "This file has been frozen and cannot be appended to" if frozen?
|
123
|
-
|
132
|
+
File.execute_query("UPDATE files SET `blob` = CONCAT(`blob`, #{self.class.escape_and_quote(data)}), `size` = `size` + #{data.bytesize}, `updated_at` = '#{self.class.time_now}' WHERE id = #{@attributes['id']}")
|
124
133
|
reload(true)
|
125
134
|
end
|
126
|
-
|
135
|
+
|
127
136
|
## Overwrites any data which is stored in the file
|
128
137
|
def overwrite(data)
|
129
138
|
raise CannotEditFrozenFile, "This file has been frozen and cannot be overwriten" if frozen?
|
130
|
-
|
139
|
+
File.execute_query("UPDATE files SET `blob` = #{self.class.escape_and_quote(data)}, `size` = #{data.bytesize}, `updated_at` = '#{self.class.time_now}' WHERE id = #{@attributes['id']}")
|
131
140
|
@attributes['blob'] = data
|
132
141
|
reload
|
133
142
|
end
|
134
|
-
|
143
|
+
|
135
144
|
## Changes the name for a file
|
136
145
|
def rename(name)
|
137
146
|
raise CannotEditFrozenFile, "This file has been frozen and cannot be renamed" if frozen?
|
138
|
-
|
147
|
+
File.execute_query("UPDATE files SET `name` = #{self.class.escape_and_quote(name)}, `updated_at` = '#{self.class.time_now}' WHERE id = #{@attributes['id']}")
|
139
148
|
reload
|
140
149
|
end
|
141
|
-
|
150
|
+
|
142
151
|
## Removes the file from the database
|
143
152
|
def delete
|
144
153
|
raise CannotEditFrozenFile, "This file has been frozen and cannot be deleted" if frozen?
|
145
|
-
|
154
|
+
File.execute_query("DELETE FROM files WHERE id = #{@attributes['id']}")
|
146
155
|
@frozen = true
|
147
156
|
end
|
148
|
-
|
157
|
+
|
149
158
|
## Reload properties from the database. Optionally, pass true to include the blob
|
150
159
|
## in the update
|
151
160
|
def reload(include_blob = false)
|
152
|
-
query =
|
161
|
+
query = File.execute_query("SELECT #{include_blob ? '*' : '`id`, `name`, `size`, `created_at`, `updated_at`'} FROM files WHERE id = #{@attributes['id']}").first
|
153
162
|
@attributes.merge!(parsed_attributes(query))
|
154
163
|
end
|
155
|
-
|
164
|
+
|
156
165
|
private
|
157
|
-
|
166
|
+
|
158
167
|
def parsed_attributes(attributes)
|
159
168
|
attributes.inject(Hash.new) do |hash,(key,value)|
|
160
169
|
hash[key.to_s] = value
|
161
170
|
hash
|
162
171
|
end
|
163
172
|
end
|
164
|
-
|
173
|
+
|
165
174
|
def self.escape_and_quote(string)
|
166
175
|
string = string.strftime('%Y-%m-%d %H:%M:%S') if string.is_a?(Time)
|
167
176
|
"'#{ObjectStore.backend.escape(string.to_s)}'"
|
168
177
|
end
|
169
|
-
|
178
|
+
|
170
179
|
def self.time_now
|
171
180
|
Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')
|
172
181
|
end
|
173
|
-
|
174
|
-
|
182
|
+
|
183
|
+
|
175
184
|
end
|
176
185
|
end
|
177
186
|
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: objectstore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Adam Cooke
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-07-02 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description:
|
15
14
|
email: adam@atechmedia.com
|
@@ -17,31 +16,30 @@ executables: []
|
|
17
16
|
extensions: []
|
18
17
|
extra_rdoc_files: []
|
19
18
|
files:
|
20
|
-
- schema.sql
|
21
|
-
- lib/atech/object_store/file.rb
|
22
19
|
- lib/atech/object_store.rb
|
20
|
+
- lib/atech/object_store/file.rb
|
21
|
+
- schema.sql
|
23
22
|
homepage: http://www.atechmedia.com
|
24
23
|
licenses: []
|
24
|
+
metadata: {}
|
25
25
|
post_install_message:
|
26
26
|
rdoc_options: []
|
27
27
|
require_paths:
|
28
28
|
- lib
|
29
29
|
required_ruby_version: !ruby/object:Gem::Requirement
|
30
|
-
none: false
|
31
30
|
requirements:
|
32
|
-
- -
|
31
|
+
- - ">="
|
33
32
|
- !ruby/object:Gem::Version
|
34
33
|
version: '0'
|
35
34
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
35
|
requirements:
|
38
|
-
- -
|
36
|
+
- - ">="
|
39
37
|
- !ruby/object:Gem::Version
|
40
38
|
version: '0'
|
41
39
|
requirements: []
|
42
40
|
rubyforge_project:
|
43
|
-
rubygems_version:
|
41
|
+
rubygems_version: 2.2.2
|
44
42
|
signing_key:
|
45
|
-
specification_version:
|
43
|
+
specification_version: 4
|
46
44
|
summary: A SQL based object store library
|
47
45
|
test_files: []
|