Implements DB model and preliminary select queries
This commit is contained in:
parent
464fc88d8e
commit
0529fa7d01
1 changed files with 159 additions and 0 deletions
159
src/database/ddl.py
Normal file
159
src/database/ddl.py
Normal file
|
@ -0,0 +1,159 @@
|
|||
import json
|
||||
import logging
|
||||
|
||||
import math
|
||||
import timeit
|
||||
|
||||
import typing
|
||||
|
||||
from peewee import ModelSelect
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
from peewee import *
|
||||
|
||||
|
||||
def get_database_connection():
|
||||
# for now it's an sqlite database
|
||||
db = SqliteDatabase()
|
||||
return db
|
||||
|
||||
|
||||
database = get_database_connection()
|
||||
|
||||
|
||||
class BaseModel(Model):
|
||||
class Meta:
|
||||
database = database
|
||||
|
||||
|
||||
class Channel(BaseModel):
|
||||
claim_id = TextField(column_name='ClaimId', primary_key=True)
|
||||
name = TextField(column_name='Name')
|
||||
|
||||
class Meta:
|
||||
table_name = 'CHANNEL'
|
||||
|
||||
|
||||
class Comment(BaseModel):
|
||||
comment = TextField(column_name='Body')
|
||||
channel = ForeignKeyField(
|
||||
backref='comments',
|
||||
column_name='ChannelId',
|
||||
field='claim_id',
|
||||
model=Channel,
|
||||
null=True
|
||||
)
|
||||
comment_id = TextField(column_name='CommentId', primary_key=True)
|
||||
is_hidden = BooleanField(column_name='IsHidden', constraints=[SQL("DEFAULT FALSE")])
|
||||
claim_id = TextField(column_name='LbryClaimId')
|
||||
parent = ForeignKeyField(
|
||||
column_name='ParentId',
|
||||
field='comment_id',
|
||||
model='self',
|
||||
null=True,
|
||||
backref='replies'
|
||||
)
|
||||
signature = TextField(column_name='Signature', null=True, unique=True)
|
||||
signing_ts = TextField(column_name='SigningTs', null=True)
|
||||
timestamp = IntegerField(column_name='Timestamp')
|
||||
|
||||
class Meta:
|
||||
table_name = 'COMMENT'
|
||||
indexes = (
|
||||
(('author', 'comment_id'), False),
|
||||
(('claim_id', 'comment_id'), False),
|
||||
)
|
||||
|
||||
|
||||
COMMENT_FIELDS = [
|
||||
Comment.comment,
|
||||
Comment.comment_id,
|
||||
Comment.claim_id,
|
||||
Comment.timestamp,
|
||||
Comment.signature,
|
||||
Comment.signing_ts,
|
||||
Comment.is_hidden,
|
||||
Comment.parent.alias('parent_id'),
|
||||
]
|
||||
|
||||
CHANNEL_FIELDS = [
|
||||
Channel.claim_id.alias('channel_id'),
|
||||
Channel.name.alias('channel_name')
|
||||
]
|
||||
|
||||
|
||||
def get_comment_list(claim_id: str = None, parent_id: str = None,
|
||||
top_level: bool = False, exclude_mode: str = None,
|
||||
page: int = 1, page_size: int = 50, expressions=None) -> dict:
|
||||
query = Comment.select(*COMMENT_FIELDS, *CHANNEL_FIELDS)
|
||||
if claim_id:
|
||||
query = query.where(Comment.claim_id == claim_id)
|
||||
if top_level:
|
||||
query = query.where(Comment.parent.is_null())
|
||||
|
||||
if parent_id:
|
||||
query = query.where(Comment.ParentId == parent_id)
|
||||
|
||||
if exclude_mode:
|
||||
show_hidden = exclude_mode.lower() == 'hidden'
|
||||
query = query.where((Comment.is_hidden == show_hidden))
|
||||
total = query.count()
|
||||
query = (query
|
||||
.join(Channel, JOIN.LEFT_OUTER)
|
||||
.where(expressions)
|
||||
.order_by(Comment.timestamp.desc())
|
||||
.paginate(page, page_size))
|
||||
items = [clean(item) for item in query.dicts()]
|
||||
# has_hidden_comments is deprecated
|
||||
data = {
|
||||
'page': page,
|
||||
'page_size': page_size,
|
||||
'total_pages': math.ceil(total / page_size),
|
||||
'total_items': total,
|
||||
'items': items,
|
||||
'has_hidden_comments': exclude_mode is not None and exclude_mode == 'hidden',
|
||||
}
|
||||
return data
|
||||
|
||||
|
||||
def clean(thing: dict) -> dict:
|
||||
return {k: v for k, v in thing.items() if v is not None}
|
||||
|
||||
|
||||
def get_comment(comment_id: str) -> dict:
|
||||
try:
|
||||
comment: Comment = Comment.get_by_id(comment_id)
|
||||
except DoesNotExist as e:
|
||||
raise ValueError from e
|
||||
else:
|
||||
as_dict = model_to_dict(comment)
|
||||
if comment.channel:
|
||||
as_dict.update({
|
||||
'channel_id': comment.channel_id,
|
||||
'channel_name': comment.channel.name,
|
||||
'signature': comment.signature,
|
||||
'signing_ts': comment.signing_ts,
|
||||
'channel_url': f'lbry://{comment.channel.name}#{comment.channel_id}'
|
||||
})
|
||||
if comment.parent:
|
||||
as_dict.update({
|
||||
'parent_id': comment.parent_id
|
||||
})
|
||||
return clean(as_dict)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
logger = logging.getLogger('peewee')
|
||||
logger.addHandler(logging.StreamHandler())
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
comment_list = get_comment_list(
|
||||
page_size=1,
|
||||
expressions=(Comment.channel.is_null())
|
||||
)
|
||||
|
||||
comment = comment_list['items'].pop()
|
||||
print(json.dumps(comment, indent=4))
|
||||
other_comment = get_comment(comment['comment_id'])
|
||||
|
||||
print(json.dumps(other_comment, indent=4))
|
||||
print(comment == other_comment)
|
Loading…
Reference in a new issue