api/rename: add a `propagate` parameter

This will be used by extenders (notably formula).
In the future, all of this will be moved where it belongs.
5 files changed, 31 insertions(+), 6 deletions(-)

M test/test_api.py
M tshistory/api.py
M tshistory/http/client.py
M tshistory/http/server.py
M tshistory/tsio.py
M test/test_api.py +19 -0
@@ 1131,6 1131,25 @@ 2023-07-03 00:00:00+00:00  2023-07-01 00
     assert metadata == {'metadata1': 'value1'}
 
 
+def test_rename(tsx):
+    ts = pd.Series(
+        [1, 2, 3],
+        index=pd.date_range(
+            utcdt(2023, 1, 1),
+            freq='d',
+            periods=3
+        )
+    )
+    tsx.update('rename-me', ts, 'Babar')
+    tsx.rename('rename-me', 'me-renamed')
+    assert tsx.exists('me-renamed')
+    assert not tsx.exists('rename-me')
+
+    tsx.rename('me-renamed', 'renamed-again', propagate=False)
+    assert tsx.exists('renamed-again')
+    assert not tsx.exists('me-renamed')
+
+
 def test_str_series(tsx):
     ts = pd.Series(
         ['a', 'b', 'c'],

          
M tshistory/api.py +3 -2
@@ 768,7 768,8 @@ class mainsource:
 
     def rename(self,
                currname: str,
-               newname: str) -> NONETYPE:
+               newname: str,
+               propagate: bool=True) -> NONETYPE:
         """Rename a series.
 
         The target name must be available.

          
@@ 780,7 781,7 @@ class mainsource:
             'not allowed to rename to a secondary source'
         )
 
-        return self.tsh.rename(self.engine, currname, newname)
+        return self.tsh.rename(self.engine, currname, newname, propagate=propagate)
 
     def delete(self, name: str):
         """Delete a series.

          
M tshistory/http/client.py +2 -2
@@ 610,10 610,10 @@ class httpclient:
         return res
 
     @unwraperror
-    def rename(self, oldname, newname):
+    def rename(self, oldname, newname, propagate=True):
         res = self.session.put(
             f'{self.uri}/series/state',
-            data={'name': oldname, 'newname': newname}
+            data={'name': oldname, 'newname': newname, 'propagate': json.dumps(propagate)}
         )
         if res.status_code == 204:
             return

          
M tshistory/http/server.py +6 -1
@@ 103,6 103,11 @@ rename.add_argument(
     'newname', type=str, required=True,
     help='new name of the series'
 )
+rename.add_argument(
+    'propagate', type=inputs.boolean,
+    default=True,
+    help='propagate renaming to dependents'
+)
 
 source = base.copy()
 

          
@@ 730,7 735,7 @@ class httpapi:
                     api.abort(409, f'`{args.newname}` does exists')
 
                 try:
-                    tsa.rename(args.name, args.newname)
+                    tsa.rename(args.name, args.newname, args.propagate)
                 except ValueError as err:
                     if err.args[0].startswith('not allowed to'):
                         api.abort(405, err.args[0])

          
M tshistory/tsio.py +1 -1
@@ 683,7 683,7 @@ class timeseries:
         return q.do(cn).scalar()
 
     @tx
-    def rename(self, cn, oldname, newname):
+    def rename(self, cn, oldname, newname, propagate=True):
         sql = (f'update "{self.namespace}".registry '
                'set name = %(newname)s '
                'where name = %(oldname)s')