Reddit voting consists of up voting  and down voting. These votes decide rank of the post, which ultimately decides the position of the story link. Here in this article, we are going to see simple architecture and database structure to implement reddit voting system. 

Note 

It is really big project. Its difficult to explain every code snippet here. So please download the project

Database

Lets build database first. Click here to read complete explanation on reddit database. Execute below SQL commands on your MySQL console

CREATE schema demos;

CREATE TABLE reddit_post
(parent_id BIGINT(20) NOT NULL,post_id BIGINT(20) AUTO_INCREMENT,
  title varchar(200) NOT NULL,
  content varchar(2000) NOT NULL,
  link varchar(2083) NOT NULL,
  user_id varchar(25) NOT NULL,
  pic varchar(2083),
  status varchar(15) NOT NULL,
  type varchar(15) NOT NULL,
  votes INTEGER,
  created_time TIMESTAMP default CURRENT_TIMESTAMP,
  primary key(post_id)
);


CREATE TABLE reddit_votes
(
  post_id BIGINT(20) NOT NULL,
  user_id VARCHAR(25) NOT NULL,
  vflag SMALLINT NOT NULL,
  last_updated_time TIMESTAMP default CURRENT_TIMESTAMP,
  primary key(post_id,user_id),
  foreign key(post_id) references reddit_post(post_id)
);

CREATE TABLE reddit_user
(
  user_id VARCHAR(25),
  property VARCHAR(25) NOT NULL,
  value varchar(200) NOT NULL,
  last_updated_time TIMESTAMP default CURRENT_TIMESTAMP,
  primary key(user_id,property,value)
);

CREATE TABLE reddit_ranks
(
  post_id BIGINT(20) NOT NULL,
  hot double,
  new double,
  raising double,
  controversial double,
  top double,
  foreign key(post_id) references reddit_post(post_id)
);

CREATE TABLE reddit_rights
(
  post_id BIGINT(20) NOT NULL,
  property VARCHAR(25),
  user_id VARCHAR(25),
  assigned_user_id VARCHAR(25),
  foreign key(post_id) references reddit_post(post_id),
  foreign key(user_id) references reddit_user(user_id),
  foreign key(assigned_user_id) references reddit_user(user_id)
);

INSERT INTO reddit_user(user_id, property, value) values('admin','name', 'admin');
INSERT INTO reddit_user(user_id, property, value) values('srinivas','name', 'srinivas dasari');
INSERT INTO reddit_user(user_id, property, value) values('ramesh','name', 'ramesh');

INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(0,'java','sub reddit for java developers','/r/java','admin','java_subreddit.png', 'active', 'subreddit', 0);
INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(0,'angularjs','sub reddit for AngularJS developers','/r/angularjs','admin','angularjs_subreddit.png', 'active', 'subreddit', 0);
INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(0,'sql','sub reddit for sql developers','/r/sql','admin','sql_subreddit.png', 'active', 'subreddit', 0);

INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(1,'Java Restful Webservice Tutorial with Sample case study','','http://blog.sodhanalibrary.com/2013/09/restful-web-service-tutorial-with-java.html','srinivas','http://4.bp.blogspot.com/-IWnld2WXOCg/UinxJK9ahMI/AAAAAAAAAAw/b8mFC6bl41w/s1600/screen2.bmp', 'active', 'post', 1);
INSERT INTO reddit_votes(post_id, user_id, vflag) VALUES(LAST_INSERT_ID(),'srinivas',1);

INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(2,'Responsive Web Design Using AngularJS Material UI','','http://blog.sodhanalibrary.com/2015/08/responsive-web-design-using-angularjs.html','srinivas','',  'active', 'post', 1);
INSERT INTO reddit_votes(post_id, user_id, vflag) VALUES(LAST_INSERT_ID(),'srinivas',1);

INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(2,'Responsive Web Design Using AngularJS Material UI','','http://blog.sodhanalibrary.com/2015/08/responsive-web-design-using-angularjs.html','srinivas','',  'active', 'post', 1);
INSERT INTO reddit_votes(post_id, user_id, vflag) VALUES(LAST_INSERT_ID(),'srinivas',1);

INSERT INTO reddit_post(parent_id, title, content, link, user_id, pic, status, type, votes) VALUES(4,'','good one','/r/java/4/comments','ramesh','','active', 'comment', 1);
INSERT INTO reddit_votes(post_id, user_id, vflag) VALUES(LAST_INSERT_ID(),'srinivas',1);

Program Flow

Here we will see what are basic rules to implement this functionality
(In the given demo, the default user id is "admin", No authentication required)

Load posts

Send request from jQuery to server, Server will send details by digging database. Find below for database queries

Select only post data from reddit_posts
select * from reddit_post where TYPE = 'post'
Select user vote for post
select * from reddit_votes where POST_ID = ? and USER_ID = ?
Now display the given data to user using jQuery

User Voting

Whenever user clicks on up arrow or down arrow, That user vote either is to be inserted or updated in reddit_votes. Total votes in reddit_posts has to be updated

Query for inserting vote into reddit_votes
insert into reddit_votes (POST_ID,USER_ID,VFLAG) values (?,?,?)
Query for updating vote in reddit_votes
update reddit_votes set VFLAG=?,LAST_UPDATED_TIME=CURRENT_TIMESTAMP where POST_ID=? and USER_ID=?
Query for deleting vote ( User can withdraw his vote )
delete from reddit_votes where POST_ID = ? and USER_ID = ?
Query for updating total votes
update reddit_post set VOTES = (select sum(vflag) from reddit_votes where POST_ID = ?) where POST_ID = ?

jQuery Code

Find below for jQuery code, It will handle up voting and down voting. 
$.get( "GetRedditPosts", function( rdata ) {
    var jsondata = JSON.parse(rdata);
    var html = '';
    if(jsondata.result_code == -1) {
        alert(jsondata.error_message);
        return;
    }
    var data = jsondata.data;
    // display this data as html
    

        // click event action for up arrow button
    $(".upArrow, .upArrowActive").on('click', function(){
        // update the post with new votes count
    });
    
    $(".downArrow, .downArrowActive").on('click', function(){
                // update the post with new votes count               
    });
});

Java Code

There are 2 main servlet classes, VotePost and GetRedditPosts
GetRedditPosts servlet is for loading posts
@WebServlet("/GetRedditPosts")
public class GetRedditPosts extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Result result = new Result();
        try { 
            // select posts from database
            ArrayList<RedditPost> posts = RedditPostDAO.selectRedditPost("admin");
            result.setData(posts);
        } catch (DBException e) {
            result.setResult_code(-1);
            result.setError_msg("Database error");
        }  catch (Exception e) {
            result.setResult_code(-1);
            result.setError_msg(e.getMessage());
        }
        PrintWriter pw = response.getWriter();
        pw.write(CodeUtils.toJson(result));
        pw.flush();
    }
}
VotePost servlet is for insert, update, delete user vote 
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Result result = new Result();
    try {
        RedditVotes rv = new RedditVotes();
        
        // id of the post
        rv.setPOST_ID(Integer.parseInt(request.getParameter("post_id")));
        
        // this is user vote (+1 is for up vote and -1 is for down vote) 
        rv.setVFLAG(Integer.parseInt(request.getParameter("vflag")));
        
        // this decides whether user want to withdraw his vote, 0 is for updating or inserting, other than 0 is for deleting vote
        rv.setREMOVE_FLAG(Integer.parseInt(request.getParameter("rflag")));
        
        // defaul userid for test
        rv.setUSER_ID("admin");
        
        if(rv.getREMOVE_FLAG() == 0) {
            // insert or update user vote
            RedditVotesDAO.insertRow(rv);
        } else {
            // delete user vote
            RedditVotesDAO.deleteRow(rv);
        }
        result.setData(RedditPostDAO.selectRedditPost(rv.getPOST_ID(),rv.getUSER_ID()));
    } catch (DBException e) {
        result.setResult_code(-1);
        result.setError_msg("Database error");
    }  catch (Exception e) {
        result.setResult_code(-1);
        result.setError_msg(e.getMessage());
    }
    PrintWriter pw = response.getWriter();
    pw.write(CodeUtils.toJson(result));
    pw.flush();
}

0 comments:

Blogroll

Follow this blog by Email

Popular Posts