ambry 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Ambry Changelog
2
2
 
3
- ## [0.2.4](https://github.com/norman/ambry/tree/0.2.3) - 2011-10-07 ([diff](https://github.com/norman/ambry/compare/0.2.3...0.2.4))
3
+ ## [0.3.0](https://github.com/norman/ambry/tree/0.3.0) - 2012-03-15 ([diff](https://github.com/norman/ambry/compare/0.2.4...0.3.0))
4
+
5
+ ### [Norman Clarke](https://github.com/norman)
6
+
7
+ * Don't raise from finds using hash proxy when a key has a falsy value
8
+ * Remove cookie adapter; keep Ambry focused on its core mission.
9
+ * Fixed bug which allowed invalid records to be saved with Active Model. Thanks Tute Costa for reporting.
10
+
11
+ ## [0.2.4](https://github.com/norman/ambry/tree/0.2.4) - 2011-10-07 ([diff](https://github.com/norman/ambry/compare/0.2.3...0.2.4))
4
12
 
5
13
  ### [Norman Clarke](https://github.com/norman)
6
14
 
data/README.md CHANGED
@@ -6,8 +6,7 @@ library with plain old Ruby objects that are searchable via a fast, simple
6
6
  database-like API.
7
7
 
8
8
  It implements Active Model and has generators to integrate nicely with Rails.
9
- You can store your data in a file, a signed string suitable for storage in a
10
- cookie, or easily write your own IO adapter.
9
+ You can store your data in either YAML or dump file.
11
10
 
12
11
  For more info, take a peek at the
13
12
  [docs](http://rubydoc.info/github/ambry/ambry/master/frames), or read on for some
data/extras/countries.rb CHANGED
@@ -3,8 +3,6 @@
3
3
  require "bundler/setup"
4
4
  require "ambry"
5
5
 
6
- Ambry::Adapter.new
7
-
8
6
  class Country
9
7
  extend Ambry::Model
10
8
  field :tld, :name, :population, :region
@@ -49,6 +49,14 @@ module Ambry
49
49
  new(*args).save!
50
50
  end
51
51
 
52
+ # Create and save a model instance, returning false if any errors
53
+ # occur.
54
+ def create(*args)
55
+ new(*args).save!
56
+ rescue AmbryError
57
+ false
58
+ end
59
+
52
60
  # Validate the uniqueness of a field's value in a model instance.
53
61
  def validates_uniqueness_of(*attr_names)
54
62
  validates_with Validations::Uniqueness, _merge_attributes(attr_names)
@@ -88,6 +96,7 @@ module Ambry
88
96
  end
89
97
 
90
98
  def save
99
+ return false unless valid?
91
100
  run_callbacks(:save) do
92
101
  @new_record = false
93
102
  super
@@ -117,6 +126,10 @@ module Ambry
117
126
  def update_attributes(*args)
118
127
  run_callbacks(:save) { update(*args) }
119
128
  end
129
+
130
+ def to_partial_path
131
+ "#{self.class.name.pluralize.underscore}/#{self.class.name.underscore}"
132
+ end
120
133
  end
121
134
  end
122
135
  end
@@ -12,7 +12,13 @@ module Ambry
12
12
 
13
13
  # Allows accessing a hash attribute as a method.
14
14
  def method_missing(symbol)
15
- hash[symbol] or hash[symbol.to_s] or raise NoMethodError
15
+ if hash.key?(symbol)
16
+ hash[symbol]
17
+ elsif hash.key?(symbol.to_s)
18
+ hash[symbol.to_s]
19
+ else
20
+ raise NoMethodError
21
+ end
16
22
  end
17
23
 
18
24
  # Allows accessing a hash attribute as hash key, either a string or symbol.
data/lib/ambry/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Ambry
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 2
5
- TINY = 4
4
+ MINOR = 3
5
+ TINY = 0
6
6
  BUILD = nil
7
7
  STRING = [MAJOR, MINOR, TINY, BUILD].compact.join('.')
8
8
  end
@@ -59,6 +59,24 @@ describe Ambry::ActiveModel do
59
59
  end
60
60
  end
61
61
 
62
+ describe "#create" do
63
+ it "should not store invalid model instances" do
64
+ old_count = Book.count
65
+ Book.create({})
66
+ assert_equal old_count, Book.count
67
+ end
68
+ end
69
+
70
+ describe "#save" do
71
+ it "should not store invalid model instances" do
72
+ old_count = Book.count
73
+ book = Book.new
74
+ assert !book.valid?
75
+ book.save
76
+ assert_equal old_count, Book.count
77
+ end
78
+ end
79
+
62
80
  describe "#to_json" do
63
81
  it "should serialize" do
64
82
  json = @model.to_json
@@ -86,7 +104,9 @@ describe Ambry::ActiveModel do
86
104
 
87
105
  describe "callbacks" do
88
106
  it "should fire save callbacks" do
107
+ Book.mapper.clear
89
108
  book = Book.new valid_book
109
+ assert book.valid?
90
110
  book.save
91
111
  assert book.instance_variable_defined? :@save_callback_fired
92
112
  end
@@ -112,4 +132,11 @@ describe Ambry::ActiveModel do
112
132
  assert @book.valid?
113
133
  end
114
134
  end
135
+
136
+ describe "to_partial_path" do
137
+ it "should return something reasonable" do
138
+ assert_equal "books/book", Book.new.to_partial_path
139
+ end
140
+ end
141
+
115
142
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ambry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-24 00:00:00.000000000 Z
12
+ date: 2012-03-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffaker
16
- requirement: &70331994375060 !ruby/object:Gem::Requirement
16
+ requirement: &70196828901600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70331994375060
24
+ version_requirements: *70196828901600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &70331994374560 !ruby/object:Gem::Requirement
27
+ requirement: &70196828901100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.2.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70331994374560
35
+ version_requirements: *70196828901100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: mocha
38
- requirement: &70331994374100 !ruby/object:Gem::Requirement
38
+ requirement: &70196828900640 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70331994374100
46
+ version_requirements: *70196828900640
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activesupport
49
- requirement: &70331994373520 !ruby/object:Gem::Requirement
49
+ requirement: &70196828900020 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '3.0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70331994373520
57
+ version_requirements: *70196828900020
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: activemodel
60
- requirement: &70331994373020 !ruby/object:Gem::Requirement
60
+ requirement: &70196828915860 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '3.0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70331994373020
68
+ version_requirements: *70196828915860
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
- requirement: &70331994372560 !ruby/object:Gem::Requirement
71
+ requirement: &70196828915480 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70331994372560
79
+ version_requirements: *70196828915480
80
80
  description: ! " Ambry is not an ORM, man! It's a database and ORM replacement
81
81
  for (mostly)\n static models and small datasets. It provides ActiveModel compatibility,
82
82
  and\n flexible searching and storage.\n"
@@ -93,13 +93,11 @@ files:
93
93
  - Rakefile
94
94
  - ambry.gemspec
95
95
  - extras/bench.rb
96
- - extras/cookie_demo.rb
97
96
  - extras/countries.rb
98
97
  - lib/ambry.rb
99
98
  - lib/ambry/abstract_key_set.rb
100
99
  - lib/ambry/active_model.rb
101
100
  - lib/ambry/adapter.rb
102
- - lib/ambry/adapters/cookie.rb
103
101
  - lib/ambry/adapters/file.rb
104
102
  - lib/ambry/adapters/yaml.rb
105
103
  - lib/ambry/hash_proxy.rb
@@ -107,10 +105,8 @@ files:
107
105
  - lib/ambry/model.rb
108
106
  - lib/ambry/version.rb
109
107
  - lib/generators/ambry_generator.rb
110
- - lib/rack/ambry.rb
111
108
  - spec/active_model_spec.rb
112
109
  - spec/adapter_spec.rb
113
- - spec/cookie_adapter_spec.rb
114
110
  - spec/file_adapter_spec.rb
115
111
  - spec/fixtures.yml
116
112
  - spec/key_set_spec.rb
@@ -137,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
133
  version: '0'
138
134
  requirements: []
139
135
  rubyforge_project: ! '[none]'
140
- rubygems_version: 1.8.10
136
+ rubygems_version: 1.8.11
141
137
  signing_key:
142
138
  specification_version: 3
143
139
  summary: An ActiveModel-compatible ORM-like library for storing model instances in
@@ -1,111 +0,0 @@
1
- $LOAD_PATH << File.expand_path("../../lib", __FILE__)
2
- $LOAD_PATH.uniq!
3
-
4
- require "rubygems"
5
- require "sinatra"
6
- require "haml"
7
- require "babosa"
8
- require "date"
9
- require "ambry"
10
- require "ambry/adapters/cookie"
11
- require "rack/ambry"
12
-
13
- set :session, false
14
-
15
- use Rack::Cookies
16
- use Rack::Ambry, :name => :cookie, :secret => "Sssshhhh! This is a secret."
17
-
18
- class Book
19
- extend Ambry::Model
20
- field :slug, :title, :author
21
- use :cookie
22
-
23
- def title=(value)
24
- @slug = value.to_slug.normalize.to_s
25
- @title = value
26
- end
27
- end
28
-
29
- get "/" do
30
- @header = "Books"
31
- @books = Book.all
32
- haml :index
33
- end
34
-
35
- get "/books/new" do
36
- @header = "Add a Book"
37
- @action = "/books"
38
- haml :new
39
- end
40
-
41
- get "/books/:slug/edit" do |slug|
42
- @book = Book.get(slug)
43
- @action = "/books"
44
- @header = @book.title
45
- params[:title] = @book.title
46
- params[:author] = @book.author
47
- haml :edit
48
- end
49
-
50
- get "/books/:slug" do |slug|
51
- @book = Book.get(slug)
52
- @header = @book.title
53
- haml :book
54
- end
55
-
56
- post "/books" do
57
- Book.delete params[:slug] if params[:slug]
58
- @book = Book.create params if params[:title]
59
- redirect "/"
60
- end
61
-
62
- __END__
63
- @@layout
64
- !!! 5
65
- %html
66
- %head
67
- %meta(http-equiv="Content-Type" content="text/html; charset=utf-8")
68
- %title Ambry Cookie Adapter Demo
69
- %body
70
- %h2= @header
71
- = yield
72
-
73
- @@edit
74
- = haml(:form, :layout => false)
75
-
76
- @@index
77
- %ul
78
- - @books.each do |book|
79
- %li= '<a href="/books/%s">%s</a>' % [book.slug, book.title, book.author]
80
- %p.controls
81
- <a href="/books/new">New book</a>
82
-
83
- @@new
84
- = haml(:form, :layout => false)
85
- %p.controls
86
- <a href="/">Books</a>
87
-
88
- @@book
89
- by #{@book.author}
90
- %p.controls
91
- <a href="/">Books</a>
92
- <a href="/books/#{@book.slug}/edit">Edit</a>
93
-
94
- @@form
95
- %form(method="post" enctype="utf-8" action=@action)
96
- %p
97
- - if @book
98
- %input#slug{:type => "hidden", :value => @book.slug, :name => "slug"}
99
- %label(for="title") Title:
100
- %br
101
- %input#title{:type => "text", :value => params[:title], :name => "title"}
102
- %p
103
- %label(for="author") Author:
104
- %br
105
- %input#author{:type => "text", :value => params[:author], :name => "author"}
106
- %p
107
- %input(type="submit" value="save it")
108
- - if @book
109
- %form{:method => "post", :enctype => "utf-8", :action => "/books"}
110
- %input#slug{:type => "hidden", :value => @book.slug, :name => "slug"}
111
- %input(type="submit" value="or delete it")
@@ -1,55 +0,0 @@
1
- require "active_support"
2
- require "active_support/message_verifier"
3
- require "zlib"
4
-
5
- module Ambry
6
- module Adapters
7
-
8
- # Ambry's cookie adapter allows you to store a Ambry database inside
9
- # a zipped and signed string suitable for setting as a cookie. This can be
10
- # useful for modelling things like basic shopping carts or form wizards.
11
- # Keep in mind the data is signed, so it can't be tampered with. However,
12
- # the data is not *encrypted*, so somebody that wanted to could unzip and
13
- # load the cookie data to see what's inside. So don't send this data
14
- # client-side if it's at all sensitive.
15
- class Cookie < Adapter
16
-
17
- attr :verifier
18
- attr_accessor :data
19
-
20
- MAX_DATA_LENGTH = 4096
21
-
22
- def self.max_data_length
23
- MAX_DATA_LENGTH
24
- end
25
-
26
- def initialize(options)
27
- @data = options[:data]
28
- @verifier = ActiveSupport::MessageVerifier.new(options[:secret])
29
- super
30
- end
31
-
32
- def export_data
33
- cookie = verifier.generate(Zlib::Deflate.deflate(Marshal.dump(db)))
34
- length = cookie.bytesize
35
- if length > Cookie.max_data_length
36
- raise(AmbryError, "Data is %s bytes, cannot exceed %s" % [length, Cookie.max_data_length])
37
- end
38
- cookie
39
- end
40
-
41
- def import_data
42
- (!data || data.empty?) ? {} : Marshal.load(Zlib::Inflate.inflate(verifier.verify(data)))
43
- end
44
-
45
- def load_database
46
- @db = import_data
47
- @db.map(&:freeze)
48
- end
49
-
50
- def save_database
51
- @data = export_data
52
- end
53
- end
54
- end
55
- end
data/lib/rack/ambry.rb DELETED
@@ -1,23 +0,0 @@
1
- require "rack/contrib"
2
-
3
- module Rack
4
- # Rack::Ambry is a middleware that allows you to store a Ambry datbase
5
- # in a cookie.
6
- # @see Ambry::Adapters::Cookie
7
- class Ambry
8
- def initialize(app, options = {})
9
- @app = app
10
- options = options.call if options.respond_to? :call
11
- @cookie_name = options.delete(:cookie_name) || "ambry_data"
12
- @ambry = ::Ambry::Adapters::Cookie.new(options.merge(:sync => true))
13
- end
14
-
15
- def call(env)
16
- @ambry.data = env["rack.cookies"][@cookie_name]
17
- @ambry.load_database
18
- status, headers, body = @app.call(env)
19
- env["rack.cookies"][@cookie_name] = @ambry.export_data
20
- [status, headers, body]
21
- end
22
- end
23
- end
@@ -1,81 +0,0 @@
1
- require File.expand_path("../spec_helper", __FILE__)
2
- require "ambry/adapters/cookie"
3
-
4
- class User
5
- extend Ambry::Model
6
- field :email, :name
7
- end
8
-
9
- module CookieAdapterSpecHelpers
10
- def secret
11
- "ssssshh... this is a secret!"
12
- end
13
-
14
- def sample_data
15
- # hash = {"User" => {valid_user[:email] => valid_user}}
16
- # p ActiveSupport::MessageVerifier.new(secret).generate(Zlib::Deflate.deflate(Marshal.dump(hash)))
17
- "BAgiTnicY+GoZvNU4gwtTi1is2JzDQHxhLPyUx2KkzNy81P1kvNz2awZQqrZrTjzEnNTPZX4" +
18
- "vfJTFYLBkiAJK67U3MTMHKyaAJGaGlk=--08913fe1c677e4bb0dd34ef90fb22f9027e587f4"
19
- end
20
-
21
- def valid_user
22
- @valid_user ||= {:name => "Joe Schmoe", :email => "joe@schmoe.com"}
23
- end
24
-
25
- def load_fixtures
26
- Ambry.adapters.clear
27
- @adapter = Ambry::Adapters::Cookie.new \
28
- :name => :cookie,
29
- :secret => secret
30
- User.use :cookie, :sync => true
31
- end
32
- end
33
-
34
- describe Ambry::Adapters::Cookie do
35
-
36
- include CookieAdapterSpecHelpers
37
-
38
- before { load_fixtures }
39
- after { Ambry.adapters.clear }
40
-
41
- describe Ambry::Adapters::Cookie do
42
-
43
- describe "#initialize" do
44
- it "should decode signed data if given" do
45
- adapter = Ambry::Adapters::Cookie.new \
46
- :secret => secret,
47
- :data => sample_data
48
- assert_kind_of Hash, adapter.db["User"]
49
- assert_equal "joe@schmoe.com", adapter.db["User"].keys.first
50
- end
51
-
52
- it "should load properly with nil or blank data" do
53
- [nil, ""].each_with_index do |arg, index|
54
- adapter = Ambry::Adapters::Cookie.new \
55
- :secret => secret,
56
- :data => arg,
57
- :name => :"main_#{index}"
58
- assert_instance_of Hash, adapter.db
59
- end
60
- end
61
- end
62
-
63
- describe "#export_data" do
64
- it "should encode and sign the database" do
65
- User.create \
66
- :name => Faker::Name.name,
67
- :email => Faker::Internet.email
68
- refute_nil @adapter.export_data
69
- end
70
- end
71
-
72
- describe "#save_database" do
73
- it "should raise a AmbryError if signed data exceeds max data length" do
74
- Ambry::Adapters::Cookie.stubs(:max_data_length).returns(1)
75
- assert_raises Ambry::AmbryError do
76
- User.create valid_user
77
- end
78
- end
79
- end
80
- end
81
- end