s/restaurants/suggestions/

This commit is contained in:
Aaron Lindsay 2016-12-24 10:00:21 -05:00
parent 4c7b9310c0
commit c4f07d3b3e
14 changed files with 237 additions and 215 deletions

View File

@ -5,11 +5,14 @@ import (
"log" "log"
"net/http" "net/http"
"strings" "strings"
"time"
) )
type Attendee struct { type Attendee struct {
AttendeeId int64 AttendeeId int64
UserId int64 `json:"-"`
Name string Name string
Date time.Time `json:"-"`
} }
type AttendeeList struct { type AttendeeList struct {
@ -37,10 +40,10 @@ func (aeu AttendeeExistsError) Error() string {
return "Attendee exists" return "Attendee exists"
} }
func GetAttendees() (*[]*Attendee, error) { func GetAttendees(userid int64, date time.Time) (*[]*Attendee, error) {
var attendees []*Attendee var attendees []*Attendee
_, err := DB.Select(&attendees, "SELECT * from attendees") _, err := DB.Select(&attendees, "SELECT * from attendees WHERE UserId=? AND Date=?", userid, date)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -79,12 +82,14 @@ func InsertAttendee(a *Attendee) error {
} }
func AttendeeHandler(w http.ResponseWriter, r *http.Request) { func AttendeeHandler(w http.ResponseWriter, r *http.Request) {
_, err := GetUserFromSession(r) user, err := GetUserFromSession(r)
if err != nil { if err != nil {
WriteError(w, 1 /*Not Signed In*/) WriteError(w, 1 /*Not Signed In*/)
return return
} }
today := time.Now().Truncate(time.Hour * 24)
if r.Method == "POST" { if r.Method == "POST" {
attendee_json := r.PostFormValue("attendee") attendee_json := r.PostFormValue("attendee")
if attendee_json == "" { if attendee_json == "" {
@ -99,6 +104,8 @@ func AttendeeHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
attendee.AttendeeId = -1 attendee.AttendeeId = -1
attendee.UserId = user.UserId
attendee.Date = today
err = InsertAttendee(&attendee) err = InsertAttendee(&attendee)
if err != nil { if err != nil {
@ -121,7 +128,7 @@ func AttendeeHandler(w http.ResponseWriter, r *http.Request) {
} else if r.Method == "GET" { } else if r.Method == "GET" {
var al AttendeeList var al AttendeeList
attendees, err := GetAttendees() attendees, err := GetAttendees(user.UserId, today)
if err != nil { if err != nil {
WriteError(w, 999 /*Internal Error*/) WriteError(w, 999 /*Internal Error*/)
log.Print(err) log.Print(err)

2
db.go
View File

@ -19,7 +19,7 @@ func initDB() *gorp.DbMap {
dbmap.AddTableWithName(User{}, "users").SetKeys(true, "UserId") dbmap.AddTableWithName(User{}, "users").SetKeys(true, "UserId")
dbmap.AddTableWithName(Session{}, "sessions").SetKeys(true, "SessionId") dbmap.AddTableWithName(Session{}, "sessions").SetKeys(true, "SessionId")
dbmap.AddTableWithName(Attendee{}, "attendees").SetKeys(true, "AttendeeId") dbmap.AddTableWithName(Attendee{}, "attendees").SetKeys(true, "AttendeeId")
dbmap.AddTableWithName(Restaurant{}, "restaurants").SetKeys(true, "RestaurantId") dbmap.AddTableWithName(Suggestion{}, "suggestions").SetKeys(true, "SuggestionId")
err = dbmap.CreateTablesIfNotExists() err = dbmap.CreateTablesIfNotExists()
if err != nil { if err != nil {

View File

@ -17,7 +17,7 @@ var error_codes = map[int]string{
3: "Invalid Request", 3: "Invalid Request",
4: "User Exists", 4: "User Exists",
5: "Attendee Exists", 5: "Attendee Exists",
6: "Restaurant Exists", 6: "Suggestion Exists",
// 5: "Connection Failed", //client-side error // 5: "Connection Failed", //client-side error
999: "Internal Error", 999: "Internal Error",
} }

View File

@ -1,40 +1,40 @@
var RestaurantConstants = require('../constants/RestaurantConstants'); var SuggestionConstants = require('../constants/SuggestionConstants');
var ErrorActions = require('./ErrorActions'); var ErrorActions = require('./ErrorActions');
var models = require('../models.js'); var models = require('../models.js');
var Restaurant = models.Restaurant; var Suggestion = models.Suggestion;
var Error = models.Error; var Error = models.Error;
function fetchRestaurants() { function fetchSuggestions() {
return { return {
type: RestaurantConstants.FETCH_RESTAURANTS type: SuggestionConstants.FETCH_SUGGESTIONS
} }
} }
function restaurantsFetched(restaurants) { function restaurantsFetched(restaurants) {
return { return {
type: RestaurantConstants.RESTAURANTS_FETCHED, type: SuggestionConstants.SUGGESTIONS_FETCHED,
restaurants: restaurants restaurants: restaurants
} }
} }
function createRestaurant() { function createSuggestion() {
return { return {
type: RestaurantConstants.CREATE_RESTAURANT type: SuggestionConstants.CREATE_SUGGESTION
} }
} }
function restaurantCreated(restaurant) { function restaurantCreated(restaurant) {
return { return {
type: RestaurantConstants.RESTAURANT_CREATED, type: SuggestionConstants.SUGGESTION_CREATED,
restaurant: restaurant restaurant: restaurant
} }
} }
function fetchAll() { function fetchAll() {
return function (dispatch) { return function (dispatch) {
dispatch(fetchRestaurants()); dispatch(fetchSuggestions());
$.ajax({ $.ajax({
type: "GET", type: "GET",
@ -47,7 +47,7 @@ function fetchAll() {
ErrorActions.serverError(e); ErrorActions.serverError(e);
} else { } else {
dispatch(restaurantsFetched(data.restaurants.map(function(json) { dispatch(restaurantsFetched(data.restaurants.map(function(json) {
var a = new Restaurant(); var a = new Suggestion();
a.fromJSON(json); a.fromJSON(json);
return a; return a;
}))); })));
@ -62,7 +62,7 @@ function fetchAll() {
function create(restaurant) { function create(restaurant) {
return function (dispatch) { return function (dispatch) {
dispatch(createRestaurant()); dispatch(createSuggestion());
$.ajax({ $.ajax({
type: "POST", type: "POST",
@ -75,7 +75,7 @@ function create(restaurant) {
if (e.isError()) { if (e.isError()) {
ErrorActions.serverError(e); ErrorActions.serverError(e);
} else { } else {
var a = new Restaurant(); var a = new Suggestion();
a.fromJSON(data); a.fromJSON(data);
dispatch(restaurantCreated(a)); dispatch(restaurantCreated(a));
} }

View File

@ -1,7 +1,7 @@
var UserConstants = require('../constants/UserConstants'); var UserConstants = require('../constants/UserConstants');
var AttendeeActions = require('./AttendeeActions'); var AttendeeActions = require('./AttendeeActions');
var RestaurantActions = require('./RestaurantActions'); var SuggestionActions = require('./SuggestionActions');
var ErrorActions = require('./ErrorActions'); var ErrorActions = require('./ErrorActions');
var models = require('../models.js'); var models = require('../models.js');
@ -92,7 +92,7 @@ function initializeSession(dispatch, session) {
dispatch(userLoggedIn(session)); dispatch(userLoggedIn(session));
dispatch(fetch(session.UserId)); dispatch(fetch(session.UserId));
dispatch(AttendeeActions.fetchAll()); dispatch(AttendeeActions.fetchAll());
dispatch(RestaurantActions.fetchAll()); dispatch(SuggestionActions.fetchAll());
} }
function login(user) { function login(user) {

View File

@ -1,8 +0,0 @@
var keyMirror = require('keymirror');
module.exports = keyMirror({
FETCH_RESTAURANTS: null,
RESTAURANTS_FETCHED: null,
CREATE_RESTAURANT: null,
RESTAURANT_CREATED: null
});

View File

@ -0,0 +1,8 @@
var keyMirror = require('keymirror');
module.exports = keyMirror({
FETCH_SUGGESTIONS: null,
SUGGESTIONS_FETCHED: null,
CREATE_SUGGESTION: null,
SUGGESTION_CREATED: null
});

View File

@ -101,31 +101,37 @@ Attendee.prototype.isAttendee = function() {
this.Name != empty_attendee.Name; this.Name != empty_attendee.Name;
} }
function Restaurant() { function Suggestion() {
this.RestaurantId = -1; this.SuggestionId = -1;
this.Name = ""; this.VetoingId = -1;
this.AttendeeId = -1;
this.RestaurantName = "";
} }
Restaurant.prototype.toJSON = function() { Suggestion.prototype.toJSON = function() {
var json_obj = {}; var json_obj = {};
json_obj.RestaurantId = this.RestaurantId; json_obj.SuggestionId = this.SuggestionId;
json_obj.Name = this.Name; json_obj.AttendeeId = this.AttendeeId;
json_obj.RestaurantName = this.RestaurantName;
return JSON.stringify(json_obj); return JSON.stringify(json_obj);
} }
Restaurant.prototype.fromJSON = function(json_input) { Suggestion.prototype.fromJSON = function(json_input) {
var json_obj = getJSONObj(json_input); var json_obj = getJSONObj(json_input);
if (json_obj.hasOwnProperty("RestaurantId")) if (json_obj.hasOwnProperty("SuggestionId"))
this.RestaurantId = json_obj.RestaurantId; this.SuggestionId = json_obj.SuggestionId;
if (json_obj.hasOwnProperty("Name")) if (json_obj.hasOwnProperty("AttendeeId"))
this.Name = json_obj.Name; this.AttendeeId = json_obj.AttendeeId;
if (json_obj.hasOwnProperty("RestaurantName"))
this.RestaurantName = json_obj.RestaurantName;
} }
Restaurant.prototype.isRestaurant = function() { Suggestion.prototype.isSuggestion = function() {
var empty_attendee = new Restaurant(); var empty_suggestion = new Suggestion();
return this.RestaurantId != empty_attendee.RestaurantId || return this.SuggestionId != empty_suggestion.SuggestionId &&
this.Name != empty_attendee.Name; this.AttendeeId != empty_suggestion.AttendeeId &&
this.RestaurantName != empty_suggestion.RestaurantName;
} }
function Error() { function Error() {

View File

@ -3,13 +3,13 @@ var Redux = require('redux');
var UserReducer = require('./UserReducer'); var UserReducer = require('./UserReducer');
var SessionReducer = require('./SessionReducer'); var SessionReducer = require('./SessionReducer');
var AttendeeReducer = require('./AttendeeReducer'); var AttendeeReducer = require('./AttendeeReducer');
var RestaurantReducer = require('./RestaurantReducer'); var SuggestionReducer = require('./SuggestionReducer');
var ErrorReducer = require('./ErrorReducer'); var ErrorReducer = require('./ErrorReducer');
module.exports = Redux.combineReducers({ module.exports = Redux.combineReducers({
user: UserReducer, user: UserReducer,
session: SessionReducer, session: SessionReducer,
attendees: AttendeeReducer, attendees: AttendeeReducer,
restaurants: RestaurantReducer, suggestions: SuggestionReducer,
error: ErrorReducer error: ErrorReducer
}); });

View File

@ -1,26 +0,0 @@
var assign = require('object-assign');
var RestaurantConstants = require('../constants/RestaurantConstants');
var UserConstants = require('../constants/UserConstants');
module.exports = function(state = {}, action) {
switch (action.type) {
case RestaurantConstants.RESTAURANTS_FETCHED:
var restaurants = {};
for (var i = 0; i < action.restaurants.length; i++) {
var restaurant = action.restaurants[i];
restaurants[restaurant.RestaurantId] = restaurant;
}
return restaurants;
case RestaurantConstants.RESTAURANT_CREATED:
var restaurant = action.restaurant;
var restaurants = assign({}, state, {
[restaurant.RestaurantId]: restaurant
});
return restaurants;
case UserConstants.USER_LOGGEDOUT:
return {};
default:
return state;
}
};

View File

@ -0,0 +1,26 @@
var assign = require('object-assign');
var SuggestionConstants = require('../constants/SuggestionConstants');
var UserConstants = require('../constants/UserConstants');
module.exports = function(state = {}, action) {
switch (action.type) {
case SuggestionConstants.SUGGESTIONS_FETCHED:
var suggestions = {};
for (var i = 0; i < action.suggestions.length; i++) {
var suggestion = action.suggestions[i];
suggestions[suggestion.SuggestionId] = suggestion;
}
return suggestions;
case SuggestionConstants.SUGGESTION_CREATED:
var suggestion = action.suggestion;
var suggestions = assign({}, state, {
[suggestion.SuggestionId]: suggestion
});
return suggestions;
case UserConstants.USER_LOGGEDOUT:
return {};
default:
return state;
}
};

View File

@ -70,7 +70,7 @@ func main() {
servemux.HandleFunc("/session/", SessionHandler) servemux.HandleFunc("/session/", SessionHandler)
servemux.HandleFunc("/user/", UserHandler) servemux.HandleFunc("/user/", UserHandler)
servemux.HandleFunc("/attendee/", AttendeeHandler) servemux.HandleFunc("/attendee/", AttendeeHandler)
servemux.HandleFunc("/restaurant/", RestaurantHandler) servemux.HandleFunc("/suggestion/", SuggestionHandler)
listener, err := net.Listen("tcp", ":"+strconv.Itoa(port)) listener, err := net.Listen("tcp", ":"+strconv.Itoa(port))
if err != nil { if err != nil {

View File

@ -1,143 +0,0 @@
package main
import (
"encoding/json"
"log"
"net/http"
"strings"
)
type Restaurant struct {
RestaurantId int64
Name string
}
type RestaurantList struct {
Restaurants *[]*Restaurant `json:"restaurants"`
}
func (r *Restaurant) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w)
return enc.Encode(r)
}
func (r *Restaurant) Read(json_str string) error {
dec := json.NewDecoder(strings.NewReader(json_str))
return dec.Decode(r)
}
func (rl *RestaurantList) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w)
return enc.Encode(rl)
}
type RestaurantExistsError struct{}
func (aeu RestaurantExistsError) Error() string {
return "Restaurant exists"
}
func GetRestaurants() (*[]*Restaurant, error) {
var restaurants []*Restaurant
_, err := DB.Select(&restaurants, "SELECT * from restaurants")
if err != nil {
return nil, err
}
return &restaurants, nil
}
func InsertRestaurant(r *Restaurant) error {
transaction, err := DB.Begin()
if err != nil {
return err
}
existing, err := transaction.SelectInt("SELECT count(*) from users where Name=?", r.Name)
if err != nil {
transaction.Rollback()
return err
}
if existing > 0 {
transaction.Rollback()
return RestaurantExistsError{}
}
err = transaction.Insert(r)
if err != nil {
transaction.Rollback()
return err
}
err = transaction.Commit()
if err != nil {
transaction.Rollback()
return err
}
return nil
}
func RestaurantHandler(w http.ResponseWriter, r *http.Request) {
_, err := GetUserFromSession(r)
if err != nil {
WriteError(w, 1 /*Not Signed In*/)
return
}
if r.Method == "POST" {
restaurant_json := r.PostFormValue("restaurant")
if restaurant_json == "" {
WriteError(w, 3 /*Invalid Request*/)
return
}
var restaurant Restaurant
err := restaurant.Read(restaurant_json)
if err != nil {
WriteError(w, 3 /*Invalid Request*/)
return
}
restaurant.RestaurantId = -1
err = InsertRestaurant(&restaurant)
if err != nil {
if _, ok := err.(RestaurantExistsError); ok {
WriteError(w, 6 /*Restaurant Exists*/)
} else {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
}
return
}
w.WriteHeader(201 /*Created*/)
err = restaurant.Write(w)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
} else if r.Method == "GET" {
var rl RestaurantList
restaurants, err := GetRestaurants()
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
rl.Restaurants = restaurants
err = (&rl).Write(w)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
} else {
/* No PUT or DELETE */
WriteError(w, 3 /*Invalid Request*/)
return
}
}

152
suggestions.go Normal file
View File

@ -0,0 +1,152 @@
package main
import (
"encoding/json"
"log"
"net/http"
"strings"
"time"
)
type Suggestion struct {
SuggestionId int64
VetoingId int64 // -1 for initial suggestion
AttendeeId int64
UserId int64 `json:"-"`
RestaurantName string
Date time.Time `json:"-"`
}
type SuggestionList struct {
Suggestions *[]*Suggestion `json:"suggestions"`
}
func (s *Suggestion) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w)
return enc.Encode(s)
}
func (s *Suggestion) Read(json_str string) error {
dec := json.NewDecoder(strings.NewReader(json_str))
return dec.Decode(s)
}
func (sl *SuggestionList) Write(w http.ResponseWriter) error {
enc := json.NewEncoder(w)
return enc.Encode(sl)
}
type SuggestionExistsError struct{}
func (aeu SuggestionExistsError) Error() string {
return "Suggestion exists"
}
func GetSuggestions(userid int64, date time.Time) (*[]*Suggestion, error) {
var suggestions []*Suggestion
_, err := DB.Select(&suggestions, "SELECT * from suggestions WHERE UserId=? AND Date=?", userid, date)
if err != nil {
return nil, err
}
return &suggestions, nil
}
func InsertSuggestion(s *Suggestion) error {
transaction, err := DB.Begin()
if err != nil {
return err
}
existing, err := transaction.SelectInt("SELECT count(*) from suggestions where RestaurantName=? AND UserId=? AND Date=?", s.RestaurantName, s.UserId, s.Date)
if err != nil {
transaction.Rollback()
return err
}
if existing > 0 {
transaction.Rollback()
return SuggestionExistsError{}
}
err = transaction.Insert(s)
if err != nil {
transaction.Rollback()
return err
}
err = transaction.Commit()
if err != nil {
transaction.Rollback()
return err
}
return nil
}
func SuggestionHandler(w http.ResponseWriter, r *http.Request) {
user, err := GetUserFromSession(r)
if err != nil {
WriteError(w, 1 /*Not Signed In*/)
return
}
today := time.Now().Truncate(time.Hour * 24)
if r.Method == "POST" {
suggestion_json := r.PostFormValue("suggestion")
if suggestion_json == "" {
WriteError(w, 3 /*Invalid Request*/)
return
}
var suggestion Suggestion
err := suggestion.Read(suggestion_json)
if err != nil {
WriteError(w, 3 /*Invalid Request*/)
return
}
suggestion.SuggestionId = -1
suggestion.UserId = user.UserId
suggestion.Date = today
err = InsertSuggestion(&suggestion)
if err != nil {
if _, ok := err.(SuggestionExistsError); ok {
WriteError(w, 6 /*Suggestion Exists*/)
} else {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
}
return
}
w.WriteHeader(201 /*Created*/)
err = suggestion.Write(w)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
} else if r.Method == "GET" {
var sl SuggestionList
suggestions, err := GetSuggestions(user.UserId, today)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
sl.Suggestions = suggestions
err = (&sl).Write(w)
if err != nil {
WriteError(w, 999 /*Internal Error*/)
log.Print(err)
return
}
} else {
/* No PUT or DELETE */
WriteError(w, 3 /*Invalid Request*/)
return
}
}