sid_list 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bcb011cca900e1071244d7ad7cc3b0190f4fadff
4
+ data.tar.gz: 364210567619c5d65854c032d93b49890430f61a
5
+ SHA512:
6
+ metadata.gz: cdede409505f1ddba9077db2db90b1c4306d979ca1a966505ba5778505528246e855134cb237db800a9b7262a1476bea17fdc97d170962be5702b5b1887e5b42
7
+ data.tar.gz: 5ddc2432944f46dbd8b7b4cff6e60f32b5924d7352540b026b835985e344c5756b98ce1549dfd2b199482b41738537a9f7081be7646fa2bfdd3c78a1c74980f1
data/.gitignore ADDED
@@ -0,0 +1,52 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ md
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+
20
+ # Configs and tests
21
+ test.rb
22
+ *.yml
23
+ *.yaml
24
+
25
+ # Packages #
26
+ ############
27
+ # it's better to unpack these files and commit the raw source
28
+ # git has its own built in compression methods
29
+ *.7z
30
+ *.dmg
31
+ *.gz
32
+ *.iso
33
+ *.jar
34
+ *.rar
35
+ *.tar
36
+ *.zip
37
+
38
+ # Linux generated files #
39
+ #########################
40
+ *~
41
+
42
+ # OS generated files #
43
+ ######################
44
+ .DS_Store
45
+ .DS_Store?
46
+ ._*
47
+ .Spotlight-V100
48
+ .Trashes
49
+ Icon?
50
+ ehthumbs.db
51
+ Thumbs.db
52
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sid_list.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sid_list (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (10.1.0)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bundler (~> 1.3)
16
+ rake
17
+ sid_list!
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sikian
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.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = Sid List
2
+
3
+ List containing any type of Object intenteded to be indexed by status and id, making it easy to select all Objects for a given status, update the list, etc.
4
+
5
+ == Introduction
6
+
7
+ Sid List is a list I created for one of the servers I developed. The idea behind it was to provide a list that could easily manage any type of objects and index them by status & id and be able to load and update itself with just a command once it had been extended.
8
+
9
+ As I had previously developed MdlSql (a modular sql gem), configuring the gem as I wanted proved itself clear and easy. For example, in case I wanted to make a list of instances which would be loaded from Mysql, it would go the following way:
10
+
11
+ require 'mdlsql'
12
+ class InstanceList < SidList
13
+ def load_hash
14
+ results = MdlSql::select.from(:instances).where(:status, 1, '>').execute
15
+ end
16
+ def update_hash time
17
+ results = MdlSql::select.from(:instances).where("status > 1 AND updated_at > #{time}").execute
18
+ end
19
+ def new_obj obj_data
20
+ obj = Instance.new obj_data
21
+ end
22
+ end
23
+
24
+ And with this I could just go straight to work with the list:
25
+
26
+ il = InstanceList.new
27
+ il.load
28
+ il.ready.first # Get the first of the 'ready' instance
29
+ il.update
30
+
31
+ == License
32
+
33
+ Copyright (C) 2013 Sid List contributers
34
+
35
+ This program is free software: you can redistribute it and/or modify
36
+ it under the terms of the GNU General Public License as published by
37
+ the Free Software Foundation, either version 3 of the License, or
38
+ (at your option) any later version.
39
+
40
+ This program is distributed in the hope that it will be useful,
41
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43
+ GNU General Public License for more details.
44
+
45
+ You should have received a copy of the GNU General Public License
46
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
47
+
48
+ In order to contact the author of this gem, please write to sikian@gmail.com.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/git.pub ADDED
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDXjQe85FC6wXxk9xCeI6qb7rqeoBIErMlPpXIokBQgtdlzH8JJcWdKsUjvJpEU0DW5SP+wsLDsiDruFqzgVV4KsNp/akCcK4FDd/6zAeVF7z8fODTGs+NQl5/yGbYUJ3u7M26unrLg8HwH/NjjTX2b2PQq83MY3pnZjncuQc5ZBKL+9Kv8j5dCzxVhQfbSc/xEUZzWt6KR0ABxlM8fZcGacfClI0t970NSXBpmsJOZAL4wRq94ZfSeSqcnCnsFyN/jDe1oyWiRoV2IGyV6Gp75mBb0BJtesybwddlRQn8xenDvVmGvOha2+NdUmQ9K3zLFXVRzcYKzI0p4YY3IHknP owl@arch
@@ -0,0 +1,3 @@
1
+ class SidList
2
+ VERSION = "0.0.1"
3
+ end
data/lib/sid_list.rb ADDED
@@ -0,0 +1,259 @@
1
+ require "sid_list/version"
2
+
3
+ class SidList
4
+ # Creates a list of objects (jobs, instances, etc.) indexed by id & status
5
+ attr_accessor :list_by_status, :list_by_id
6
+
7
+ def initialize
8
+ @list_by_id = Array.new()
9
+ @list_by_status = Hash.new()
10
+ end
11
+
12
+ # Finds objecst in the list based on any of its accessible attributes.
13
+ # If only a Fixnum is passed, it will be interpreted as an id search.
14
+ # @note the Object must respond to obj#attribute().
15
+ # @return [Array] Objects found.
16
+ #
17
+ # @params values [Hash] Params. for search.
18
+ # @params values [Fixnum] Id.
19
+ def find values={}
20
+ found = Array.new
21
+
22
+ if values.is_a? Fixnum
23
+ return @list_by_id[values]
24
+ # values = {:id => values}
25
+ elsif !values.is_a? Hash
26
+ raise ArgumentError, 'argument must be a Hash or a Fixnum.'
27
+ end
28
+
29
+ @list_by_status.each do |status, status_list|
30
+
31
+ status_list.each do |obj|
32
+
33
+ # Catch is now acting as an OR condition.
34
+ # Maybe it would be a good idea to do it an AND
35
+ # @todo change this to AND
36
+ catch :not_equal do
37
+ values.each do |term, value|
38
+ if obj.send(term)!= value
39
+ throw :not_equal
40
+ end
41
+ end
42
+ found << obj
43
+ end
44
+
45
+ end
46
+ end
47
+
48
+ return found
49
+ end
50
+
51
+ def add obj
52
+ @list_by_id[obj.id] = obj # Add obj by id
53
+
54
+ # Add obj by status. ensure_status_in_list is called to make sure that the status
55
+ # has an array in @list_by_status.
56
+ ensure_status_in_list(obj.status) << obj
57
+
58
+ return self
59
+ end
60
+
61
+ # @overload delete(obj)
62
+ # Deletes an object from the list.
63
+ # @param [Object] obj Object to be deleted.
64
+ #
65
+ # @overload delete(id)
66
+ # Deletes an object from the list using its id.
67
+ # @param [Fixnum] id Object's id.
68
+ #
69
+ # @todo revise first part to get an optimum algorithm.
70
+ def delete value
71
+ if value.is_a? Fixnum
72
+ id = value
73
+ obj = @list_by_id[value]
74
+ else
75
+ obj = value
76
+ id = obj.id
77
+ value = nil
78
+ end
79
+
80
+ @list_by_id.delete_at(id)
81
+ @list_by_status[obj.status].delete obj
82
+
83
+ return self
84
+ end
85
+
86
+ # Loads objects into list.
87
+ # Objects must be able to receive data in initialization, i.e. Object.new(:name => '', :id => '', ...)
88
+ def load
89
+ load_objs.each do |obj|
90
+ add obj
91
+ end
92
+ end
93
+
94
+ # @todo better time options
95
+ # @todo find a way to move adding here without cycling again
96
+ def update opts={}
97
+ time = opts[:time]? opts[:time] : Time.now.utc
98
+ update_objs time
99
+ end
100
+
101
+ # @option opts [Symbol] :noforce
102
+ # @option opts [Symbol] :old_status
103
+ def change_status obj, new_status, opts={}
104
+ if obj.is_a? Fixnum
105
+ id = obj
106
+ obj = self.find(id).first
107
+ end
108
+
109
+ # Delete Object from old_status
110
+ # If old_status is given, it's easily done.
111
+ # Otherwise, the object's status must be check to see if it's not the new one (and supose it's the old one).
112
+ # If the status has already been changed, the Object is looked for in @list_by_status.
113
+ #
114
+ # In any case, we will proceed to the next method if the Object is not found and deleted.
115
+ #
116
+ # Maybe it would be easier just to delete and re-add the Object, but the status may have already changed.
117
+
118
+ deleted = nil
119
+
120
+ # Using opts[:old_status]
121
+ if opts[:old_status]
122
+ if @list_by_status[:old_status].delete(obj)
123
+ deleted = true
124
+ end
125
+ end
126
+
127
+ # Using obj.status
128
+ unless deleted && obj.status == new_status
129
+ if @list_by_status[obj.status].delete(obj)
130
+ deleted = true
131
+ end
132
+ end
133
+
134
+ # Search through @list_by_status
135
+ unless deleted
136
+ catch :deleted do
137
+ @list_by_status.each do |status, status_list|
138
+ if status_list.include? obj
139
+ @list_by_status[status].delete obj
140
+ deleted = true
141
+ throw :deleted
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ # Force status, avoidable with :noforce
148
+ obj.status = new_status unless obj.status == new_status || opts[:noforce]
149
+
150
+ # Only add again if deleted?
151
+ # Maybe should add anyway. Or be strict and just allow adding with #add
152
+ ensure_status_in_list(new_status) << obj if deleted
153
+
154
+ # Return nil if it has not been deleted (and therefore, not added).
155
+ return deleted
156
+ end
157
+
158
+ private
159
+
160
+ ###
161
+ # The following methods must be overwritten to configure the list:
162
+ # load_hash
163
+ # update_hash
164
+ # new_obj
165
+ #
166
+
167
+ # @return [Array] data to be loaded into list
168
+ # @note This method must be overwritten to configure the list.
169
+ def load_hash
170
+ raise 'StatusList#load_hash() has not been overwritten to allow data to be loaded into the list.'
171
+
172
+ return Array.new
173
+ end
174
+
175
+ # @return [Hash] values to be updated/added. Please see example to see how this hash should be.
176
+ # @example update_hash's return
177
+ # update_hash(now) # => {:created => [{:id => 1, ...}, ...], :updated => [{:id => 10, ...}, ...]}
178
+ # @note This method must be overwritten to configure the list.
179
+ def update_hash time
180
+ raise 'StatusList#update_hash() has not been overwritten to allow data in the list to be updated.'
181
+
182
+ return Hash.new
183
+ end
184
+
185
+ # @param obj_data [Hash] data to be loaded to the Object.
186
+ # @return [Object] new Object the list is composed of.
187
+ # @note This method must be overwritten to configure the list.
188
+ def new_obj obj_data
189
+ raise 'StatusList#new_obj(obj_data)has not been overwritten to allow new objects to be created.'
190
+ end
191
+
192
+ def load_objs
193
+ list_data = load_hash()
194
+ obj_array = Array.new()
195
+
196
+ list_data.each do |obj_data|
197
+ obj_array << new_obj(obj_data)
198
+ end
199
+
200
+ return obj_array
201
+ end
202
+
203
+ # Uses #update_hash to get all objects to be added or edited.
204
+ # @param time [Time] time to pass to update_hash in order to get new changes.
205
+ # @note update_hash must return a Hash with keys :created and :updated (see #update_hash).
206
+
207
+ def update_objs time
208
+ list_data = update_hash(time)
209
+ created_obj_array = Array.new()
210
+ updated_obj_array = Array.new()
211
+
212
+ if list_data[:created]
213
+ list_data[:created].each do |obj_data|
214
+ add new_obj obj_data
215
+ end
216
+ end
217
+ if list_data[:updated]
218
+ list_data[:updated].each do |obj_data|
219
+ edit_obj obj_data
220
+ end
221
+ end
222
+ end
223
+
224
+ # Updates/Edits an object that already exists.
225
+ # @note Object must respond to the hash's keys. Otherwise an exception will be raised.
226
+ # @param obj_data [Hash] new values for the object.
227
+ # @return obj [Object] edited Object.
228
+ # @return obj [NilClass] nil if no Object was found to be edited.
229
+ def edit_obj obj_data
230
+ obj = @list_by_id[obj_data[:id]]
231
+
232
+ if obj
233
+ obj_data.each do |key,value|
234
+ obj.send("#{key}=", value)
235
+ end
236
+ end
237
+
238
+ return obj
239
+ end
240
+
241
+ # Returns the list for a given status. If there is no such status in list, it is added
242
+ # (as a new array). It also defines the method #{status}, that calls all the objects with that status,
243
+ # if it hasn't been already been defined.
244
+ # @note if a status has the same name as any of the methods defined in the class, it wont be overwritten.
245
+ # @param status [Symbol]
246
+ def ensure_status_in_list status
247
+ unless @list_by_status[status].is_a? Array
248
+ @list_by_status[status] = Array.new
249
+ end
250
+ unless self.respond_to?(status)
251
+ puts 'i dont respond'
252
+ self.class.send(:define_method, status) do
253
+ @list_by_status[status]
254
+ end
255
+ end
256
+
257
+ return @list_by_status[status]
258
+ end
259
+ end
data/sid_list.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sid_list/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sid_list"
8
+ spec.version = SidList::VERSION
9
+ spec.authors = ["Sikian"]
10
+ spec.email = ["sikian@gmail.com"]
11
+ spec.description = %q{List containing any type of Object intenteded to be indexed by status and id, making it easy to select all Objects for a given status, update the list, etc.}
12
+ spec.summary = %q{List indexed by status & id.}
13
+ spec.homepage = ""
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", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/test/testclass.rb ADDED
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require "sid_list"
7
+
8
+
9
+ class List < SidList
10
+
11
+ def update_hash time
12
+ hash = {:updated => [{:id => 3, :name=>'meou'}]}
13
+ return hash
14
+ end
15
+ end
16
+
17
+ class Job
18
+ attr_accessor :id, :name, :status, :date
19
+
20
+ def initialize values={}
21
+ @id = values[:id]
22
+ @name = values[:name]
23
+ @status = values[:status]
24
+ @date = values[:date]
25
+ end
26
+ end
27
+
28
+ jobs = List.new
29
+
30
+ jobs.add Job.new :id => 1, :name => 'aaa', :status => :new, :date => '2013-03-25 16:24:58'
31
+ jobs.add Job.new :id => 2, :name => 'bbb', :status => :new, :date => '2013-03-25 16:24:58'
32
+ jobs.add Job.new :id => 3, :name => 'ccc', :status => :old, :date => '2013-03-25 16:24:58'
33
+ jobs.add Job.new :id => 4, :name => 'aaa', :status => :old, :date => '2013-03-25 16:24:58'
34
+ jobs.add Job.new :id => 5, :name => 'bbb', :status => :new, :date => '2013-03-25 16:24:58'
35
+
36
+ # puts "found: #{jobs.find :name => 'aaa', :id => 3}"
37
+ # puts jobs.list_by_status.inspect
38
+
39
+ # puts jobs.find(:name => 'aaa', :status => :new).inspect
40
+ # jobs.change_status(1, :old)
41
+ # puts jobs.list_by_status.inspect
42
+
43
+ puts jobs.update
44
+ puts jobs.find(3).inspect
45
+ puts jobs.old
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sid_list
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sikian
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-02 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: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: List containing any type of Object intenteded to be indexed by status
42
+ and id, making it easy to select all Objects for a given status, update the list,
43
+ etc.
44
+ email:
45
+ - sikian@gmail.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - .gitignore
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE.txt
54
+ - README.rdoc
55
+ - Rakefile
56
+ - git.pub
57
+ - lib/sid_list.rb
58
+ - lib/sid_list/version.rb
59
+ - sid_list.gemspec
60
+ - test/testclass.rb
61
+ homepage: ''
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.0.3
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: List indexed by status & id.
85
+ test_files:
86
+ - test/testclass.rb
87
+ has_rdoc: