sbfaulkner-sequel_container 1.0.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.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 unwwwired.net
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,45 @@
1
+ # sequel\_container
2
+
3
+ contained documents (i.e. attachments) for sequel models
4
+
5
+ ## WHY?
6
+
7
+ I needed a way to more easily support images and css in blobs, since the hosting provider I'm using is read-only (except for the tmp folder) and I'm not ready to use Amazon, or any other external storage provider.
8
+
9
+ ## Installation
10
+
11
+ Run the following if you haven't already:
12
+
13
+ $ gem sources -a http://gems.github.com
14
+
15
+ Install the gem(s):
16
+
17
+ $ sudo gem install -r sbfaulkner-sequel_container
18
+
19
+ ## Example
20
+
21
+ require 'rubygems'
22
+ require 'sequel'
23
+
24
+ class User < Sequel::Model
25
+ set_schema do
26
+ primary_key :id
27
+ varchar :avatar_type, :size => 255
28
+ bytea :avatar_data
29
+ end
30
+ is :container, :tmp => File.dirname(__FILE__) + '/tmp'
31
+ contains :avatar
32
+ end
33
+
34
+ ## TODO
35
+
36
+ - remove frozen copy sequel gem when updateis released
37
+ - include logic for image width and height
38
+ - better assignment support (i.e. don't require separate assignment of type and data)
39
+ - publish in sequel www/pages/plugins
40
+ - other containment types... e.g. filesystem, s3, git?
41
+
42
+ ## Legal
43
+
44
+ **Author:** S. Brent Faulkner <brentf@unwwwired.net>
45
+ **License:** Copyright &copy; 2009 unwwwired.net, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+
5
+ load File.join(File.dirname(__FILE__),'sequel_container.gemspec')
6
+
7
+ Rake::GemPackageTask.new(SPEC) do |pkg|
8
+ end
9
+
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.pattern = 'test/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ Rake::Task[:test].comment = "Run the tests"
16
+
17
+ task :default => :test
@@ -0,0 +1,77 @@
1
+ require 'tmpdir'
2
+
3
+ module Sequel
4
+ module Plugins
5
+ module Container
6
+ def self.apply(model, options = {})
7
+ model.const_set "CONTAINER_TMPDIR", options[:tmp] || Dir.tmpdir
8
+ end
9
+
10
+ module ClassMethods
11
+ def contains(object, options = {})
12
+ return object.each { |o| contains(o, options) } if object.is_a? Array
13
+
14
+ container = table_name
15
+
16
+ class_eval <<-CONTAINED_PATH, __FILE__, __LINE__ + 1
17
+ def #{object}_path
18
+ return if #{object}_data.nil? || #{object}_data.empty?
19
+ @#{object}_path ||= write_#{object}
20
+ end
21
+ CONTAINED_PATH
22
+
23
+ class_eval <<-CONTAINED_URL, __FILE__, __LINE__ + 1
24
+ def #{object}_url
25
+ return if #{object}_data.nil? || #{object}_data.empty?
26
+ @#{object}_path ||= write_#{object}
27
+ @#{object}_url ||= "/#{container}/\#{id}/\#{#{object}_filename}"
28
+ end
29
+ CONTAINED_URL
30
+
31
+ class_eval <<-CONTAINED_IMAGE, __FILE__, __LINE__ + 1
32
+ def #{object}_image?
33
+ #{object}_type[0,6] == 'image/'
34
+ end
35
+ CONTAINED_IMAGE
36
+
37
+ class_eval <<-CONTAINED_DIRECTORY, __FILE__, __LINE__ + 1
38
+ def #{object}_directory
39
+ @asset_directory ||= FileUtils.mkdir_p(File.join(CONTAINER_TMPDIR, "#{container}", id.to_s))
40
+ end
41
+ protected :#{object}_directory
42
+ CONTAINED_DIRECTORY
43
+
44
+ class_eval <<-CONTAINED_FILENAME, __FILE__, __LINE__ + 1
45
+ def #{object}_filename
46
+ @#{object}_filename ||= "#{object}.\#{#{object}_extension}"
47
+ end
48
+ protected :#{object}_filename
49
+ CONTAINED_FILENAME
50
+
51
+ class_eval <<-CONTAINED_EXTENSION, __FILE__, __LINE__ + 1
52
+ def #{object}_extension
53
+ @#{object}_extension ||= case #{object}_type
54
+ when /^text\\\/plain/
55
+ 'txt'
56
+ when /^(?:image|text)\\\/(.*)/
57
+ $1
58
+ else
59
+ raise "unhandled asset type \#{#{object}_type}"
60
+ end
61
+ end
62
+ protected :#{object}_extension
63
+ CONTAINED_EXTENSION
64
+
65
+ class_eval <<-WRITE_CONTAINED, __FILE__, __LINE__ + 1
66
+ def write_#{object}
67
+ path = File.join(#{object}_directory, #{object}_filename)
68
+ File.open(path, 'w') { |file| file.write #{object}_data }
69
+ path
70
+ end
71
+ protected :write_#{object}
72
+ WRITE_CONTAINED
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,19 @@
1
+ SPEC = Gem::Specification.new do |s|
2
+ # identify the gem
3
+ s.name = "sequel_container"
4
+ s.version = "1.0.1"
5
+ s.author = "S. Brent Faulkner"
6
+ s.email = "brentf@unwwwired.net"
7
+ s.homepage = "http://github.com/sbfaulkner/sequel_container"
8
+ # platform of choice
9
+ s.platform = Gem::Platform::RUBY
10
+ # description of gem
11
+ s.summary = "contained documents (i.e. attachments) for sequel models"
12
+ s.files = %w(lib/sequel_container.rb MIT-LICENSE Rakefile README.markdown sequel_container.gemspec test/sequel_container_test.rb test/data/bio.html test/data/bio.txt test/data/logo.gif)
13
+ s.require_path = "lib"
14
+ s.test_file = "test/sequel_container_test.rb"
15
+ s.has_rdoc = true
16
+ s.extra_rdoc_files = ["README.markdown"]
17
+ s.add_dependency "sequel"
18
+ # s.rubyforge_project = "sequel_container"
19
+ end
@@ -0,0 +1,13 @@
1
+ <?xml version='1.0' encoding='utf-8' ?>
2
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
3
+ <html>
4
+ <head>
5
+ <title>biography</title>
6
+ </head>
7
+ <body>
8
+ <p>unwwwired.net is S. Brent Faulkner, an independent developer based in Caledon, Ontario with a wide range of experience from over 20 years in the software industry.</p>
9
+ </p>Working “closer to the metal” in C and C++ for many years, Brent's past projects included code generators, compilers and interpreters, mobile message switches and terminal emulators for UNIX and Windows.</p>
10
+ </p>More recently, he spent several years developing FileMaker Pro applications for the enterprise before being bitten by the Ruby on Rails bug.</p>
11
+ </p>Offering a wide variety of services, he has extensive experience with custom software development, web technologies, systems integration and system administration.</p>
12
+ </body>
13
+ </html>
data/test/data/bio.txt ADDED
@@ -0,0 +1,7 @@
1
+ unwwwired.net is S. Brent Faulkner, an independent developer based in Caledon, Ontario with a wide range of experience from over 20 years in the software industry.
2
+
3
+ Working “closer to the metal” in C and C++ for many years, Brent's past projects included code generators, compilers and interpreters, mobile message switches and terminal emulators for UNIX and Windows.
4
+
5
+ More recently, he spent several years developing FileMaker Pro applications for the enterprise before being bitten by the Ruby on Rails bug.
6
+
7
+ Offering a wide variety of services, he has extensive experience with custom software development, web technologies, systems integration and system administration.
Binary file
@@ -0,0 +1,73 @@
1
+ # get frozen copy of sequel with patched support for bytea escaping
2
+ $:.unshift File.dirname(__FILE__)+'/sequel-2.8.0.patched/lib'
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'sequel'
7
+
8
+ DB = Sequel.connect('postgres://postgres:p0stgr3s@localhost:5432/sequel_container_test')
9
+
10
+ class Company < Sequel::Model
11
+ set_schema do
12
+ primary_key :id
13
+ varchar :logo_type, :size => 255
14
+ bytea :logo_data
15
+ varchar :biography_type, :size => 255
16
+ bytea :biography_data
17
+ end
18
+ create_table!
19
+ is :container
20
+ contains [ :logo, :biography ]
21
+ end
22
+
23
+ class User < Sequel::Model
24
+ set_schema do
25
+ primary_key :id
26
+ varchar :avatar_type, :size => 255
27
+ bytea :avatar_data
28
+ end
29
+ create_table!
30
+ is :container, :tmp => File.dirname(__FILE__) + '/tmp'
31
+ contains :avatar
32
+ end
33
+
34
+ class SequelCascadingTest < Test::Unit::TestCase
35
+ def test_should_create_empty_container
36
+ company = Company.create
37
+ assert company.reload
38
+ assert_nil company.logo_type
39
+ assert_nil company.logo_data
40
+ assert_nil company.logo_path
41
+ assert_nil company.logo_url
42
+ end
43
+
44
+ def test_should_contain_image
45
+ logo = File.read(File.dirname(__FILE__)+'/data/logo.gif')
46
+ company = Company.create :logo_type => 'image/gif', :logo_data => logo
47
+ assert company.reload
48
+ assert company.logo_image?
49
+ assert_equal logo, company.logo_data
50
+ assert_equal Dir.tmpdir+"/companies/#{company.id}/logo.gif", company.logo_path
51
+ assert_equal "/companies/#{company.id}/logo.gif", company.logo_url
52
+ end
53
+
54
+ def test_should_contain_text
55
+ bio = File.read(File.dirname(__FILE__)+'/data/bio.txt')
56
+ company = Company.create :biography_type => 'text/plain', :biography_data => bio
57
+ assert company.reload
58
+ assert !company.biography_image?
59
+ assert_equal bio, company.biography_data
60
+ assert_equal Dir.tmpdir+"/companies/#{company.id}/biography.txt", company.biography_path
61
+ assert_equal "/companies/#{company.id}/biography.txt", company.biography_url
62
+ end
63
+
64
+ def test_should_contain_html
65
+ bio = File.read(File.dirname(__FILE__)+'/data/bio.html')
66
+ company = Company.create :biography_type => 'text/html', :biography_data => bio
67
+ assert company.reload
68
+ assert !company.biography_image?
69
+ assert_equal bio, company.biography_data
70
+ assert_equal Dir.tmpdir+"/companies/#{company.id}/biography.html", company.biography_path
71
+ assert_equal "/companies/#{company.id}/biography.html", company.biography_url
72
+ end
73
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sbfaulkner-sequel_container
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - S. Brent Faulkner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-11 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sequel
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description:
25
+ email: brentf@unwwwired.net
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - README.markdown
32
+ files:
33
+ - lib/sequel_container.rb
34
+ - MIT-LICENSE
35
+ - Rakefile
36
+ - README.markdown
37
+ - sequel_container.gemspec
38
+ - test/sequel_container_test.rb
39
+ - test/data/bio.html
40
+ - test/data/bio.txt
41
+ - test/data/logo.gif
42
+ has_rdoc: true
43
+ homepage: http://github.com/sbfaulkner/sequel_container
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.2.0
65
+ signing_key:
66
+ specification_version: 2
67
+ summary: contained documents (i.e. attachments) for sequel models
68
+ test_files:
69
+ - test/sequel_container_test.rb