ambry 0.2.4 → 0.3.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.
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