nosequel 1.0.0.pre.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.ruby-version +1 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +96 -0
- data/Rakefile +8 -0
- data/lib/nosequel.rb +73 -0
- data/lib/nosequel/configuration.rb +69 -0
- data/lib/nosequel/container.rb +112 -0
- data/lib/nosequel/version.rb +3 -0
- data/nosequel.gemspec +25 -0
- data/test/all_tests.rb +4 -0
- data/test/test_helper.rb +26 -0
- data/test/tests/config.rb +34 -0
- data/test/tests/data.rb +35 -0
- data/test/tests/query.rb +40 -0
- data/test/tests/register.rb +22 -0
- data/test/tests/write.rb +21 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fc76411b87eef119504bbf126033ff7809ed3f88
|
4
|
+
data.tar.gz: 1004767c7e3a39f7b0b62a904ead2b3aa4c22dca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec9c5d986287a91f05c8c7f856e544c1a3c107b317c704a480d405b5f3ec499443a818cd664ad97326ed830e2b5b55a1335756ba05fc7b5a9ea96c3f9a5d10ee
|
7
|
+
data.tar.gz: 108f4a439489346f2dc1bf5f34c0211e2408e92d57f971e5968f7d9bdf19384cb32c8ec6e65826c307b47b31882dfe45cffec29994407af677721f4a7a1556b2
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p247
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Donovan C. Young
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
NoSequel
|
2
|
+
========
|
3
|
+
What is it?
|
4
|
+
-----------
|
5
|
+
NoSequel provides a simple, pure ruby, key/value data storage container using a persistent database powered by the Sequel O/RM system by Sharon Rosner and Jeremy Evans.
|
6
|
+
|
7
|
+
How do I use it?
|
8
|
+
------------------
|
9
|
+
Glad you asked!
|
10
|
+
|
11
|
+
### Install it
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'nosequel'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install nosequel
|
24
|
+
|
25
|
+
#### Register it
|
26
|
+
```ruby
|
27
|
+
require 'nosequel'
|
28
|
+
|
29
|
+
# Here, our app is using a table named ':my_store', but this could be anything
|
30
|
+
# that's meaningful to you. It doesn't matter if this table already exists.
|
31
|
+
# If it does, any data stored will be available in the container.
|
32
|
+
# If not, it will be created on the fly. Neato!
|
33
|
+
container = NoSequel.register(:my_store)
|
34
|
+
```
|
35
|
+
|
36
|
+
This sets up a `container` which acts as your primary data store. Then, all you need to do is...
|
37
|
+
|
38
|
+
#### Use it
|
39
|
+
```ruby
|
40
|
+
container[:some_key] = "Some value I care about"
|
41
|
+
```
|
42
|
+
|
43
|
+
That's all there is to it, easy peasy ~~Japanesey~~! *[appologies to my East Asian friends, I mean no offense]*
|
44
|
+
|
45
|
+
Once registered, your container is a simple, persistent, HASH-like storage system. Use it to store any object you want to persist between runs of you ruby code. Yup! That's right! You can store just about any Object in your container for later retrieval between runs, or even from another program altogether -- the registration name is the key.
|
46
|
+
|
47
|
+
If the value you're storing isn't already a String, we'll serialize it before saving and deserialize it upon retrieval. Cool, huh?
|
48
|
+
|
49
|
+
Behind the scenes, we're actually writing your data to a database (specifically, in a table named `my_store` in our example). We (and by _we_, I mean Sequel) only read and write to the database when we absolutely have to, so it keeps disk access down to a minimum. It's also thread-safe, so... YAY!
|
50
|
+
|
51
|
+
#### Configure it
|
52
|
+
The defaults (`sqlite`) are going to work pretty well for most people, but hey, if you want to change the database options, go for it!
|
53
|
+
|
54
|
+
##### Here's how...
|
55
|
+
Send in a hash with the options you would like to change along with your call to #register. Yup, that's it.
|
56
|
+
|
57
|
+
| Item | Description | Default Value |
|
58
|
+
|:------:|:-------------|:---------------|
|
59
|
+
| db_type | The database type (sqlite, mysql, postgres, etc.) -- see [Sequel Gem](http://sequel.rubyforge.org/rdoc-adapters/index.html) for complete options. | sqlite |
|
60
|
+
| db_name | The name of the database (or file, depending on type) | data.db |
|
61
|
+
| db_user | The database user[:password] to use. | none |
|
62
|
+
| db_host | The database host[:port] to use. | localhost |
|
63
|
+
|
64
|
+
##### Like This...
|
65
|
+
```ruby
|
66
|
+
container = NoSequel.register(
|
67
|
+
:my_plugin,
|
68
|
+
db_name: 'mydb',
|
69
|
+
db_type: 'mysql',
|
70
|
+
db_user: 'myname',
|
71
|
+
db_host: 'localhost'
|
72
|
+
)
|
73
|
+
```
|
74
|
+
|
75
|
+
### Notes
|
76
|
+
***Hey, you should probably know that we're under development, so this information may or may not be lying to you, however the core public interface should be relatively stable.***
|
77
|
+
|
78
|
+
Since NoSequel relies on [Sequel](https://github.com/jeremyevans/sequel) to provide the back-end database support, it **only** supports what they do. Our goal is to keep this gem lightweight, so if you want to use some fancy new (or anciently old) database model that they don't (yet) support, 'tuff noogies -- go whine to them. :-)
|
79
|
+
|
80
|
+
|
81
|
+
Other Stuff you might want to know
|
82
|
+
----------------------------------
|
83
|
+
### Who's Involved with this?
|
84
|
+
- [Donovan C. Young](https://github.com/dyoung522)
|
85
|
+
|
86
|
+
### Help (I need somebody)!
|
87
|
+
You can email me directly via dyoung522 at gmail.com or find me lurking somewhere on irc.freenode.net (as dyoung522)
|
88
|
+
|
89
|
+
### How can I help?
|
90
|
+
If you wish NoSequel could act in a particular way, or had some cool new feature it's missing, by all means, [let me know!](mailto:dyoung522@gmail.com), or better yet...
|
91
|
+
|
92
|
+
1. Fork it
|
93
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
94
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
95
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
96
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/nosequel.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# The idea is to add a NoSQL interface for the Sequel OR/M
|
2
|
+
#
|
3
|
+
# Author:: Donovan C. Young (mailto:dyoung522@gmail.com)
|
4
|
+
# Copyright:: Copyright (c) 2013 Donovan C. Young
|
5
|
+
# License:: MIT
|
6
|
+
#
|
7
|
+
# :include:LICENSE.txt
|
8
|
+
|
9
|
+
require 'nosequel/version'
|
10
|
+
require 'nosequel/configuration'
|
11
|
+
require 'nosequel/container'
|
12
|
+
|
13
|
+
# Module methods
|
14
|
+
module NoSequel
|
15
|
+
|
16
|
+
# Creates or Retrieves and returns a container object
|
17
|
+
#
|
18
|
+
# == Parameters:
|
19
|
+
# === Required:
|
20
|
+
# table::
|
21
|
+
# A string or symbol referencing the table name to use
|
22
|
+
#
|
23
|
+
# === Optional:
|
24
|
+
# db_type::
|
25
|
+
# The database type (defaults to sqlite3)
|
26
|
+
#
|
27
|
+
# db_name::
|
28
|
+
# The database name (or file) to use
|
29
|
+
#
|
30
|
+
# db_user::
|
31
|
+
# The database user (along with optional :password, if necessary)
|
32
|
+
#
|
33
|
+
# db_host::
|
34
|
+
# The database host (defaults to localhost)
|
35
|
+
#
|
36
|
+
# == Returns:
|
37
|
+
# A NoSequel::Container object
|
38
|
+
#
|
39
|
+
def self.register( table, config = {} )
|
40
|
+
# Create the Sequel connection
|
41
|
+
#Container.new(@sequel, table)
|
42
|
+
@config = Configuration.new(config)
|
43
|
+
@sequel = @config.sequel
|
44
|
+
Container.new( @sequel, table )
|
45
|
+
end
|
46
|
+
|
47
|
+
# Permanently deletes table from the underlying database
|
48
|
+
#
|
49
|
+
def self.drop( table )
|
50
|
+
raise RuntimeError, 'You must call register first' unless @sequel
|
51
|
+
# Drop the table
|
52
|
+
@sequel.drop_table( table.to_sym ) if exists?(table)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Drops the database table and deletes the local file (if it exists)
|
56
|
+
#
|
57
|
+
def self.drop!( table )
|
58
|
+
drop( table )
|
59
|
+
|
60
|
+
# Remove the file (if any)
|
61
|
+
File.unlink(@config.db_name) if File.exists?(@config.db_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Tests if a table already exists in the database
|
65
|
+
# == Returns:
|
66
|
+
# true or false
|
67
|
+
#
|
68
|
+
def self.exists?( table )
|
69
|
+
raise RuntimeError, 'You must call register first' unless @sequel
|
70
|
+
@sequel.table_exists?( table.to_sym )
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
|
3
|
+
# NoSequel::Configuration class
|
4
|
+
module NoSequel
|
5
|
+
class Configuration
|
6
|
+
attr_accessor :db_type , :db_name, :db_user, :db_host
|
7
|
+
|
8
|
+
# NoSequel::Configuration constructor
|
9
|
+
#
|
10
|
+
# == Returns:
|
11
|
+
# A Configuration object which holds the user supplied config along with class defaults.
|
12
|
+
#
|
13
|
+
def initialize( opts = {} )
|
14
|
+
config = default_config.merge(opts)
|
15
|
+
config.each do |key, value|
|
16
|
+
self.send("#{key}=", value) if self.respond_to?(key)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Create and return an active Sequel object
|
21
|
+
# == Returns:
|
22
|
+
# A Sequel Object
|
23
|
+
#
|
24
|
+
def sequel
|
25
|
+
Sequel.connect( sequel_url )
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Converts the object into a textual string that can be sent to sequel
|
31
|
+
#
|
32
|
+
# == Returns:
|
33
|
+
# A string representing the object in a sequel-connect string format
|
34
|
+
#
|
35
|
+
def sequel_url
|
36
|
+
|
37
|
+
return '' unless db_type
|
38
|
+
|
39
|
+
# Start our connection string
|
40
|
+
connect_string = db_type + '://'
|
41
|
+
|
42
|
+
# Add user:password if supplied
|
43
|
+
unless db_user.nil?
|
44
|
+
connect_string += db_user
|
45
|
+
|
46
|
+
# Add either a @ or / depending on if a host was provided too
|
47
|
+
connect_string += db_host ? '@' : '/'
|
48
|
+
|
49
|
+
# Add host:port if supplied
|
50
|
+
connect_string += db_host + '/' if db_host
|
51
|
+
end
|
52
|
+
|
53
|
+
connect_string + db_name
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Reasonable defaults for the Object
|
58
|
+
#
|
59
|
+
def default_config
|
60
|
+
{
|
61
|
+
db_type: 'sqlite', # Any database connector supported by the Sequel gem
|
62
|
+
db_name: 'data.db', # The name of the database (or file) to use
|
63
|
+
db_user: nil, # The database user and optional password (user:password)
|
64
|
+
db_host: 'localhost' # The database host and options port (host:port)
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
# NoSequel::Container class
|
4
|
+
module NoSequel
|
5
|
+
class Container
|
6
|
+
|
7
|
+
# NoSequel::Container constructor
|
8
|
+
# called via NoSequel.register(:table)
|
9
|
+
# == Parameters:
|
10
|
+
# db::
|
11
|
+
# Sequel object
|
12
|
+
# table::
|
13
|
+
# The Sequel database table
|
14
|
+
#
|
15
|
+
# == Returns:
|
16
|
+
# A valid Container object
|
17
|
+
#
|
18
|
+
def initialize(db, table)
|
19
|
+
|
20
|
+
unless db.table_exists?(table.to_sym)
|
21
|
+
db.create_table table do
|
22
|
+
primary_key :id
|
23
|
+
String :key
|
24
|
+
String :value
|
25
|
+
end
|
26
|
+
db.add_index table, :key
|
27
|
+
db.add_index table, :value
|
28
|
+
end
|
29
|
+
|
30
|
+
@sequel = db
|
31
|
+
@db = db[table]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public Atributes
|
35
|
+
# db::
|
36
|
+
# NoSequel data object
|
37
|
+
# sequel::
|
38
|
+
# Underlying Sequel database object
|
39
|
+
#
|
40
|
+
attr_reader :db, :sequel
|
41
|
+
|
42
|
+
# Assigns the <value> to a given <:key>
|
43
|
+
#
|
44
|
+
def []=(key, value)
|
45
|
+
obj = value.is_a?(String) ? value : YAML::dump(value)
|
46
|
+
if exists?(key) # column already exists
|
47
|
+
data(key).update(value: obj)
|
48
|
+
else
|
49
|
+
db.insert(key: key.to_s, value: obj)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the value stored in :key, or nil of the data wasn't found.
|
54
|
+
#
|
55
|
+
def [](key)
|
56
|
+
exists?(key) ? YAML::load(value(key)) : nil
|
57
|
+
end
|
58
|
+
|
59
|
+
# Deletes :key from the nosequel container
|
60
|
+
#
|
61
|
+
def delete(key)
|
62
|
+
if exists?(key)
|
63
|
+
value = value(key)
|
64
|
+
data(key).delete
|
65
|
+
end
|
66
|
+
value
|
67
|
+
end
|
68
|
+
alias_method :remove, :delete
|
69
|
+
|
70
|
+
# Checks if a given key exists in the container
|
71
|
+
#
|
72
|
+
def has_key?(key)
|
73
|
+
data(validate_key(key)).count == 1 ? true : false
|
74
|
+
end
|
75
|
+
alias_method :exist?, :has_key?
|
76
|
+
alias_method :exists?, :has_key?
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Handle all other Hash methods
|
81
|
+
#
|
82
|
+
def method_missing(meth, *args, &block)
|
83
|
+
db.to_hash(:key, :value).send(meth, *args, &block)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Make sure we respond to all Hash methods
|
87
|
+
#
|
88
|
+
def respond_to?(meth)
|
89
|
+
db.to_hash(:key, :value).respond_to?(meth)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns a single record which matches key
|
93
|
+
def data(key)
|
94
|
+
db.where(key: validate_key(key).to_s)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returns the value of a given key
|
98
|
+
def value(key)
|
99
|
+
data(key).get(:value)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Make sure the key is valid
|
103
|
+
def validate_key(key)
|
104
|
+
unless key.is_a?(Symbol) || key.is_a?(String)
|
105
|
+
raise ArgumentError, 'Key must be a string or symbol'
|
106
|
+
end
|
107
|
+
key
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/nosequel.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'nosequel/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "nosequel"
|
8
|
+
spec.version = NoSequel::VERSION
|
9
|
+
spec.authors = ["Donovan C. Young"]
|
10
|
+
spec.email = ["dyoung522@gmail.com"]
|
11
|
+
spec.description = "Simple NoSQL-like storage methods for Sequel O/RM"
|
12
|
+
spec.summary = "Provides a NoSQL-like interface for data storage, backed by Sequel"
|
13
|
+
spec.homepage = "http://github.com/dyoung522/nosequel"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
|
+
|
23
|
+
spec.add_dependency 'sequel', '~> 4.1.0'
|
24
|
+
spec.add_dependency 'sqlite3' # default storage engine
|
25
|
+
end
|
data/test/all_tests.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'nosequel'
|
2
|
+
require 'minitest/spec'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/reporters'
|
5
|
+
|
6
|
+
if ENV['RUBYMINE_TESTUNIT_REPORTER']
|
7
|
+
MiniTest::Reporters.use! MiniTest::Reporters::RubyMineReporter
|
8
|
+
else
|
9
|
+
#MiniTest::Reporters.use! MiniTest::Reporters::DefaultReporter.new
|
10
|
+
#MiniTest::Reporters.use! MiniTest::Reporters::ProgressReporter.new
|
11
|
+
MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
|
12
|
+
end
|
13
|
+
|
14
|
+
module TestSetup
|
15
|
+
def setup
|
16
|
+
@table = :test
|
17
|
+
@data = NoSequel.register(@table, db_type: 'sqlite', db_name: 'test.db')
|
18
|
+
|
19
|
+
(1..4).each { |i| @data["test#{i}"] = "value#{i}" }
|
20
|
+
end
|
21
|
+
|
22
|
+
def teardown
|
23
|
+
NoSequel.drop!(@table)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestConfigurationMethods < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_drop_method_raises_error_before_register
|
6
|
+
out, err = capture_io do
|
7
|
+
assert_raises(RuntimeError) { NoSequel.drop!(:test) }
|
8
|
+
end
|
9
|
+
assert_match err, 'must call register'
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_exists_method_raises_error_before_register
|
13
|
+
out, err = capture_io do
|
14
|
+
assert_raises(RuntimeError) { NoSequel.exists?(:test) }
|
15
|
+
end
|
16
|
+
assert_match err, 'must call register'
|
17
|
+
end
|
18
|
+
|
19
|
+
# We're testing a private method to be sure it's returning a valid response.
|
20
|
+
# If you're reading this, please note that this is a private method and
|
21
|
+
# therefore should generally *not* be called directly in your code.
|
22
|
+
# You probably want object.sequel if you need direct access to sequel calls.
|
23
|
+
def test_private_sequel_url_returns_a_valid_response
|
24
|
+
( db_name, db_type, db_user, db_host ) = %w(testing mysql test)
|
25
|
+
config = NoSequel::Configuration.new(
|
26
|
+
db_type: db_type,
|
27
|
+
db_name: db_name,
|
28
|
+
db_user: db_user,
|
29
|
+
db_host: db_host
|
30
|
+
)
|
31
|
+
assert_equal "#{db_type}://#{db_user}/#{db_name}", config.send(:sequel_url)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/test/tests/data.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestDataMethods < Minitest::Unit::TestCase
|
4
|
+
include TestSetup
|
5
|
+
|
6
|
+
def test_column_should_exist
|
7
|
+
assert @data.has_key?(:test1), "@data[:test1] should exist"
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_retrieve_column_value
|
11
|
+
assert_equal 'value1', @data[:test1], "@data[:test1] should return 'value1'"
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_add_a_key_value_pair
|
15
|
+
@data[:newkey] = 'new key value'
|
16
|
+
assert_equal 'new key value', @data[:newkey], "We should be able to set a new key/value pair at will"
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_update_an_existing_key_value_pair
|
20
|
+
@data[:test1] = 'new value'
|
21
|
+
assert_equal 'new value', @data[:test1], "We should be able to add a new value to an existing key"
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_delete_key
|
25
|
+
out = @data.delete(:test1)
|
26
|
+
refute @data.has_key?(:test1)
|
27
|
+
assert_equal 'value1', out
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_data_persists_between_calls
|
31
|
+
@data = nil
|
32
|
+
newdata = NoSequel.register(:test, db_type: 'sqlite', db_name: 'test.db')
|
33
|
+
assert_equal 'value1', newdata[:test1], "Data should persist between NoSequel calls"
|
34
|
+
end
|
35
|
+
end
|
data/test/tests/query.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestQueryMethods < Minitest::Unit::TestCase
|
4
|
+
include TestSetup
|
5
|
+
|
6
|
+
def test_data_responds_to_Hash_methods
|
7
|
+
assert_respond_to @data, :keys
|
8
|
+
assert_respond_to @data, :values
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_keys_method_returns_an_array_of_keys
|
12
|
+
assert_equal %w( test1 test2 test3 test4 ), @data.keys
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_array_method_returns_an_array_of_values
|
16
|
+
assert_equal %w( value1 value2 value3 value4 ), @data.values
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_data_handles_next
|
20
|
+
enum = @data.each
|
21
|
+
|
22
|
+
assert_equal %w(test1 value1), enum.next
|
23
|
+
assert_equal %w(test2 value2), enum.next
|
24
|
+
assert_equal %w(test3 value3), enum.next
|
25
|
+
assert_equal %w(test4 value4), enum.next
|
26
|
+
|
27
|
+
assert_raises(StopIteration) { enum.next }
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_data_handles_map
|
31
|
+
assert_equal %w(VALUE1 VALUE2 VALUE3 VALUE4), @data.map { |k,v| v.upcase }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_data_doesnt_respond_to_bogus_methods
|
35
|
+
refute_respond_to @data, :foo
|
36
|
+
assert_raises(NoMethodError) { @data.foo }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestRegister < Minitest::Unit::TestCase
|
4
|
+
include TestSetup
|
5
|
+
|
6
|
+
def test_exists
|
7
|
+
assert NoSequel.exists?(@table), "table '#{@table}' should exist"
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_remove_table_after_drop
|
11
|
+
NoSequel.register(:drop_test)
|
12
|
+
assert NoSequel.exists?(:drop_test), "table 'drop_test' should now exist"
|
13
|
+
|
14
|
+
NoSequel.drop!(:drop_test)
|
15
|
+
refute NoSequel.exists?(:drop_test), "table 'drop_test' should no longer exist"
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_nontexistant_table_should_not_exist
|
19
|
+
refute NoSequel.exists?(:bogus_table), "table :bogus_table should not exist"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/test/tests/write.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class TestWriteMethods < Minitest::Unit::TestCase
|
4
|
+
include TestSetup
|
5
|
+
|
6
|
+
Tester = Struct.new(:data)
|
7
|
+
|
8
|
+
def test_non_string_key_raises_error
|
9
|
+
assert_raises(ArgumentError) { @data[Tester] = 'invalid' }
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_serialize_objects_before_write
|
13
|
+
@data[:test_object] = Tester.new()
|
14
|
+
assert_instance_of Tester, @data[:test_object]
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_deserialize_objects_before_read
|
18
|
+
@data[:test_object] = Tester.new('hi there')
|
19
|
+
assert_equal 'hi there', @data[:test_object].data
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nosequel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre.alpha.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Donovan C. Young
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sequel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Simple NoSQL-like storage methods for Sequel O/RM
|
56
|
+
email:
|
57
|
+
- dyoung522@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".ruby-version"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/nosequel.rb
|
69
|
+
- lib/nosequel/configuration.rb
|
70
|
+
- lib/nosequel/container.rb
|
71
|
+
- lib/nosequel/version.rb
|
72
|
+
- nosequel.gemspec
|
73
|
+
- test/all_tests.rb
|
74
|
+
- test/test_helper.rb
|
75
|
+
- test/tests/config.rb
|
76
|
+
- test/tests/data.rb
|
77
|
+
- test/tests/query.rb
|
78
|
+
- test/tests/register.rb
|
79
|
+
- test/tests/write.rb
|
80
|
+
homepage: http://github.com/dyoung522/nosequel
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 1.3.1
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.1.9
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Provides a NoSQL-like interface for data storage, backed by Sequel
|
104
|
+
test_files:
|
105
|
+
- test/all_tests.rb
|
106
|
+
- test/test_helper.rb
|
107
|
+
- test/tests/config.rb
|
108
|
+
- test/tests/data.rb
|
109
|
+
- test/tests/query.rb
|
110
|
+
- test/tests/register.rb
|
111
|
+
- test/tests/write.rb
|
112
|
+
has_rdoc:
|