processMsg conn client (CreateRoom (lat, lng)) = do
  let q0 = "select rooms.room_id, rooms.lat, rooms.lng, \
      \ST_Distance(ST_Transform(ST_GeomFromText('POINT(' || ? || ' ' || ? || ')', 4326), 2163 ), rooms.geom) dist \
      \from rooms where \
      \ST_Distance(ST_Transform(ST_GeomFromText('POINT(' || ? || ' ' || ? || ')', 4326), 2163 ), rooms.geom) < 700 \
      \and room_id in (select room_id from rooms inner join clients using(room_id) group by room_id) \
      \order by dist asc"
  xs :: [(Int, Double, Double, Double)] <- query conn q0 (lng, lat, lng, lat)
  case xs of
    ((rid,lat,lng,dist):_) -> do
      -- putStrLn $ "Instead of creating, nearby room " ++ (show dist) ++ " meters close, rid "  ++ (show rid) 
      processMsg conn client (JoinRoom rid)
    otherwise -> do
      -- putStrLn $ "Creating new room at " ++ (show lat) ++ ", " ++ (show lng)
      let q = "insert into rooms (lat, lng) values (?, ?) returning room_id"
      ((Only rid):_) :: [Only Int] <- query conn q (lat, lng)
      processMsg conn client (JoinRoom rid)
processMsg conn client (CreateRoom (lat, lng)) = do
  let q0 = "select rooms.room_id, rooms.lat, rooms.lng, \
      \ST_Distance(ST_Transform(ST_GeomFromText('POINT(' || ? || ' ' || ? || ')', 4326), 2163 ), rooms.geom) dist \
      \from rooms where \
      \ST_Distance(ST_Transform(ST_GeomFromText('POINT(' || ? || ' ' || ? || ')', 4326), 2163 ), rooms.geom) < 700 \
      \and room_id in (select room_id from rooms inner join clients using(room_id) group by room_id) \
      \order by dist asc"
  xs :: [(Int, Double, Double, Double)] <- query conn q0 (lng, lat, lng, lat)
  case xs of
    ((rid,lat,lng,dist):_) -> do
      -- putStrLn $ "Instead of creating, nearby room " ++ (show dist) ++ " meters close, rid "  ++ (show rid) 
      processMsg conn client (JoinRoom rid)
    otherwise -> do
      -- putStrLn $ "Creating new room at " ++ (show lat) ++ ", " ++ (show lng)
      let q = "insert into rooms (lat, lng) values (?, ?) returning room_id"
      ((Only rid):_) :: [Only Int] <- query conn q (lat, lng)
      processMsg conn client (JoinRoom rid)
processMsg conn client (CreateRoom (lat, lng)) = do
  let q0 = "select rooms.room_id, rooms.lat, rooms.lng, \
      \ST_Distance(ST_Transform(ST_GeomFromText('POINT(' || ? || ' ' || ? || ')', 4326), 2163 ), rooms.geom) dist \
      \from rooms where \
      \ST_Distance(ST_Transform(ST_GeomFromText('POINT(' || ? || ' ' || ? || ')', 4326), 2163 ), rooms.geom) < 700 \
      \and room_id in (select room_id from rooms inner join clients using(room_id) group by room_id) \
      \order by dist asc"
  xs :: [(Int, Double, Double, Double)] <- query conn q0 (lng, lat, lng, lat)
  case xs of
    ((rid,lat,lng,dist):_) -> do
      -- putStrLn $ "Instead of creating, nearby room " ++ (show dist) ++ " meters close, rid "  ++ (show rid) 
      processMsg conn client (JoinRoom rid)
    otherwise -> do
      -- putStrLn $ "Creating new room at " ++ (show lat) ++ ", " ++ (show lng)
      let q = "insert into rooms (lat, lng) values (?, ?) returning room_id"
      ((Only rid):_) :: [Only Int] <- query conn q (lat, lng)
      processMsg conn client (JoinRoom rid)