localstore 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +20 -0
- data/lib/localstore.rb +119 -0
- data/spec/localstore_spec.rb +58 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 75a0f31d41f3a25e79784f76c5801a7805203113
|
4
|
+
data.tar.gz: c707c8a66d4f2501fc3602bf3eebd41c56d1d3d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 633d2c10d8b1eb91101e7180c85f13b6d8981a4d5336bce373ca0d8e67c00df377efedf39c3458335b2f8ae40011f770ad9065f8183d7690270374c1d4f00395
|
7
|
+
data.tar.gz: dbff138aa1c5c0f01f58ed7a1ed757ebfc8d1ac40755b3ecf2bf4918732d7de99812edf5fbb5f27175b4a6d0a8337dae64810e5ff739109a2e270c4fcb9a9273
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# File: Rakefile
|
2
|
+
# Time-stamp: <2018-12-13 11:06:32>
|
3
|
+
# Copyright (C) 2018 Pierre Lecocq
|
4
|
+
# Description: LocalStore rake tasks
|
5
|
+
|
6
|
+
task default: :spec
|
7
|
+
|
8
|
+
# Spec
|
9
|
+
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new :spec
|
13
|
+
|
14
|
+
# Yard
|
15
|
+
|
16
|
+
require 'yard'
|
17
|
+
|
18
|
+
YARD::Rake::YardocTask.new do |t|
|
19
|
+
t.files = ['lib/**/*.rb']
|
20
|
+
end
|
data/lib/localstore.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# File: localstore.rb
|
2
|
+
# Time-stamp: <2018-12-14 08:16:38>
|
3
|
+
# Copyright (C) 2018 Pierre Lecocq
|
4
|
+
# Description: LocalStore module for classes
|
5
|
+
|
6
|
+
# Provides a class level local data store with namespaces support.
|
7
|
+
#
|
8
|
+
# API:
|
9
|
+
#
|
10
|
+
# When calling `localstore` at the top of a class definition, class and instance methods are created automatically:
|
11
|
+
#
|
12
|
+
# - <namespace>_store(key, value) to store data in the local store
|
13
|
+
# - <namespace>_fetch(key = nil) to fetch data from the local store
|
14
|
+
# - <namespace>_flush to flush data from the local store
|
15
|
+
#
|
16
|
+
# @example Local storage from class and instance methods
|
17
|
+
#
|
18
|
+
# require 'localstore'
|
19
|
+
#
|
20
|
+
# class TestLocalStore
|
21
|
+
# extend LocalStore
|
22
|
+
#
|
23
|
+
# # Initialize namespace
|
24
|
+
# localstore :test
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Class methods#
|
28
|
+
# TestLocalStore.test_store :hello, 'world'
|
29
|
+
# p TestLocalStore.test_fetch :hello
|
30
|
+
# p TestLocalStore.test_fetch
|
31
|
+
# TestLocalStore.test_flush
|
32
|
+
# p TestLocalStore.test_fetch
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# # Instance methods
|
36
|
+
# obj = TestLocalStore.new
|
37
|
+
# obj.test_store :hello2, 'world2'
|
38
|
+
# p obj.test_fetch :hello2
|
39
|
+
# p obj.test_fetch
|
40
|
+
# obj.test_flush
|
41
|
+
# p obj.test_fetch
|
42
|
+
#
|
43
|
+
module LocalStore
|
44
|
+
# Library name
|
45
|
+
NAME = 'localstore'.freeze
|
46
|
+
|
47
|
+
# Semantic version number
|
48
|
+
VERSION = [0, 5, 0].join '.'
|
49
|
+
|
50
|
+
# @!visibility private
|
51
|
+
attr_reader :_local_store
|
52
|
+
|
53
|
+
# Create a new namespace in the local store and create dynamic class methods
|
54
|
+
# to interact with the store
|
55
|
+
#
|
56
|
+
# @param namespace [Symbol, String] namespace to create
|
57
|
+
def localstore(namespace)
|
58
|
+
localstores namespace
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create multiple new namespaces in the local store and create dynamic class
|
62
|
+
# methods to interact with the store
|
63
|
+
#
|
64
|
+
# @param namespaces [Array<Symbol>, Array<String>] namespaces to create
|
65
|
+
def localstores(*namespaces)
|
66
|
+
namespaces.each do |namespace|
|
67
|
+
@_local_store ||= {}
|
68
|
+
@_local_store[namespace] ||= {}
|
69
|
+
|
70
|
+
create_class_methods namespace
|
71
|
+
create_instance_methods namespace
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Create class metods according to the namespace
|
76
|
+
#
|
77
|
+
# @api private
|
78
|
+
#
|
79
|
+
# @param namespace [Symbol, String]
|
80
|
+
def create_class_methods(namespace)
|
81
|
+
self.class.send :define_method, "#{namespace}_store" do |key, value|
|
82
|
+
@_local_store[namespace][key] = value
|
83
|
+
end
|
84
|
+
|
85
|
+
self.class.send :define_method, "#{namespace}_fetch" do |key = nil|
|
86
|
+
return @_local_store[namespace] if key.nil?
|
87
|
+
|
88
|
+
@_local_store[namespace].fetch key
|
89
|
+
end
|
90
|
+
|
91
|
+
self.class.send :define_method, "#{namespace}_flush" do
|
92
|
+
@_local_store[namespace] = {}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Create instance methods according to a namespace.
|
97
|
+
# They are only proxy methods to class methods
|
98
|
+
#
|
99
|
+
# @api private
|
100
|
+
#
|
101
|
+
# @param namespace [Symbol, String]
|
102
|
+
def create_instance_methods(namespace)
|
103
|
+
define_method "#{namespace}_store" do |key, value|
|
104
|
+
self.class.send "#{namespace}_store", key, value
|
105
|
+
end
|
106
|
+
|
107
|
+
define_method "#{namespace}_fetch" do |key = nil|
|
108
|
+
self.class.send "#{namespace}_fetch", key
|
109
|
+
end
|
110
|
+
|
111
|
+
define_method "#{namespace}_flush" do
|
112
|
+
self.class.send "#{namespace}_flush"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# https://6ftdan.com/allyourdev/2015/02/24/writing-methods-for-both-class-and-instance-levels/
|
118
|
+
# http://railstic.com/2011/06/dynamically-defining-methods-with-define_method/
|
119
|
+
# http://paulsturgess.co.uk/blog/2018/01/09/ruby-metaprogramming-define-method-and-instance-exec/
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# File: localstore_spec.rb
|
2
|
+
# Time-stamp: <2018-12-14 08:08:11>
|
3
|
+
# Copyright (C) 2018 Pierre Lecocq
|
4
|
+
# Description: LocalStore module spec
|
5
|
+
|
6
|
+
require_relative '../lib/localstore'
|
7
|
+
|
8
|
+
describe LocalStore do
|
9
|
+
before :all do
|
10
|
+
class TestLocalStore
|
11
|
+
extend LocalStore
|
12
|
+
|
13
|
+
localstore :test
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'checks class methods' do
|
18
|
+
expect(TestLocalStore).to respond_to :test_store
|
19
|
+
expect(TestLocalStore).to respond_to :test_fetch
|
20
|
+
expect(TestLocalStore).to respond_to :test_flush
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'checks instance methods' do
|
24
|
+
obj = TestLocalStore.new
|
25
|
+
|
26
|
+
expect(obj).to respond_to :test_store
|
27
|
+
expect(obj).to respond_to :test_fetch
|
28
|
+
expect(obj).to respond_to :test_flush
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'checks local store from class methods calls' do
|
32
|
+
TestLocalStore.test_store :key_1, '1'
|
33
|
+
TestLocalStore.test_store :key_2, '2'
|
34
|
+
|
35
|
+
expect(TestLocalStore.test_fetch(:key_1)).to be == '1'
|
36
|
+
expect(TestLocalStore.test_fetch(:key_2)).to be == '2'
|
37
|
+
expect(TestLocalStore.test_fetch).to be == { key_1: '1', key_2: '2' }
|
38
|
+
|
39
|
+
TestLocalStore.test_flush
|
40
|
+
|
41
|
+
expect(TestLocalStore.test_fetch).to be == {}
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'checks local store from instance methods calls' do
|
45
|
+
obj = TestLocalStore.new
|
46
|
+
|
47
|
+
obj.test_store :key_3, '3'
|
48
|
+
obj.test_store :key_4, '4'
|
49
|
+
|
50
|
+
expect(obj.test_fetch(:key_3)).to be == '3'
|
51
|
+
expect(obj.test_fetch(:key_4)).to be == '4'
|
52
|
+
expect(obj.test_fetch).to be == { key_3: '3', key_4: '4' }
|
53
|
+
|
54
|
+
obj.test_flush
|
55
|
+
|
56
|
+
expect(obj.test_fetch).to be == {}
|
57
|
+
end
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: localstore
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pierre Lecocq
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-12-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Provides a class level local data store with namespaces support
|
14
|
+
email: pierre.lecocq@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- Rakefile
|
20
|
+
- lib/localstore.rb
|
21
|
+
- spec/localstore_spec.rb
|
22
|
+
homepage: https://github.com/pierre-lecocq/localstore
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.6.14
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Local data store
|
46
|
+
test_files: []
|