Skip to content

Commit

Permalink
Schema for subscriptions
Browse files Browse the repository at this point in the history
Create table for subscriptions.

Populate table with subscriptions for attachments and revisions.

Subscriptions will support multiple repositories and Git, even though
code comments themselves don't currently (trac-hacks#13 and trac-hacks#14).
  • Loading branch information
schwuk committed Aug 9, 2014
1 parent 0fa54f4 commit efdca67
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 22 deletions.
105 changes: 84 additions & 21 deletions code_comments/db.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from trac.core import *
from trac.core import Component, implements
from trac.db.schema import Table, Column, Index
from trac.env import IEnvironmentSetupParticipant
from trac.db.api import DatabaseManager

# Database version identifier for upgrades.
db_version = 2
db_version = 3

# Database schema
schema = {
Expand All @@ -21,61 +21,119 @@
Index(['path']),
Index(['author']),
],
'code_comments_subscriptions': Table('code_comments_subscriptions',
key=('user', 'type', 'path',
'repos', 'rev'))[
Column('user'),
Column('usertype'),
Column('type'),
Column('path'),
Column('repos'),
Column('rev'),
Index(['user']),
Index(['path']),
],
}


def to_sql(env, table):
""" Convenience function to get the to_sql for the active connector."""
dc = DatabaseManager(env)._get_connector()[0]
return dc.to_sql(table)


def create_tables(env, db):
cursor = db.cursor()
for table_name in schema:
for stmt in to_sql(env, schema[table_name]):
cursor.execute(stmt)
cursor.execute("INSERT into system values ('code_comments_schema_version', %s)",
str(db_version))
cursor.execute(
"insert into system values ('code_comments_schema_version', %s)",

This comment has been minimized.

Copy link
@nb

nb Aug 20, 2014

We usually capitalize SQL keywords.

This comment has been minimized.

Copy link
@schwuk

schwuk Aug 20, 2014

Author Owner

Not sure how that snuck in, but addressed in c7e1392.

str(db_version))


# Upgrades

def upgrade_from_1_to_2(env, db):
# Add the new column "type"
@env.with_transaction()
def add_type_column( db ):
def add_type_column(db):
cursor = db.cursor()
cursor.execute( 'ALTER TABLE code_comments ADD COLUMN type TEXT' )
cursor.execute('ALTER TABLE code_comments ADD COLUMN type TEXT')

# Convert all the current comments to the new schema
@env.with_transaction()
def convert_comments( db ):
def convert_comments(db):
comments = {}
cursor = db.cursor()
cursor.execute( 'SELECT id, path FROM code_comments' )
cursor.execute('SELECT id, path FROM code_comments')
comments = cursor.fetchall()
# options:
# 1: comment on file (path != "" && path != "attachment")
# 2: comment on changeset (path == "")
# 3: comment on attachment (path == "attachment")
for comment in comments:
path = comment[1]
is_comment_to_attachment = path.startswith( 'attachment' )
is_comment_to_attachment = path.startswith('attachment')
is_comment_to_file = not is_comment_to_attachment and '' != path
is_comment_to_changeset = '' == path
cursor = db.cursor()
update = 'UPDATE code_comments SET type={0} WHERE id={1}'
sql = ''

if is_comment_to_changeset:
sql = update.format( "'changeset'", str( comment[0] ) )
sql = update.format("'changeset'", str(comment[0]))
elif is_comment_to_attachment:
sql = update.format( "'attachment'", str(comment[0] ) )
sql = update.format("'attachment'", str(comment[0]))
elif is_comment_to_file:
sql = update.format( "'browser'", str(comment[0] ) )
sql = update.format("'browser'", str(comment[0]))

cursor.execute(sql)


def upgrade_from_2_to_3(env, db):
# Add the new table
@env.with_transaction()
def add_subscriptions_table(db):
cursor = db.cursor()
for stmt in to_sql(env, schema['code_comments_subscriptions']):
cursor.execute(stmt)

@env.with_transaction()
def add_attachment_subscriptions(db):
"""
Create a subscription for all existing attachments.
"""
cursor = db.cursor()
cursor.execute("SELECT type, id, filename, author FROM attachment")
attachments = cursor.fetchall()
for attachment in attachments:
path = "/{0}/{1}/{2}".format(*attachment)
sql = ("INSERT INTO code_comments_subscriptions VALUES "
"('{3}', 'author', 'attachment', '{path}', '', '')"
).format(*attachment, path=path)
cursor.execute(sql)

@env.with_transaction()
def add_revision_subscriptions(db):
"""
Create a subscription for all existing revisions.
"""
cursor = db.cursor()
cursor.execute("SELECT repos, rev, author FROM revision")
revisions = cursor.fetchall()
for revision in revisions:
sql = ("INSERT INTO code_comments_subscriptions VALUES "
"('{2}', 'author', 'revision', '', '{0}', '{1}')"
).format(*revision)
cursor.execute(sql)

cursor.execute( sql )

upgrade_map = {
2: upgrade_from_1_to_2
}
2: upgrade_from_1_to_2,
3: upgrade_from_2_to_3,
}


class CodeCommentsSetup(Component):
"""Component that deals with database setup and upgrades."""
Expand All @@ -87,13 +145,17 @@ def environment_created(self):
pass

def environment_needs_upgrade(self, db):
"""Called when Trac checks whether the environment needs to be upgraded.
Returns `True` if upgrade is needed, `False` otherwise."""
"""
Called when Trac checks whether the environment needs to be upgraded.
Returns `True` if upgrade is needed, `False` otherwise.
"""
return self._get_version(db) != db_version

def upgrade_environment(self, db):
"""Actually perform an environment upgrade, but don't commit as
that is done by the common upgrade procedure when all plugins are done."""
"""
Actually perform an environment upgrade, but don't commit as
that is done by the common upgrade procedure when all plugins are done.
"""
current_ver = self._get_version(db)
if current_ver == 0:
create_tables(self.env, db)
Expand All @@ -102,8 +164,9 @@ def upgrade_environment(self, db):
upgrade_map[current_ver+1](self.env, db)
current_ver += 1
cursor = db.cursor()
cursor.execute("UPDATE system SET value=%s WHERE name='code_comments_schema_version'",
str(db_version))
cursor.execute(
"UPDATE system SET value=%s WHERE name='code_comments_schema_version'",
str(db_version))

def _get_version(self, db):
cursor = db.cursor()
Expand Down
2 changes: 1 addition & 1 deletion todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Need to figure out how to handle blanket subscriptions.
## Subscriptions

- [ ] model
- [ ] db
- [x] db
- [ ] api - create, update, delete, query

## Listeners
Expand Down

0 comments on commit efdca67

Please sign in to comment.