| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | |
|---|
| 3 | from datetime import datetime |
|---|
| 4 | |
|---|
| 5 | from trac.db import Table, Column, Index |
|---|
| 6 | from trac.util import to_list |
|---|
| 7 | from trac.util.datefmt import from_utimestamp, to_utimestamp, utc |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | SCHEMA = [ |
|---|
| 11 | Table('pullrequests', key='id')[ |
|---|
| 12 | Column('id', auto_increment=True), |
|---|
| 13 | Column('status'), |
|---|
| 14 | Column('author'), |
|---|
| 15 | Column('reviewers'), |
|---|
| 16 | Column('opened', type='int64'), |
|---|
| 17 | Column('modified', type='int64'), |
|---|
| 18 | Column('ticket', type='int'), |
|---|
| 19 | Column('comment', type='int'), |
|---|
| 20 | Column('wikilink'), |
|---|
| 21 | Index(['status']), |
|---|
| 22 | Index(['author']), |
|---|
| 23 | ], |
|---|
| 24 | ] |
|---|
| 25 | |
|---|
| 26 | |
|---|
| 27 | class PullRequest(object): |
|---|
| 28 | |
|---|
| 29 | def __init__(self, id, status, author, reviewers, opened, modified, ticket, comment, wikilink): |
|---|
| 30 | self.id = id |
|---|
| 31 | self.status = status |
|---|
| 32 | self.author = author |
|---|
| 33 | self.reviewers = reviewers |
|---|
| 34 | self.opened = opened |
|---|
| 35 | self.modified = modified |
|---|
| 36 | self.ticket = ticket |
|---|
| 37 | self.comment = comment |
|---|
| 38 | self.wikilink = wikilink |
|---|
| 39 | |
|---|
| 40 | def add_reviewer(self, reviewer): |
|---|
| 41 | if reviewer != self.author: |
|---|
| 42 | rset = set(to_list(self.reviewers)) |
|---|
| 43 | rset.add(reviewer) |
|---|
| 44 | self.reviewers = ','.join(rset) |
|---|
| 45 | |
|---|
| 46 | @classmethod |
|---|
| 47 | def add(cls, env, pr): |
|---|
| 48 | with env.db_transaction as db: |
|---|
| 49 | cursor = db.cursor() |
|---|
| 50 | cursor.execute(""" |
|---|
| 51 | INSERT INTO pullrequests |
|---|
| 52 | (status, author, reviewers, opened, modified, ticket, comment, wikilink) |
|---|
| 53 | VALUES (%s, %s, %s, %s, %s, %s, %s, %s) |
|---|
| 54 | """, (pr.status, pr.author, pr.reviewers, to_utimestamp(pr.opened), to_utimestamp(pr.modified), pr.ticket, pr.comment, pr.wikilink)) |
|---|
| 55 | pr.id = db.get_last_id(cursor, 'pullrequests') |
|---|
| 56 | |
|---|
| 57 | @classmethod |
|---|
| 58 | def delete_by_ids(cls, env, ids): |
|---|
| 59 | ids_sql = ','.join(["'%s'" % id for id in ids]) |
|---|
| 60 | with env.db_transaction as db: |
|---|
| 61 | db(""" |
|---|
| 62 | DELETE FROM pullrequests |
|---|
| 63 | WHERE id in (%s) |
|---|
| 64 | """ % ids_sql) |
|---|
| 65 | |
|---|
| 66 | @classmethod |
|---|
| 67 | def update_status_and_reviewers(cls, env, pr): |
|---|
| 68 | with env.db_transaction as db: |
|---|
| 69 | cursor = db.cursor() |
|---|
| 70 | cursor.execute(""" |
|---|
| 71 | UPDATE pullrequests |
|---|
| 72 | SET status=%s, reviewers=%s, modified=%s |
|---|
| 73 | WHERE id=%s |
|---|
| 74 | """, (pr.status, pr.reviewers, to_utimestamp(datetime.now(utc)), pr.id)) |
|---|
| 75 | |
|---|
| 76 | @classmethod |
|---|
| 77 | def select_by_id(cls, env, id): |
|---|
| 78 | rows = env.db_query(""" |
|---|
| 79 | SELECT status, author, reviewers, opened, modified, ticket, comment, wikilink |
|---|
| 80 | FROM pullrequests |
|---|
| 81 | WHERE id=%s |
|---|
| 82 | """, (id,)) |
|---|
| 83 | if not rows: |
|---|
| 84 | return None |
|---|
| 85 | status, author, reviewers, opened, modified, ticket, comment, wikilink = rows[0] |
|---|
| 86 | return PullRequest(id, status, author, reviewers, from_utimestamp(opened), from_utimestamp(modified), ticket, comment, wikilink) |
|---|
| 87 | |
|---|
| 88 | @classmethod |
|---|
| 89 | def select(cls, env, **kwargs): |
|---|
| 90 | with env.db_query as db: |
|---|
| 91 | conditions = [] |
|---|
| 92 | args = [] |
|---|
| 93 | for name, value in sorted(kwargs.iteritems()): |
|---|
| 94 | if value: |
|---|
| 95 | op = '=' |
|---|
| 96 | if value.startswith('!'): |
|---|
| 97 | op = '!=' |
|---|
| 98 | value = value[1:] |
|---|
| 99 | conditions.append(db.quote(name) + op + '%s') |
|---|
| 100 | args.append(value) |
|---|
| 101 | query = 'SELECT id, status, author, reviewers, opened, modified, ticket, comment, wikilink FROM pullrequests' |
|---|
| 102 | if conditions: |
|---|
| 103 | query += ' WHERE ' + ' AND '.join(conditions) |
|---|
| 104 | query += ' ORDER BY id DESC' |
|---|
| 105 | cursor = db.cursor() |
|---|
| 106 | cursor.execute(query, args) |
|---|
| 107 | return [PullRequest(id, status, author, reviewers, from_utimestamp(opened), from_utimestamp(modified), ticket, comment, wikilink) |
|---|
| 108 | for id, status, author, reviewers, opened, modified, ticket, comment, wikilink in cursor] |
|---|
| 109 | |
|---|
| 110 | @classmethod |
|---|
| 111 | def select_all_paginated(cls, env, page, max_per_page): |
|---|
| 112 | rows = env.db_query(""" |
|---|
| 113 | SELECT id, status, author, reviewers, opened, modified, ticket, comment, wikilink |
|---|
| 114 | FROM pullrequests |
|---|
| 115 | ORDER BY id DESC |
|---|
| 116 | LIMIT %s OFFSET %s |
|---|
| 117 | """, (max_per_page, max_per_page * (page - 1))) |
|---|
| 118 | return [PullRequest(id, status, author, reviewers, from_utimestamp(opened), from_utimestamp(modified), ticket, comment, wikilink) |
|---|
| 119 | for id, status, author, reviewers, opened, modified, ticket, comment, wikilink in rows] |
|---|
| 120 | |
|---|
| 121 | @classmethod |
|---|
| 122 | def count_all(cls, env): |
|---|
| 123 | with env.db_query as db: |
|---|
| 124 | return db(""" |
|---|
| 125 | SELECT COUNT(*) |
|---|
| 126 | FROM pullrequests |
|---|
| 127 | """)[0][0] |
|---|