json_store 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49e14dd153040a235c67133f3df7faeb1357ae9f
4
- data.tar.gz: b7f1b9de726f8f9da032f01260ee3f4365f94635
3
+ metadata.gz: bfcfc3af69aa015556ac14133eaa9e7c73241017
4
+ data.tar.gz: ae79607a47bbc64c2548a4a834787dbe16f6a383
5
5
  SHA512:
6
- metadata.gz: a85d3a673bbce87fc59532f65895852e76afe1c83c899a4777a72223ceb9ec9dbb072816b2f3c95cde2090a1110ba090751f490f1c1418fc5338c5f904ebdf33
7
- data.tar.gz: 3246102a9104e11127f467ee7a542789c9e6812c64527827a9b700469d9e9b00da135243a329f0daeca2a40650a7eca2c0fd00fba1db138f43a45d849e008f1f
6
+ metadata.gz: f1f1bb2d50d7529fd47ab19e3bc0d9d8886375b5dfff265b164920778866bb801dae03367f801156f396ee3502b8e2291649bc55df5d3ddd0f989c97d2f7b8b7
7
+ data.tar.gz: 689bc07143cd4b59f18344d82240fe8a90ba05fd306df36afc1ac91984311ac7f2a42d5e1d226ba323957ed7d9034e393eada766fd265150c8d4d259e8324794
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
data/README.md CHANGED
@@ -21,6 +21,35 @@ db.merge
21
21
  db.push
22
22
  ```
23
23
 
24
+ * Peristing more complex things like custom objects
25
+
26
+ ```ruby
27
+
28
+ class Person
29
+
30
+ def initialize(first,last)
31
+ @first = first
32
+ @last = last
33
+ end
34
+
35
+ def first
36
+ @first
37
+ end
38
+
39
+ def last
40
+ @last
41
+ end
42
+
43
+ end
44
+
45
+ db = JsonStore.new('people')
46
+ db.pull
47
+ db.set(:person,Person.new('Kingsley','Hendrickse'))
48
+ db.push
49
+ p db.get(:person).first # Kingsley
50
+
51
+ ```
52
+
24
53
  There are only a handful of commands:
25
54
 
26
55
  * pull
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/json_store.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: json_store 0.1.0 ruby lib
5
+ # stub: json_store 0.1.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "json_store"
9
- s.version = "0.1.0"
9
+ s.version = "0.1.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Kingsley Hendrickse"]
14
- s.date = "2014-06-19"
14
+ s.date = "2014-06-23"
15
15
  s.description = "A simple in memory key/value database using json that writes to file"
16
16
  s.email = "kingsleyhendrickse@me.com"
17
17
  s.extra_rdoc_files = [
@@ -20,14 +20,18 @@ Gem::Specification.new do |s|
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
+ ".travis.yml",
23
24
  "Gemfile",
24
- "Gemfile.lock",
25
25
  "LICENSE.txt",
26
26
  "README.md",
27
27
  "Rakefile",
28
28
  "VERSION",
29
29
  "json_store.gemspec",
30
- "lib/json_store.rb"
30
+ "lib/json_store.rb",
31
+ "spec/json_store_spec.rb",
32
+ "spec/test_data/test1.json",
33
+ "spec/test_data/test2.json",
34
+ "spec/test_data/test3.json"
31
35
  ]
32
36
  s.homepage = "http://github.com/kingsleyh/json_store"
33
37
  s.licenses = ["MIT"]
data/lib/json_store.rb CHANGED
@@ -21,12 +21,16 @@ class JsonStore
21
21
  @map
22
22
  end
23
23
 
24
+ def clear
25
+ @map = {}
26
+ end
27
+
24
28
  def all_as_json
25
29
  Oj.dump(@map)
26
30
  end
27
31
 
28
- def search(selector,kind=:matches)
29
- JSONSelect(selector).send(kind,@map)
32
+ def search(selector, kind=:matches)
33
+ JSONSelect(selector).send(kind, @map)
30
34
  end
31
35
 
32
36
  def get_as_json(key)
@@ -35,7 +39,7 @@ class JsonStore
35
39
 
36
40
  def pull
37
41
  begin
38
- @map = read
42
+ @map = read_data
39
43
  rescue LockMethod::Locked
40
44
  sleep 0.5
41
45
  pull
@@ -44,7 +48,7 @@ class JsonStore
44
48
 
45
49
  def push
46
50
  begin
47
- write
51
+ write_data
48
52
  rescue LockMethod::Locked
49
53
  sleep 0.5
50
54
  push
@@ -53,20 +57,24 @@ class JsonStore
53
57
 
54
58
  def merge(direction=:into_remote)
55
59
  begin
56
- direction == :into_local ? @map.merge!(read) : read.merge!(@map)
60
+ @map = direction == :into_local ? @map.merge(read_data) : read_data.merge(@map)
57
61
  rescue LockMethod::Locked
58
62
  sleep 0.5
59
63
  merge(direction)
60
64
  end
61
65
  end
62
66
 
63
- def as_lock
64
- 'json_store'
67
+ def db_path
68
+ @db
65
69
  end
66
70
 
67
71
  private
68
72
 
69
- def read
73
+ def as_lock
74
+ 'json_store'
75
+ end
76
+
77
+ def read_data
70
78
  data = {}
71
79
  if File.exists?(@db)
72
80
  f = File.read(@db)
@@ -75,16 +83,15 @@ class JsonStore
75
83
  data
76
84
  end
77
85
 
78
- lock_method :read
86
+ lock_method :read_data
79
87
 
80
- def write
81
- File.open(@db, 'w') { |f| f.write(Oj.dump(@map)) }
88
+ def write_data
89
+ f = File.new(@db, 'w')
90
+ f.write(Oj.dump(@map))
91
+ f.close
82
92
  end
83
93
 
84
- lock_method :write
94
+ lock_method :write_data
85
95
 
86
- def keep_trying
87
-
88
- end
89
96
 
90
97
  end
@@ -0,0 +1,141 @@
1
+ require 'rspec'
2
+ require 'fileutils'
3
+ require File.dirname(__FILE__) + '/../lib/json_store'
4
+
5
+ describe JsonStore do
6
+
7
+ it 'should populate the memory map from file on pull' do
8
+ db = JsonStore.new(File.dirname(__FILE__) + '/test_data/test1.json')
9
+ db.pull
10
+ expect(db.all).to eq({'name' => 'Kingsley'})
11
+ end
12
+
13
+ it 'should create new db if none already exists during push' do
14
+ db = create_new_db('test2.json')
15
+ expect(File.exists?(db.db_path)).to eq(true)
16
+ end
17
+
18
+ it 'should replace file with memory map on push overwriting same keys in file with map data' do
19
+ db = create_new_db('test2.json')
20
+ expect(db.all).to eq({name: 'Kingsley'})
21
+ db.set(:name, 'Kostas')
22
+ db.set(:slot, 'PM')
23
+ db.push
24
+ db.pull
25
+ expect(db.all).to eq({name: 'Kostas', slot: 'PM'})
26
+ end
27
+
28
+ it 'should merge memory map changes into file on merge into_remote' do
29
+ db = create_new_db('test2.json')
30
+ expect(db.all).to eq({name: 'Kingsley'})
31
+ db.set(:name, 'Kostas')
32
+ db.set(:slot, 'PM')
33
+ db.merge
34
+ expect(db.all).to eq({name: 'Kostas', slot: 'PM'})
35
+ end
36
+
37
+ it 'should merge file changes into memory map on merge into_local' do
38
+ db = create_new_db('test2.json')
39
+ expect(db.all).to eq({name: 'Kingsley'})
40
+ db.set(:name, 'Kostas')
41
+ db.set(:slot, 'PM')
42
+ db.merge(:into_local)
43
+ expect(db.all).to eq({name: 'Kingsley', slot: 'PM'})
44
+ end
45
+
46
+ it 'should get value by by key of stored items' do
47
+ db = JsonStore.new(File.dirname(__FILE__) + '/test_data/test1.json')
48
+ db.pull
49
+ expect(db.get('name')).to eq('Kingsley')
50
+ end
51
+
52
+ it 'should return json on get_as_json' do
53
+ db = JsonStore.new(File.dirname(__FILE__) + '/test_data/test1.json')
54
+ db.pull
55
+ expect(db.get_as_json('name')).to eq('"Kingsley"')
56
+ end
57
+
58
+ it 'should return json on all_as_json' do
59
+ db = JsonStore.new(File.dirname(__FILE__) + '/test_data/test1.json')
60
+ db.pull
61
+ expect(db.all_as_json).to eq('{"name":"Kingsley"}')
62
+ end
63
+
64
+ it 'should search basic json structure using json select' do
65
+ db = create_new_db('test2.json', {people: [{first_name: 'Kingsley', last_name: 'Hendrickse'}, {first_name: 'Kostas', last_name: 'Mamalis'}]})
66
+ expect(db.search('.people .first_name')).to eq(['Kingsley', 'Kostas'])
67
+ expect(db.search('.people .first_name', :match)).to eq('Kingsley')
68
+ expect(db.search('.people .first_name', :test)).to eq(true)
69
+ end
70
+
71
+ it 'should be able to store a more complex object' do
72
+ class Person;
73
+ attr_accessor :first_name, :last_name;
74
+
75
+ def initialize(name)
76
+ ; d = name.split(' '); @first_name = d.first; @last_name = d.last;
77
+ end
78
+
79
+ ;
80
+ end
81
+ db = create_new_db('test2.json', {people: [Person.new('Kingsley Hendrickse'), Person.new('Kostas Mamalis')]})
82
+ expect(db.get(:people).map { |person| person.first_name }).to eq(['Kingsley', 'Kostas'])
83
+ end
84
+
85
+ it 'should clear the in memory map' do
86
+ db = create_new_db('test2.json')
87
+ db.clear
88
+ expect(db.all).to eq({})
89
+ end
90
+
91
+ it 'should work with simple scenario' do
92
+ db = create_new_db('test2.json')
93
+ data = {day: 'Mon', year: '2014'}
94
+ db.set(:date, data)
95
+ db.push
96
+ expect(db.get(:date)).to eq(data)
97
+ db2 = JsonStore.new(File.dirname(__FILE__) + '/test_data/test2.json')
98
+ db2.pull
99
+ db2.set(:slot, 'PM')
100
+ db2.push
101
+ db.merge
102
+ expect(db.all).to eq(name: 'Kingsley', date: {day: 'Mon', year: '2014'}, slot: 'PM')
103
+ end
104
+
105
+ it 'should lock to prevent concurrent access' do
106
+ t1 = Thread.new {
107
+ 20.times{
108
+ db = create_new_db('test3.json')
109
+ db.set(:slot, "1_PM")
110
+ db.merge
111
+ db.push
112
+ }
113
+ }
114
+ t2 = Thread.new {
115
+ 20.times {
116
+ db = create_new_db('test3.json')
117
+ db.set(:slot, "2_PM")
118
+ db.merge
119
+ db.push
120
+ }
121
+ }
122
+ t2.join
123
+ t1.join
124
+ db2 = JsonStore.new(File.dirname(__FILE__) + '/test_data/test3.json')
125
+ db2.pull
126
+ expect(db2.get(:slot)).to match(/PM/)
127
+
128
+ end
129
+
130
+ private
131
+
132
+ def create_new_db(path, content={name: 'Kingsley'})
133
+ file_path = File.dirname(__FILE__) + "/test_data/#{path}"
134
+ FileUtils.rm_rf(file_path)
135
+ db = JsonStore.new(file_path)
136
+ db.set(content.keys.first, content[content.keys.first])
137
+ db.push
138
+ db
139
+ end
140
+
141
+ end
@@ -0,0 +1 @@
1
+ {"name":"Kingsley"}
@@ -0,0 +1 @@
1
+ {":name":"Kingsley",":date":{":day":"Mon",":year":"2014"},":slot":"PM"}
@@ -0,0 +1 @@
1
+ {":name":"Kingsley",":slot":"1_PM"}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kingsley Hendrickse
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-19 00:00:00.000000000 Z
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj
@@ -103,14 +103,18 @@ extra_rdoc_files:
103
103
  - README.md
104
104
  files:
105
105
  - ".document"
106
+ - ".travis.yml"
106
107
  - Gemfile
107
- - Gemfile.lock
108
108
  - LICENSE.txt
109
109
  - README.md
110
110
  - Rakefile
111
111
  - VERSION
112
112
  - json_store.gemspec
113
113
  - lib/json_store.rb
114
+ - spec/json_store_spec.rb
115
+ - spec/test_data/test1.json
116
+ - spec/test_data/test2.json
117
+ - spec/test_data/test3.json
114
118
  homepage: http://github.com/kingsleyh/json_store
115
119
  licenses:
116
120
  - MIT
data/Gemfile.lock DELETED
@@ -1,92 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activesupport (4.1.1)
5
- i18n (~> 0.6, >= 0.6.9)
6
- json (~> 1.7, >= 1.7.7)
7
- minitest (~> 5.1)
8
- thread_safe (~> 0.1)
9
- tzinfo (~> 1.1)
10
- addressable (2.3.6)
11
- builder (3.2.2)
12
- cache (0.4.0)
13
- descendants_tracker (0.0.4)
14
- thread_safe (~> 0.3, >= 0.3.1)
15
- diff-lcs (1.2.5)
16
- faraday (0.9.0)
17
- multipart-post (>= 1.2, < 3)
18
- git (1.2.7)
19
- github_api (0.11.3)
20
- addressable (~> 2.3)
21
- descendants_tracker (~> 0.0.1)
22
- faraday (~> 0.8, < 0.10)
23
- hashie (>= 1.2)
24
- multi_json (>= 1.7.5, < 2.0)
25
- nokogiri (~> 1.6.0)
26
- oauth2
27
- hashie (3.0.0)
28
- highline (1.6.21)
29
- i18n (0.6.9)
30
- jeweler (2.0.1)
31
- builder
32
- bundler (>= 1.0)
33
- git (>= 1.2.5)
34
- github_api
35
- highline (>= 1.6.15)
36
- nokogiri (>= 1.5.10)
37
- rake
38
- rdoc
39
- json (1.8.1)
40
- json_select (0.1.4)
41
- treetop
42
- jwt (1.0.0)
43
- lock_method (0.5.5)
44
- activesupport
45
- cache (>= 0.2.1)
46
- mini_portile (0.6.0)
47
- minitest (5.3.5)
48
- multi_json (1.10.1)
49
- multi_xml (0.5.5)
50
- multipart-post (2.0.0)
51
- nokogiri (1.6.2.1)
52
- mini_portile (= 0.6.0)
53
- oauth2 (0.9.4)
54
- faraday (>= 0.8, < 0.10)
55
- jwt (~> 1.0)
56
- multi_json (~> 1.3)
57
- multi_xml (~> 0.5)
58
- rack (~> 1.2)
59
- oj (2.9.6)
60
- polyglot (0.3.5)
61
- rack (1.5.2)
62
- rake (10.3.2)
63
- rdoc (4.1.1)
64
- json (~> 1.4)
65
- rspec (3.0.0)
66
- rspec-core (~> 3.0.0)
67
- rspec-expectations (~> 3.0.0)
68
- rspec-mocks (~> 3.0.0)
69
- rspec-core (3.0.1)
70
- rspec-support (~> 3.0.0)
71
- rspec-expectations (3.0.1)
72
- diff-lcs (>= 1.2.0, < 2.0)
73
- rspec-support (~> 3.0.0)
74
- rspec-mocks (3.0.1)
75
- rspec-support (~> 3.0.0)
76
- rspec-support (3.0.0)
77
- thread_safe (0.3.4)
78
- treetop (1.5.3)
79
- polyglot (~> 0.3)
80
- tzinfo (1.2.1)
81
- thread_safe (~> 0.1)
82
-
83
- PLATFORMS
84
- ruby
85
-
86
- DEPENDENCIES
87
- bundler (~> 1.0)
88
- jeweler (~> 2.0.1)
89
- json_select
90
- lock_method
91
- oj
92
- rspec (~> 3.0.0.rc1)