From 2fb3b7309c852efcf51859a574761797b6adb67d Mon Sep 17 00:00:00 2001
From: Oleg Silkin <o.silkin98@gmail.com>
Date: Fri, 3 Jan 2020 22:32:44 -0500
Subject: [PATCH] `create_comment` no longer requires `claim_id` when
 `parent_id` is supplied

---
 src/database/queries.py  | 38 ++++++++++++++++++++++++++++++++------
 src/database/writes.py   |  7 ++++---
 src/server/validation.py |  4 ++--
 3 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/src/database/queries.py b/src/database/queries.py
index 4264a57..16e6f0b 100644
--- a/src/database/queries.py
+++ b/src/database/queries.py
@@ -109,30 +109,56 @@ def claim_has_hidden_comments(conn, claim_id):
         return bool(tuple(result.fetchone())[0])
 
 
-def insert_comment(conn: sqlite3.Connection, claim_id: str, comment: str, parent_id: str = None,
-                   channel_id: str = None, signature: str = None, signing_ts: str = None) -> str:
+def insert_comment(conn: sqlite3.Connection, claim_id: str, comment: str,
+                   channel_id: str = None, signature: str = None, signing_ts: str = None, **extra) -> str:
     timestamp = int(time.time())
     prehash = b':'.join((claim_id.encode(), comment.encode(), str(timestamp).encode(),))
     comment_id = nacl.hash.sha256(prehash).decode()
     with conn:
-        conn.execute(
+        curs = conn.execute(
             """
             INSERT INTO COMMENT(CommentId, LbryClaimId, ChannelId, Body, ParentId, 
                                     Timestamp, Signature, SigningTs, IsHidden) 
-            VALUES (:comment_id, :claim_id, :channel_id, :comment, :parent_id,
+            VALUES (:comment_id, :claim_id, :channel_id, :comment, NULL,
                     :timestamp, :signature, :signing_ts, 0) """,
             {
                 'comment_id': comment_id,
                 'claim_id': claim_id,
                 'channel_id': channel_id,
                 'comment': comment,
-                'parent_id': parent_id,
                 'timestamp': timestamp,
                 'signature': signature,
                 'signing_ts': signing_ts
             }
         )
-    logging.info('Inserted Comment into DB, `comment_id`: %s', comment_id)
+        logging.info('attempted to insert comment with comment_id [%s] | %d rows affected', comment_id, curs.rowcount)
+    return comment_id
+
+
+def insert_reply(conn: sqlite3.Connection, comment: str, parent_id: str,
+                 channel_id: str = None, signature: str = None,
+                 signing_ts: str = None, **extra) -> str:
+    timestamp = int(time.time())
+    prehash = b':'.join((parent_id.encode(), comment.encode(), str(timestamp).encode(),))
+    comment_id = nacl.hash.sha256(prehash).decode()
+    with conn:
+        curs = conn.execute(
+            """
+            INSERT INTO COMMENT 
+                (CommentId, LbryClaimId, ChannelId, Body, ParentId, Signature, Timestamp, SigningTs, IsHidden) 
+            SELECT :comment_id, LbryClaimId, :channel_id, :comment, :parent_id, :signature, :timestamp, :signing_ts, 0
+            FROM COMMENT WHERE CommentId = :parent_id
+            """, {
+                'comment_id': comment_id,
+                'parent_id': parent_id,
+                'timestamp': timestamp,
+                'comment': comment,
+                'channel_id': channel_id,
+                'signature': signature,
+                'signing_ts': signing_ts
+            }
+        )
+        logging.info('attempted to insert reply with comment_id [%s] | %d rows affected', comment_id, curs.rowcount)
     return comment_id
 
 
diff --git a/src/database/writes.py b/src/database/writes.py
index eb189a6..e724521 100644
--- a/src/database/writes.py
+++ b/src/database/writes.py
@@ -16,11 +16,12 @@ import src.database.queries as db
 logger = logging.getLogger(__name__)
 
 
-def create_comment_or_error(conn, comment, claim_id, channel_id=None, channel_name=None,
+def create_comment_or_error(conn, comment, claim_id=None, channel_id=None, channel_name=None,
                             signature=None, signing_ts=None, parent_id=None) -> dict:
-    if channel_id or channel_name or signature or signing_ts:
+    if channel_id and channel_name:
         insert_channel_or_error(conn, channel_name, channel_id)
-    comment_id = db.insert_comment(
+    fn = db.insert_comment if parent_id is None else db.insert_reply
+    comment_id = fn(
         conn=conn,
         comment=comment,
         claim_id=claim_id,
diff --git a/src/server/validation.py b/src/server/validation.py
index 02f19b7..ad99f0c 100644
--- a/src/server/validation.py
+++ b/src/server/validation.py
@@ -52,8 +52,8 @@ def claim_id_is_valid(claim_id: str) -> bool:
 
 def is_valid_base_comment(comment: str, claim_id: str, parent_id: str = None, **kwargs) -> bool:
     return comment is not None and body_is_valid(comment) and \
-           claim_id is not None and claim_id_is_valid(claim_id) and \
-           (parent_id is None or comment_id_is_valid(parent_id))
+           ((claim_id is not None and claim_id_is_valid(claim_id)) or
+            (parent_id is not None and comment_id_is_valid(parent_id)))
 
 
 def is_valid_credential_input(channel_id: str = None, channel_name: str = None,
-- 
2.49.1