-
-
Save reddyonrails/e7decf3ca2104fb0062d8a8d69a39c23 to your computer and use it in GitHub Desktop.
Redis Nested Comments in Ruby
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 characters
| 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment