From e78c2560bbd376669243e4c2800a70622e532881 Mon Sep 17 00:00:00 2001 From: Jonathan Zernik Date: Tue, 24 Aug 2021 17:39:49 -0700 Subject: [PATCH] Make reply to hash nullable (#1057) * Make reply to hash column nullable * Add itest for null reply_to field --- itests/tests/test_squeak_node.py | 2 ++ squeaknode/admin/messages.py | 4 +-- ...dec68bd0785_make_reply_to_hash_nullable.py | 36 +++++++++++++++++++ squeaknode/db/models.py | 2 +- squeaknode/db/squeak_db.py | 6 ++-- 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 squeaknode/db/alembic/versions/adec68bd0785_make_reply_to_hash_nullable.py diff --git a/itests/tests/test_squeak_node.py b/itests/tests/test_squeak_node.py index 44151d54..7ad284de 100644 --- a/itests/tests/test_squeak_node.py +++ b/itests/tests/test_squeak_node.py @@ -90,6 +90,8 @@ def test_make_squeak(admin_stub, signing_profile_id): assert get_squeak_display_entry.HasField("author") assert len( get_squeak_display_entry.author.profile_image) > 0 + assert not get_squeak_display_entry.is_reply + assert not bool(get_squeak_display_entry.reply_to) # Block time should be within the past hour block_time = datetime.datetime.fromtimestamp( diff --git a/squeaknode/admin/messages.py b/squeaknode/admin/messages.py index 93ad1bf9..55d55fdf 100644 --- a/squeaknode/admin/messages.py +++ b/squeaknode/admin/messages.py @@ -23,13 +23,13 @@ logger = logging.getLogger(__name__) DEFAULT_PROFILE_IMAGE = load_default_profile_image() # TODO: Remove this after reply is nullable column -EMPTY_HASH = b'\x00' * 32 +# EMPTY_HASH = b'\x00' * 32 def squeak_entry_to_message(squeak_entry_with_profile: SqueakEntryWithProfile) -> squeak_admin_pb2.SqueakDisplayEntry: squeak_entry = squeak_entry_with_profile.squeak_entry squeak_profile = squeak_entry_with_profile.squeak_profile - is_reply = squeak_entry.reply_to != EMPTY_HASH + is_reply = bool(squeak_entry.reply_to) reply_to = squeak_entry.reply_to.hex() if squeak_entry.reply_to else None is_author_known = False profile_msg = None diff --git a/squeaknode/db/alembic/versions/adec68bd0785_make_reply_to_hash_nullable.py b/squeaknode/db/alembic/versions/adec68bd0785_make_reply_to_hash_nullable.py new file mode 100644 index 00000000..f200ca8c --- /dev/null +++ b/squeaknode/db/alembic/versions/adec68bd0785_make_reply_to_hash_nullable.py @@ -0,0 +1,36 @@ +"""Make reply to hash nullable + +Revision ID: adec68bd0785 +Revises: a35d180bf020 +Create Date: 2021-08-24 17:10:21.009027 + +""" +import sqlalchemy as sa +from alembic import op + + +# revision identifiers, used by Alembic. +revision = 'adec68bd0785' +down_revision = 'a35d180bf020' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('squeak', schema=None) as batch_op: + batch_op.alter_column('hash_reply_sqk', + existing_type=sa.VARCHAR(length=64), + nullable=True) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('squeak', schema=None) as batch_op: + batch_op.alter_column('hash_reply_sqk', + existing_type=sa.VARCHAR(length=64), + nullable=False) + + # ### end Alembic commands ### diff --git a/squeaknode/db/models.py b/squeaknode/db/models.py index 5d687d48..7198c1cd 100644 --- a/squeaknode/db/models.py +++ b/squeaknode/db/models.py @@ -63,7 +63,7 @@ class Models: Column("created", TZDateTime, server_default=func.now(), nullable=False), Column("squeak", Binary, nullable=False), - Column("hash_reply_sqk", String(64), nullable=False), + Column("hash_reply_sqk", String(64), nullable=True), Column("hash_block", String(64), nullable=False), Column("n_block_height", Integer, nullable=False), Column("n_time", Integer, nullable=False), diff --git a/squeaknode/db/squeak_db.py b/squeaknode/db/squeak_db.py index 1685274d..16f20146 100644 --- a/squeaknode/db/squeak_db.py +++ b/squeaknode/db/squeak_db.py @@ -167,7 +167,7 @@ class SqueakDb: ins = self.squeaks.insert().values( hash=get_hash(squeak).hex(), squeak=squeak.serialize(), - hash_reply_sqk=squeak.hashReplySqk.hex(), + hash_reply_sqk=squeak.hashReplySqk.hex() if squeak.is_reply else None, hash_block=squeak.hashBlock.hex(), n_block_height=squeak.nBlockHeight, n_time=squeak.nTime, @@ -1103,6 +1103,8 @@ class SqueakDb: def _parse_squeak_entry(self, row) -> SqueakEntry: secret_key_column = row["secret_key"] is_locked = bool(secret_key_column) + reply_to = bytes.fromhex( + row["hash_reply_sqk"]) if row["hash_reply_sqk"] else None liked_time = row["liked_time"] liked_time_s = int(liked_time.timestamp()) if liked_time else None return SqueakEntry( @@ -1111,7 +1113,7 @@ class SqueakDb: block_height=row["n_block_height"], block_hash=bytes.fromhex(row["hash_block"]), block_time=row["block_time"], - reply_to=bytes.fromhex(row["hash_reply_sqk"]), + reply_to=reply_to, is_unlocked=is_locked, liked_time=liked_time_s, content=row["content"],