-
-
Save reddyonrails/e7decf3ca2104fb0062d8a8d69a39c23 to your computer and use it in GitHub Desktop.
Revisions
-
Loupi revised this gist
May 27, 2012 . 1 changed file with 9 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,8 +43,10 @@ def leaf(id) end def delete(comment, parentId, itemId, isMainThread = true) @redis.multi { |multi| inner_delete comment, parentId, isMainThread, multi multi.del json_key(itemId) } end private @@ -67,16 +69,16 @@ def process_comments(comments) } end def inner_delete(comment, parentId, isMainThread, multi) if comment.kind_of?(Array) comment.each {|c| inner_delete c, parentId, isMainThread, multi} else id = comment['id'] comments = comment['comments'] k = isMainThread ? comments_key(parentId) : sub_comments_key(parentId) multi.del comment_key(id) multi.zrem k, id inner_delete comments, id, false, multi if comments end end -
Loupi revised this gist
May 27, 2012 . 1 changed file with 114 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,114 @@ require 'optparse' require './nested-redis' options = {} COMMANDS = {save: 1, delete: 2, print: 3, leaf: 4, remove: 5, dummy: 6} FORMATS = {text: 1, json: 2, pretty_json:3} optparse = OptionParser.new { |opts| opts.banner = "Usage: redis-cmd.rb command [options]" opts.on('-s', '--save item, parent, comment', Array, 'Save a comment on an item.') { |itemId, parentId, comment| options[:command] = COMMANDS[:save] options[:itemId] = itemId options[:parentId] = parentId if parentId != '0' options[:comment] = comment } opts.on('-p', '--print itemId', 'Print the comment hierarchy of an item.') { |itemId| options[:command] = COMMANDS[:print] options[:itemId] = itemId options[:format] = FORMATS[:text] } opts.on('-l', '--leaf leafId', 'Print the hierarchy of a leaf.') { |leafId| options[:command] = COMMANDS[:leaf] options[:itemId] = leafId options[:format] = FORMATS[:text] } opts.on('-d', '--delete itemId', 'Delete all the comments of an item.') { |itemId| options[:command] = COMMANDS[:delete] options[:itemId] = itemId } opts.on('-r', '--remove item, leaf, parent', Array, 'Delete a leaf and it\'s hierarchy from a comment.') { |itemId, leafId, parentId| options[:command] = COMMANDS[:remove] options[:itemId] = itemId options[:leafId] = leafId options[:parentId] = parentId } opts.on('-u', '--dummy itemId', 'Save a dummy comment hierarchy on an item.') { |itemId| options[:command] = COMMANDS[:dummy] options[:itemId] = itemId } opts.on('-j', '--json [pretty]', 'Set the output format to JSON.') { |pretty| options[:format] = pretty ? FORMATS[:pretty_json] : FORMATS[:json] } opts.on( '-h', '--help', 'Display this screen' ) { puts opts exit } } def print_comments(comments, tabs = 0) comments.each { |comment| tabs.times { putc "\t" } puts "#{comment['comment']}" if comment['comments'] print_comments comment['comments'], tabs + 1 end } end def save_dummy(cr, id) tree = cr.save(id, { comment:'Tree', test:1 }) root = cr.save(id, { comment:'Root', kind:'ginger', age:50 }, tree) trunk = cr.save(id, { comment:'Trunk', kmh_to_mph:0.621 }, tree) branch = cr.save(id, { comment:'Branch' }, trunk) leaf = cr.save(id, { comment:'Leaf' }, branch) top = cr.save(id, { comment:'Top' }, tree) end def print_result comments, options case options[:format] when FORMATS[:text] print_comments comments when FORMATS[:json] puts comments.to_json when FORMATS[:pretty_json] puts JSON.pretty_generate(comments) end end optparse.parse! id = options[:itemId] cr = CommentsRepository.new case options[:command] when COMMANDS[:save] comment = { comment: options[:comment] } id = cr.save(id, comment, options[:parentId]) puts "New comment saved with id #{id}." when COMMANDS[:print] print_result cr.get(id), options when COMMANDS[:leaf] print_result [cr.leaf(id)], options when COMMANDS[:delete] cr.delete cr.get(id), id, id when COMMANDS[:remove] cr.delete cr.leaf(options[:leafId]), options[:parentId], id, false when COMMANDS[:dummy] save_dummy cr, id else puts optparse end -
Loupi revised this gist
May 27, 2012 . 1 changed file with 0 additions and 38 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -97,41 +97,3 @@ def sub_comments_key(id) end end -
Loupi revised this gist
May 26, 2012 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -13,11 +13,11 @@ def save(itemId, comment, parentId = nil) comment = {id: id, time: now}.merge(comment) k = parentId ? sub_comments_key(parentId) : comments_key(itemId) @redis.multi { |multi| multi.del json_key(itemId) multi.hmset comment_key(id), comment.map { |k,v| [k,v] }.flatten(1) multi.zadd k, now, id } id end @@ -109,9 +109,9 @@ def print_comments(comments, tabs = 0) end def save_dummy(cr, id) tree = cr.save(id, { comment:'Tree', test:1 }) root = cr.save(id, { comment:'Root', kind:'ginger', age:50 }, tree) trunk = cr.save(id, { comment:'Trunk', kmh_to_mph:0.621 }, tree) branch = cr.save(id, { comment:'Branch' }, trunk) leaf = cr.save(id, { comment:'Leaf' }, branch) top = cr.save(id, { comment:'Top' }, tree) -
Loupi revised this gist
May 26, 2012 . 1 changed file with 64 additions and 78 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,151 +1,137 @@ require 'redis' require 'json' class CommentsRepository def initialize @redis = Redis.new end def save(itemId, comment, parentId = nil) now = Time.now.utc.to_i id = @redis.incr(1) comment = {id: id, time: now}.merge(comment) k = parentId ? sub_comments_key(parentId) : comments_key(itemId) @redis.multi do |multi| multi.del json_key(itemId) multi.hmset comment_key(id), comment.map { |k,v| [k,v] }.flatten(1) multi.zadd k, now, id end id end def get(id) jsonId = json_key(id) jsonComments = @redis.get(jsonId) if jsonComments comments = JSON.parse(jsonComments) else comments = multi_fetch(comments_key(id)) @redis.set jsonId, comments.to_json end comments end def leaf(id) comment = @redis.hgetall(comment_key(id)) comment['comments'] = multi_fetch(sub_comments_key(id)) comment end def delete(comment, parentId, itemId, isMainThread = true) inner_delete comment, parentId, isMainThread @redis.del json_key(itemId) end private def multi_fetch(key) commentIds = @redis.zrange(key, 0, -1) comments = @redis.multi { |multi| commentIds.map { |id| multi.hgetall(comment_key(id)) } } process_comments(comments) end def process_comments(comments) comments.each { |comment| subCommentsId = sub_comments_key(comment['id']) if @redis.zcard(subCommentsId) > 0 comment['comments'] = multi_fetch(subCommentsId) end } end def inner_delete(comment, parentId, isMainThread) if comment.kind_of?(Array) comment.each {|c| inner_delete c, parentId, isMainThread} else id = comment['id'] comments = comment['comments'] k = isMainThread ? comments_key(parentId) : sub_comments_key(parentId) @redis.del comment_key(id) @redis.zrem k, id inner_delete comments, id, false if comments end end def json_key(id) "comment:#{id}:json" end def comment_key(id) "comment:#{id}" end def comments_key(id) "comments:#{id}" end def sub_comments_key(id) "comment:#{id}:sub" end end def print_comments(comments, tabs = 0) comments.each { |comment| tabs.times { putc "\t" } puts "#{comment['comment']}" if comment['comments'] print_comments comment['comments'], tabs + 1 end } end def save_dummy(cr, id) tree = cr.save(id, { comment:'Tree',test:1 }) root = cr.save(id, { comment:'Root',kind:'ginger', age:50 }, tree) trunk = cr.save(id, { comment:'Trunk',kmh_to_mph:0.621 }, tree) branch = cr.save(id, { comment:'Branch' }, trunk) leaf = cr.save(id, { comment:'Leaf' }, branch) top = cr.save(id, { comment:'Top' }, tree) end command = ARGV[0] id = ARGV[1] cr = CommentsRepository.new case command when 's' save_dummy cr, id when 'p' print_comments cr.get(id) when 'l' print_comments [cr.leaf(id)] when 'd' cr.delete cr.get(id), id, id when 'r' cr.delete cr.leaf(ARGV[2]), ARGV[3], id, false when 'j' puts JSON.pretty_generate(cr.get(id)) end -
Loupi revised this gist
May 26, 2012 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -36,11 +36,13 @@ def get id end end def leaf id comment = @redis.hgetall commentKey id comment['comments'] = multiFetch subCommentsKey id comment end def delete comment, parentId, itemId, isMainThread = true innerDelete comment, parentId, isMainThread -
Loupi revised this gist
May 26, 2012 . 1 changed file with 122 additions and 45 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,72 +1,149 @@ require 'redis' require 'securerandom' require 'json' class CommentsRepository def initialize @redis = Redis.new end def save itemId, comment, parentId = nil now = Time.now.utc.to_i id = @redis.incr 1 comment = {id: id, comment: comment, time: now} childsOfKey = parentId ? subCommentsKey(parentId) : commentsKey(itemId) @redis.multi do |multi| @redis.del jsonKey itemId @redis.hmset commentKey(id), comment.map{|k,v| [k,v]}.flatten(1) @redis.zadd childsOfKey, now, id end id end def get id jsonId = jsonKey id jsonComments = @redis.get jsonId if jsonComments JSON.parse jsonComments else comments = multiFetch commentsKey id @redis.set jsonId, comments.to_json comments end end def leaf id comment = @redis.hgetall commentKey id comment['comments'] = multiFetch subCommentsKey id comment end def delete comment, parentId, itemId, isMainThread = true innerDelete comment, parentId, isMainThread @redis.del jsonKey itemId end private def multiFetch key commentIds = @redis.zrange key, 0, -1 comments = @redis.multi do |multi| commentIds.map { |id| multi.hgetall(commentKey id)} end processComments comments end def processComments comments comments.each do |comment| subCommentsId = subCommentsKey comment['id'] if @redis.zcard(subCommentsId) > 0 comment['comments'] = multiFetch subCommentsId end end end def innerDelete comment, parentId, isMainThread if comment.kind_of? Array comment.each {|c| innerDelete c, parentId, isMainThread} else id = comment['id'] comments = comment['comments'] childsKey = isMainThread ? commentsKey(parentId) : subCommentsKey(parentId) @redis.del commentKey id @redis.zrem childsKey, id innerDelete comments, id, false if comments end end def jsonKey id "comment:#{id}:json" end def commentKey id "comment:#{id}" end def commentsKey id "comments:#{id}" end def subCommentsKey id "comment:#{id}:sub" end end def printComments comments, tabs = 0 comments.each do |comment| tabs.times { putc "\t" } puts "#{comment['comment']}" if comment['comments'] printComments comment['comments'], tabs + 1 end end end def saveDummy cr, id tree = cr.save id, 'Tree' root = cr.save id, 'Root', tree trunk = cr.save id, 'Trunk', tree branch = cr.save id, 'Branch', trunk leaf = cr.save id, 'Leaf', branch top = cr.save id, 'Top', tree end command = ARGV[0] id = ARGV[1] cr = CommentsRepository.new case command when 's' saveDummy cr, id when 'p' printComments cr.get id when 'l' printComments [cr.leaf(id)] when 'd' cr.delete cr.get(id), id, id when 'r' cr.delete cr.leaf(ARGV[2]), ARGV[3], id, false when 'j' puts cr.get(id).to_json end -
Loupi revised this gist
May 22, 2012 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -27,7 +27,7 @@ def save itemId, comment, parentId = nil def get itemId parsedComments = @redis.get "item:#{itemId}:parsedComments" if !parsedComments data = multiFetch "item:#{itemId}:comments" parsedComments = processComments data @redis.set "item:#{itemId}:parsedComments", parsedComments.to_yaml -
Loupi revised this gist
May 22, 2012 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ #based on http://forrst.com/posts/Nested_Comments_system_using_Redis-Ror require 'ostruct' require 'redis' require 'securerandom' -
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,70 @@ require 'ostruct' require 'redis' require 'securerandom' require 'yaml' class CommentsRepository def initialize @redis = Redis.new end def save itemId, comment, parentId = nil @redis.del "item:#{itemId}:parsedComments" data = hashComment itemId, comment, parentId id = data[:id] if parentId == nil @redis.rpush "item:#{itemId}:comments", id else @redis.hset "comment:#{parentId}", 'hasChildrens', 1 @redis.rpush "thread:#{data[:parentId]}", id end @redis.hmset "comment:#{id}", data.map{|k,v| [k,v]}.flatten(1) id end def get itemId parsedComments = @redis.get "item:#{itemId}:parsedComments" if true#!parsedComments data = multiFetch "item:#{itemId}:comments" parsedComments = processComments data @redis.set "item:#{itemId}:parsedComments", parsedComments.to_yaml else parsedComments = YAML.load parsedComments end parsedComments end private def hashComment itemId, comment, parentId { id: SecureRandom.uuid, itemId: itemId, comment: comment, parentId: parentId == nil ? itemId : parentId, time: Time.now, hasChildrens: 0 } end def multiFetch keyName commentList = @redis.lrange keyName, 0, -1 @redis.multi do |multi| commentList.map { |commentId| multi.hgetall "comment:#{commentId}" } end end def processComments comments result = Hash.new comments.each do |data| data = OpenStruct.new data result[data.id] = data if data.hasChildrens == '1' childData = multiFetch "thread:#{data.id}" data.comments = processComments childData end end result end end