Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
Rename the memberships table to takes; #2282
Browse files Browse the repository at this point in the history
`memberships` was a bad name for this table because it's ambiguous with
community memberships. Renaming to `takes` fits the usage we've arrived
at and is parallel to `tips`. Tips and takes! Membership is then an
emergent property of data recorded in the takes table.
  • Loading branch information
chadwhitacre authored and seanlinsley committed Apr 17, 2014
1 parent a0d4cce commit bf08077
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 40 deletions.
50 changes: 50 additions & 0 deletions branch.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-------------------------------------------------------------------------------
-- https://github.com/gittip/www.gittip.com/issues/2282

BEGIN;


-- takes table
ALTER TABLE memberships RENAME TO takes;
ALTER TABLE takes RENAME COLUMN take TO amount;

ALTER TABLE takes DROP CONSTRAINT "memberships_pkey";
ALTER TABLE takes ADD CONSTRAINT "takes_pkey"
PRIMARY KEY (id);

ALTER TABLE takes DROP constraint "memberships_member_fkey";
ALTER TABLE takes ADD constraint "takes_member_fkey"
FOREIGN KEY (member) REFERENCES participants(username)
ON UPDATE CASCADE ON DELETE RESTRICT;

ALTER TABLE takes DROP constraint "memberships_team_fkey";
ALTER TABLE takes ADD constraint "takes_team_fkey"
FOREIGN KEY (team) REFERENCES participants(username)
ON UPDATE CASCADE ON DELETE RESTRICT;

ALTER TABLE takes DROP constraint "memberships_recorder_fkey";
ALTER TABLE takes ADD constraint "takes_recorder_fkey"
FOREIGN KEY (recorder) REFERENCES participants(username)
ON UPDATE CASCADE ON DELETE RESTRICT;

ALTER SEQUENCE memberships_id_seq RENAME TO takes_id_seq;


-- current_takes view
DROP VIEW current_memberships;
CREATE VIEW current_takes AS
SELECT * FROM (

SELECT DISTINCT ON (member, team) m.*
FROM takes m
JOIN participants p1 ON p1.username = member
JOIN participants p2 ON p2.username = team
WHERE p1.is_suspicious IS NOT TRUE
AND p2.is_suspicious IS NOT TRUE
ORDER BY member
, team
, mtime DESC

) AS anon WHERE amount > 0;

END;
11 changes: 5 additions & 6 deletions gittip/billing/payday.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,23 +246,22 @@ def pachinko(self, ts_start, participants):
, available
))

def tip(member, amount):
def tip(tippee, amount):
tip = {}
tip['tipper'] = participant.username
tip['tippee'] = member['username']
tip['tippee'] = tippee
tip['amount'] = amount
tip['claimed_time'] = ts_start
self.tip( participant
, tip
, ts_start
, pachinko=True
)
return tip['amount']

for member in participant.get_members():
amount = min(member['take'], available)
for take in participant.get_current_takes():
amount = min(take['amount'], available)
available -= amount
tip(member, amount)
tip(take['member'], amount)
if available == 0:
break

Expand Down
61 changes: 36 additions & 25 deletions gittip/models/_mixin_team.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def show_as_team(self, user):
return False
if user.ADMIN:
return True
if not self.get_members():
if not self.get_current_takes():
if self == user.participant:
return True
return False
Expand All @@ -37,7 +37,7 @@ def add_member(self, member):
"""Add a member to this team.
"""
assert self.IS_PLURAL
if len(self.get_members()) == 149:
if len(self.get_current_takes()) == 149:
raise MemberLimitReached
self.__set_take_for(member, Decimal('0.01'), self)

Expand All @@ -51,8 +51,8 @@ def member_of(self, team):
"""Given a Participant object, return a boolean.
"""
assert team.IS_PLURAL
for member in team.get_members():
if member['username'] == self.username:
for take in team.get_current_takes():
if take['member'] == self.username:
return True
return False

Expand All @@ -77,7 +77,7 @@ def get_take_for(self, member):
"""Return a Decimal representation of the take for this member, or 0.
"""
assert self.IS_PLURAL
return self.db.one( "SELECT take FROM current_memberships "
return self.db.one( "SELECT amount FROM current_takes "
"WHERE member=%s AND team=%s"
, (member.username, self.username)
, default=Decimal('0.00')
Expand Down Expand Up @@ -110,14 +110,14 @@ def set_take_for(self, member, take, recorder):
self.__set_take_for(member, take, recorder)
return take

def __set_take_for(self, member, take, recorder):
def __set_take_for(self, member, amount, recorder):
assert self.IS_PLURAL
# XXX Factored out for testing purposes only! :O Use .set_take_for.
self.db.run("""
INSERT INTO memberships (ctime, member, team, take, recorder)
INSERT INTO takes (ctime, member, team, amount, recorder)
VALUES ( COALESCE (( SELECT ctime
FROM memberships
FROM takes
WHERE member=%s
AND team=%s
LIMIT 1
Expand All @@ -129,52 +129,63 @@ def __set_take_for(self, member, take, recorder):
)
""", (member.username, self.username, member.username, self.username, \
take, recorder.username))
amount, recorder.username))

def get_members(self):
def get_current_takes(self):
"""Return a list of member takes for a team.
"""
assert self.IS_PLURAL
return self.db.all("""
SELECT member AS username, take, ctime, mtime
FROM current_memberships
SELECT member, amount, ctime, mtime
FROM current_takes
WHERE team=%s
ORDER BY ctime DESC
""", (self.username,), back_as=dict)

def get_teams_membership(self):
def get_team_take(self):
"""Return a single take for a team, the team itself's take.
"""
assert self.IS_PLURAL
TAKE = "SELECT sum(take) FROM current_memberships WHERE team=%s"
TAKE = "SELECT sum(amount) FROM current_takes WHERE team=%s"
total_take = self.db.one(TAKE, (self.username,), default=0)
team_take = max(self.get_dollars_receiving() - total_take, 0)
membership = { "ctime": None
, "mtime": None
, "username": self.username
, "take": team_take
, "member": self.username
, "amount": team_take
}
return membership

def get_memberships(self, current_participant):
def get_members(self, current_participant):
"""Return a list of member dicts.
"""
assert self.IS_PLURAL
members = self.get_members()
members.append(self.get_teams_membership())
takes = self.get_current_takes()
takes.append(self.get_team_take())
budget = balance = self.get_dollars_receiving()
for member in members:
members = []
for take in takes:
member = {}
member['username'] = take['member']
member['take'] = take['amount']

member['removal_allowed'] = current_participant == self
member['editing_allowed'] = False
member['is_current_user'] = False
if current_participant is not None:
if member['username'] == current_participant.username:
member['is_current_user'] = True
if member['ctime'] is not None:
if take['ctime'] is not None:
# current user, but not the team itself
member['editing_allowed']= True
take = member['take']
member['take'] = take
member['last_week'] = last_week = \
self.get_take_last_week_for(member)

member['last_week'] = last_week = self.get_take_last_week_for(member)
member['max_this_week'] = self.compute_max_this_week(last_week)
amount = min(take, balance)
balance -= amount
member['balance'] = balance
member['percentage'] = (amount / budget) if budget > 0 else 0
members.append(member)
return members
4 changes: 2 additions & 2 deletions gittip/models/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ def get_teams(self):
SELECT team AS name
, ( SELECT count(*)
FROM current_memberships
FROM current_takes
WHERE team=x.team
) AS nmembers
FROM current_memberships x
FROM current_takes x
WHERE member=%s;
""", (self.username,))
Expand Down
1 change: 1 addition & 0 deletions tests/py/test_membername_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def test_get_team_when_team_equals_member(self):
data = json.loads(response.body)
assert response.code == 200
assert data['username'] == 'team'
assert data['take'] == '0.00'

def test_get_team_member_returns_null_when_non_member(self):
response = self.client.GET('/team/members/alice.json', auth_as='team')
Expand Down
12 changes: 7 additions & 5 deletions www/%username/members/%membername.json.spt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Endpoint to record identifications
"""Endpoint to record team memberships.
"""
from decimal import Decimal, InvalidOperation

Expand Down Expand Up @@ -65,14 +65,16 @@ if POST:

if proceed:
team.set_take_for(member, take, user.participant)
out = team.get_memberships(user.participant)
out = team.get_members(user.participant)

else:
if member == team:
out = team.get_teams_membership()
out = team.get_team_take()
out['username'] = out.pop('member')
out['take'] = unicode(out.pop('amount'))
else:
SQL = "SELECT ctime, mtime, member AS username, take::text " \
"FROM current_memberships WHERE team=%s AND member=%s"
SQL = "SELECT ctime, mtime, member AS username, amount::text as take " \
"FROM current_takes WHERE team=%s AND member=%s"
out = website.db.one(SQL, (team.username, member.username))

response.body = out
4 changes: 2 additions & 2 deletions www/%username/members/index.json.spt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Endpoint to record identifications
"""Endpoint to list team members.
"""
from aspen import Response
from gittip.utils import get_participant
Expand All @@ -10,4 +10,4 @@ team = get_participant(request, restrict=False)
if not team.show_as_team(user):
raise Response(404)

response.body = team.get_memberships(user.participant)
response.body = team.get_members(user.participant)

0 comments on commit bf08077

Please sign in to comment.