2010-11-02 20:09:43 +00:00
|
|
|
# Introduction
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
This is the 10gen-supported Ruby driver for [MongoDB](http://www.mongodb.org).
|
2009-01-08 16:48:59 +00:00
|
|
|
|
2010-11-03 21:50:08 +00:00
|
|
|
This documentation includes other articles of interest, include:
|
|
|
|
|
2010-11-29 22:14:27 +00:00
|
|
|
1. [A tutorial](http://api.mongodb.org/ruby/current/file.TUTORIAL.html).
|
|
|
|
2. [Replica Sets in Ruby](http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html).
|
|
|
|
3. [Write Concern in Ruby](http://api.mongodb.org/ruby/current/file.WRITE_CONCERN.html).
|
|
|
|
4. [GridFS in Ruby](http://api.mongodb.org/ruby/current/file.GridFS.html).
|
2010-11-29 22:04:39 +00:00
|
|
|
5. [Frequently Asked Questions](http://api.mongodb.org/ruby/current/file.FAQ.html).
|
|
|
|
6. [History](http://api.mongodb.org/ruby/current/file.HISTORY.html).
|
2011-03-23 21:11:21 +00:00
|
|
|
6. [Release plan](http://api.mongodb.org/ruby/current/file.RELEASES.html).
|
2010-11-29 22:04:39 +00:00
|
|
|
7. [Credits](http://api.mongodb.org/ruby/current/file.CREDITS.html).
|
|
|
|
|
2011-01-05 16:14:02 +00:00
|
|
|
Here's a quick code sample. Again, see the [MongoDB Ruby Tutorial](http://api.mongodb.org/ruby/current/file.TUTORIAL.html)
|
2010-11-02 20:09:43 +00:00
|
|
|
for much more:
|
2010-11-02 18:26:31 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
require 'rubygems'
|
|
|
|
require 'mongo'
|
|
|
|
include Mongo
|
2009-01-08 16:48:59 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
db = Connection.new.db('sample-db')
|
|
|
|
coll = db.collection('test')
|
2009-01-29 16:23:50 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
coll.remove
|
|
|
|
3.times do |i|
|
|
|
|
coll.insert({'a' => i+1})
|
|
|
|
end
|
|
|
|
puts "There are #{coll.count()} records. Here they are:"
|
|
|
|
coll.find().each { |doc| puts doc.inspect }
|
2010-11-02 18:26:31 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Installation
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
### Ruby Versions
|
2010-06-16 03:05:46 +00:00
|
|
|
|
2010-10-07 21:55:36 +00:00
|
|
|
The driver works and is consistently tested on Ruby 1.8.6, 1.8.7, and 1.9.2, and JRuby 1.5.1.
|
2010-06-16 03:05:46 +00:00
|
|
|
|
|
|
|
Note that if you're on 1.8.7, be sure that you're using a patchlevel >= 249. There
|
|
|
|
are some IO bugs in earlier versions.
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
### Gems
|
2010-06-16 03:05:46 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
The driver's gems are hosted at [Rubygems.org](http://rubygems.org). Make sure you're
|
2010-03-04 16:32:59 +00:00
|
|
|
using the latest version of rubygems:
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ gem update --system
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2010-03-04 16:32:59 +00:00
|
|
|
Then you can install the mongo gem as follows:
|
2009-10-05 14:43:57 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ gem install mongo
|
2009-01-23 13:53:48 +00:00
|
|
|
|
2010-10-07 21:55:36 +00:00
|
|
|
The driver also requires the bson gem:
|
2010-04-07 23:25:09 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ gem install bson
|
2010-04-07 23:25:09 +00:00
|
|
|
|
|
|
|
And for a significant performance boost, you'll want to install the C extensions:
|
2009-11-16 21:10:12 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ gem install bson_ext
|
2009-11-16 21:10:12 +00:00
|
|
|
|
2010-10-07 21:55:36 +00:00
|
|
|
Note that bson_ext isn't used with JRuby. Instead, some native Java extensions are bundled with the bson gem.
|
|
|
|
If you ever need to modify these extenions, you can recompile with the following rake task:
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake build:java
|
2010-10-07 21:55:36 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
### From the GitHub source
|
2009-01-23 13:53:48 +00:00
|
|
|
|
2009-01-15 21:05:56 +00:00
|
|
|
The source code is available at http://github.com/mongodb/mongo-ruby-driver.
|
|
|
|
You can either clone the git repository or download a tarball or zip file.
|
|
|
|
Once you have the source, you can use it from wherever you downloaded it or
|
|
|
|
you can install it as a gem from the source by typing
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake gem:install
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2009-11-16 21:45:37 +00:00
|
|
|
To install the C extensions from source, type this instead:
|
2009-03-19 18:56:54 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake gem:install_extensions
|
2009-03-19 18:56:54 +00:00
|
|
|
|
|
|
|
That's all there is to it!
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Examples
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
For extensive examples, see the [MongoDB Ruby Tutorial](http://www.mongodb.org/display/DOCS/Ruby+Tutorial).
|
2009-11-24 22:39:44 +00:00
|
|
|
|
2010-11-03 17:00:34 +00:00
|
|
|
Bundled with the driver are many examples, located in the "docs/examples" subdirectory. Samples include using
|
2009-11-24 22:39:44 +00:00
|
|
|
the driver and using the GridFS class GridStore. MongoDB must be running for
|
2009-02-03 17:16:33 +00:00
|
|
|
these examples to work, of course.
|
2009-01-07 21:07:22 +00:00
|
|
|
|
2009-11-24 22:39:44 +00:00
|
|
|
Here's how to start MongoDB and run the "simple.rb" example:
|
2009-02-03 17:16:33 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ cd path/to/mongo
|
|
|
|
$ ./mongod run
|
|
|
|
... then in another window ...
|
|
|
|
$ cd path/to/mongo-ruby-driver
|
2010-11-03 17:00:34 +00:00
|
|
|
$ ruby docs/examples/simple.rb
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2009-08-18 14:07:01 +00:00
|
|
|
See also the test code, especially test/test_db_api.rb.
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# GridFS
|
2009-01-29 16:23:50 +00:00
|
|
|
|
2010-02-24 20:24:01 +00:00
|
|
|
The Ruby driver include two abstractions for storing large files: Grid and GridFileSystem.
|
|
|
|
The Grid class is a Ruby implementation of MongoDB's GridFS file storage
|
|
|
|
specification. GridFileSystem is essentailly the same, but provides a more filesystem-like API
|
|
|
|
and assumes that filenames are unique.
|
2009-01-29 16:31:45 +00:00
|
|
|
|
2010-02-24 20:24:01 +00:00
|
|
|
An instance of both classes represents an individual file store. See the API reference
|
|
|
|
for details, and see examples/gridfs.rb for code that uses many of the Grid
|
|
|
|
features (metadata, content type, seek, tell, etc).
|
2009-01-29 16:31:45 +00:00
|
|
|
|
2010-02-24 20:24:01 +00:00
|
|
|
Examples:
|
2010-11-02 20:09:43 +00:00
|
|
|
# Write a file on disk to the Grid
|
|
|
|
file = File.open('image.jpg')
|
|
|
|
grid = Grid.new(db)
|
|
|
|
id = grid.put(file)
|
2010-02-24 20:24:01 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Retrieve the file
|
|
|
|
file = grid.get(id)
|
|
|
|
file.read
|
2010-01-07 23:35:18 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Get all the file's metata
|
|
|
|
file.filename
|
|
|
|
file.content_type
|
|
|
|
file.metadata
|
2010-01-07 23:35:18 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Notes
|
2010-01-07 23:35:18 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## Thread Safety
|
2009-10-09 04:33:35 +00:00
|
|
|
|
2010-01-13 21:36:53 +00:00
|
|
|
The driver is thread-safe.
|
2009-11-24 22:39:44 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## Connection Pooling
|
2009-11-24 22:39:44 +00:00
|
|
|
|
2011-02-10 20:13:28 +00:00
|
|
|
The driver implements connection pooling. By default, only one
|
2009-11-24 22:39:44 +00:00
|
|
|
socket connection will be opened to MongoDB. However, if you're running a
|
|
|
|
multi-threaded application, you can specify a maximum pool size and a maximum
|
|
|
|
timeout for waiting for old connections to be released to the pool.
|
|
|
|
|
|
|
|
To set up a pooled connection to a single MongoDB instance:
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
@conn = Connection.new("localhost", 27017, :pool_size => 5, :timeout => 5)
|
2009-11-24 22:39:44 +00:00
|
|
|
|
2010-01-13 18:11:09 +00:00
|
|
|
Though the pooling architecture will undoubtedly evolve, it currently owes much credit
|
2009-11-24 22:39:44 +00:00
|
|
|
to the connection pooling implementations in ActiveRecord and PyMongo.
|
2009-10-09 04:33:35 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## Using with Phusion Passenger and Unicorn
|
2009-09-14 19:22:41 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
When Passenger and Unicorn are in smart spawning mode you need to be sure that child
|
|
|
|
processes will create a new connection to the database. In Passenger, this can be handled like so:
|
2009-09-14 19:22:41 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
if defined?(PhusionPassenger)
|
|
|
|
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
|
|
|
if forked
|
2011-02-10 20:13:28 +00:00
|
|
|
# Reset all connection objects. How you do this depends on where
|
|
|
|
# you keep your connection object. In any case, call the #connect
|
|
|
|
# method on the connection object. For example:
|
|
|
|
# CONN.connect
|
|
|
|
#
|
|
|
|
# If you're using MongoMapper:
|
|
|
|
# MongoMapper.connection.connect
|
2010-11-02 20:09:43 +00:00
|
|
|
end
|
2009-09-14 19:22:41 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-10 20:13:28 +00:00
|
|
|
In Unicorn, add this to your unicorn.rb file:
|
|
|
|
|
|
|
|
after_fork do |server, worker|
|
|
|
|
# Handle reconnection
|
|
|
|
end
|
|
|
|
|
|
|
|
The above code should be put into a Rails initializer or similar initialization script.
|
2009-09-14 19:22:41 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## String Encoding
|
2009-01-13 17:53:55 +00:00
|
|
|
|
|
|
|
The BSON ("Binary JSON") format used to communicate with Mongo requires that
|
|
|
|
strings be UTF-8 (http://en.wikipedia.org/wiki/UTF-8).
|
|
|
|
|
|
|
|
Ruby 1.9 has built-in character encoding support. All strings sent to Mongo
|
|
|
|
and received from Mongo are converted to UTF-8 when necessary, and strings
|
|
|
|
read from Mongo will have their character encodings set to UTF-8.
|
|
|
|
|
|
|
|
When used with Ruby 1.8, the bytes in each string are written to and read from
|
2010-11-02 20:09:43 +00:00
|
|
|
Mongo as is. If the string is ASCII, all is well, because ASCII is a subset of
|
2010-01-07 23:35:18 +00:00
|
|
|
UTF-8. If the string is not ASCII, it may not be a well-formed UTF-8
|
2009-01-16 19:41:53 +00:00
|
|
|
string.
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## Primary Keys
|
2009-02-01 14:14:21 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
The `_id` field is a primary key. It is treated specially by the database, and
|
2009-07-13 16:18:05 +00:00
|
|
|
its use makes many operations more efficient. The value of an _id may be of
|
|
|
|
any type. The database itself inserts an _id value if none is specified when
|
|
|
|
a record is inserted.
|
2009-02-01 15:25:50 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
### Primary Key Factories
|
2009-01-16 19:41:53 +00:00
|
|
|
|
2009-02-01 14:14:21 +00:00
|
|
|
A primary key factory is a class you supply to a DB object that knows how to
|
2009-07-13 16:18:05 +00:00
|
|
|
generate _id values. If you want to control _id values or even their types,
|
|
|
|
using a PK factory lets you do so.
|
2009-02-01 14:14:21 +00:00
|
|
|
|
|
|
|
You can tell the Ruby Mongo driver how to create primary keys by passing in
|
2010-03-23 18:35:50 +00:00
|
|
|
the :pk option to the Connection#db method.
|
2009-01-16 19:41:53 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
db = Mongo::Connection.new.db('dbname', :pk => MyPKFactory.new)
|
2009-01-16 19:41:53 +00:00
|
|
|
|
2010-03-23 18:35:50 +00:00
|
|
|
A primary key factory object must respond to :create_pk, which should
|
|
|
|
take a hash and return a hash which merges the original hash with any
|
|
|
|
primary key fields the factory wishes to inject.
|
2010-01-07 23:35:18 +00:00
|
|
|
|
2010-03-23 18:35:50 +00:00
|
|
|
NOTE: if the object already has a primary key, the factory should not
|
|
|
|
inject a new key; this means that the object may already exist in the
|
|
|
|
database. The idea here is that whenever a record is inserted, the
|
|
|
|
:pk object's +create_pk+ method will be called and the new hash
|
|
|
|
returned will be inserted.
|
2009-01-16 19:41:53 +00:00
|
|
|
|
|
|
|
Here is a sample primary key factory, taken from the tests:
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
class TestPKFactory
|
|
|
|
def create_pk(row)
|
|
|
|
row['_id'] ||= Mongo::ObjectID.new
|
|
|
|
row
|
|
|
|
end
|
2009-01-16 19:41:53 +00:00
|
|
|
end
|
|
|
|
|
2009-01-29 16:31:45 +00:00
|
|
|
Here's a slightly more sophisticated one that handles both symbol and string
|
|
|
|
keys. This is the PKFactory that comes with the MongoRecord code (an
|
|
|
|
ActiveRecord-like framework for non-Rails apps) and the AR Mongo adapter code
|
|
|
|
(for Rails):
|
|
|
|
|
|
|
|
class PKFactory
|
|
|
|
def create_pk(row)
|
|
|
|
return row if row[:_id]
|
|
|
|
row.delete(:_id) # in case it exists but the value is nil
|
2009-08-20 14:50:48 +00:00
|
|
|
row['_id'] ||= Mongo::ObjectID.new
|
2009-01-29 16:31:45 +00:00
|
|
|
row
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-02-01 14:14:21 +00:00
|
|
|
A database's PK factory object may be set either when a DB object is created
|
|
|
|
or immediately after you obtain it, but only once. The only reason it is
|
|
|
|
changeable at all is so that libraries such as MongoRecord that use this
|
|
|
|
driver can set the PK factory after obtaining the database but before using it
|
|
|
|
for the first time.
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## The DB Class
|
2009-01-16 19:41:53 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
### Strict mode
|
2009-01-16 19:41:53 +00:00
|
|
|
|
|
|
|
Each database has an optional strict mode. If strict mode is on, then asking
|
|
|
|
for a collection that does not exist will raise an error, as will asking to
|
|
|
|
create a collection that already exists. Note that both these operations are
|
|
|
|
completely harmless; strict mode is a programmer convenience only.
|
|
|
|
|
|
|
|
To turn on strict mode, either pass in :strict => true when obtaining a DB
|
2010-11-02 20:09:43 +00:00
|
|
|
object or call the `:strict=` method:
|
2009-01-16 19:41:53 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
db = Connection.new.db('dbname', :strict => true)
|
|
|
|
# I'm feeling lax
|
|
|
|
db.strict = false
|
|
|
|
# No, I'm not!
|
|
|
|
db.strict = true
|
2009-01-16 19:41:53 +00:00
|
|
|
|
|
|
|
The method DB#strict? returns the current value of that flag.
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
## Cursors
|
2009-02-03 17:43:22 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
Notes:
|
2009-02-03 17:43:22 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
* Cursors are enumerable (and have a #to_a method).
|
2009-02-03 17:43:22 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
* The query doesn't get run until you actually attempt to retrieve data from a
|
2009-02-03 17:43:22 +00:00
|
|
|
cursor.
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
* Cursors will timeout on the server after 10 minutes. If you need to keep a cursor
|
|
|
|
open for more than 10 minutes, specify `:timeout => false` when you create the cursor.
|
2009-02-03 17:43:22 +00:00
|
|
|
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Testing
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
If you have the source code, you can run the tests.
|
2009-01-08 16:42:52 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake test:c
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
If you want to test the basic Ruby encoder, without the C extension, or if you're running JRuby:
|
2009-12-01 18:49:57 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake test:ruby
|
2009-12-01 18:49:57 +00:00
|
|
|
|
|
|
|
These will run both unit and functional tests. To run these tests alone:
|
2009-11-23 18:13:14 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake test:unit
|
|
|
|
$ rake test:functional
|
2009-11-23 18:13:14 +00:00
|
|
|
|
2010-01-13 18:11:09 +00:00
|
|
|
To run any individual rake tasks with the C extension enabled, just pass C_EXT=true to the task:
|
2009-12-01 18:49:57 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake test:unit C_EXT=true
|
2009-11-23 18:13:14 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
If you want to test replica set, you can run the following tests
|
2009-11-23 18:13:14 +00:00
|
|
|
individually:
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake test:replica_set_count
|
|
|
|
$ rake test:replica_set_insert
|
|
|
|
$ rake test:replica_set_query
|
2009-11-23 18:13:14 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
### Shoulda and Mocha
|
2009-11-24 20:20:51 +00:00
|
|
|
|
2010-02-22 20:49:04 +00:00
|
|
|
Running the test suite requires shoulda and mocha. You can install them as follows:
|
2009-10-20 15:31:07 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ gem install shoulda
|
|
|
|
$ gem install mocha
|
2009-10-20 15:31:07 +00:00
|
|
|
|
2009-01-29 15:42:20 +00:00
|
|
|
The tests assume that the Mongo database is running on the default port. You
|
2009-08-20 22:48:09 +00:00
|
|
|
can override the default host (localhost) and port (Connection::DEFAULT_PORT) by
|
2009-01-29 15:42:20 +00:00
|
|
|
using the environment variables MONGO_RUBY_DRIVER_HOST and
|
|
|
|
MONGO_RUBY_DRIVER_PORT.
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Documentation
|
2008-12-04 22:02:19 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
This documentation is available online at [http://api.mongodb.org/ruby](http://api.mongodb.org/ruby). You can
|
2009-01-08 16:42:52 +00:00
|
|
|
generate the documentation if you have the source by typing
|
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
$ rake ydoc
|
2008-12-04 22:02:19 +00:00
|
|
|
|
2010-01-13 18:11:09 +00:00
|
|
|
Then open the file +ydoc/index.html+.
|
2008-12-02 15:45:02 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Release Notes
|
2008-12-02 15:45:02 +00:00
|
|
|
|
2009-11-24 22:39:44 +00:00
|
|
|
See HISTORY.
|
2008-12-02 15:45:02 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# Credits
|
2008-12-05 21:39:00 +00:00
|
|
|
|
2009-12-08 22:13:54 +00:00
|
|
|
See CREDITS.
|
2009-11-25 16:25:50 +00:00
|
|
|
|
2010-11-02 20:09:43 +00:00
|
|
|
# License
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2010-02-20 00:17:38 +00:00
|
|
|
Copyright 2008-2010 10gen Inc.
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2009-02-15 13:24:14 +00:00
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
2008-12-02 01:20:00 +00:00
|
|
|
|
2009-02-15 13:24:14 +00:00
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|