objectstore 1.0.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -1,6 +1,6 @@
1
1
  module Atech
2
2
  module ObjectStore
3
- VERSION = '1.0.1'
3
+ VERSION = '1.1.1'
4
4
 
5
5
  ## Error class which all Object Store errors are inherited fro
6
6
  class Error < StandardError; end
@@ -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 = ObjectStore.backend.query("SELECT * FROM files WHERE id = #{id.to_i}").first || raise(FileNotFound, "File not found with id '#{id.to_i}'")
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
- ObjectStore.backend.query("INSERT INTO files (`#{columns}`) VALUES (#{data})")
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
- ObjectStore.backend.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']}")
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
- ObjectStore.backend.query("UPDATE files SET `blob` = #{self.class.escape_and_quote(data)}, `size` = #{data.bytesize}, `updated_at` = '#{self.class.time_now}' WHERE id = #{@attributes['id']}")
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
- ObjectStore.backend.query("UPDATE files SET `name` = #{self.class.escape_and_quote(name)}, `updated_at` = '#{self.class.time_now}' WHERE id = #{@attributes['id']}")
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
- ObjectStore.backend.query("DELETE FROM files WHERE id = #{@attributes['id']}")
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 = ObjectStore.backend.query("SELECT #{include_blob ? '*' : '`id`, `name`, `size`, `created_at`, `updated_at`'} FROM files WHERE id = #{@attributes['id']}").first
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.0.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: 2013-05-13 00:00:00.000000000 Z
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: 1.8.23
41
+ rubygems_version: 2.2.2
44
42
  signing_key:
45
- specification_version: 3
43
+ specification_version: 4
46
44
  summary: A SQL based object store library
47
45
  test_files: []