api/prepare: do not record identical schedule plans

If api.prepare is used in some command line tools to prepare a bunnch
of operations, it is annoying to have as duplicates the identical entries.
2 files changed, 23 insertions(+), 8 deletions(-)

M rework/api.py
M tests/test_api.py
M rework/api.py +19 -4
@@ 193,11 193,26 @@ def prepare(engine,
         else:
             rawinputdata = dumps(inputdata, protocol=2)
 
-    q = select('id').table('rework.operation').where(
-        name=opname
-    )
     with engine.begin() as cn:
-        opid = q.do(cn).scalar()
+        opid = select('id').table('rework.operation').where(
+            name=opname
+        ).do(cn).scalar()
+
+        # check replacement if operation + domain + host + rule matches
+        q = select('id').table('rework.sched').where(
+            operation=opid,
+            domain=domain,
+            rule=rule
+        )
+        if host:
+            q.where(host=host)
+        sid = q.do(cn).scalar()
+
+        if sid is not None:
+            cn.execute(
+                'delete from rework.sched where id=%(sid)s',
+                sid=sid
+            )
         q = insert('rework.sched').values(
             operation=opid,
             domain=domain,

          
M tests/test_api.py +4 -4
@@ 129,7 129,7 @@ def test_prepare(engine, cleanup):
         api.prepare(engine, 'foo', '* * * * * *')
 
     res = engine.execute('select count(*) from rework.sched').scalar()
-    assert res == 2
+    assert res == 1
 
 
 def test_with_inputs(engine, cleanup):

          
@@ 272,11 272,11 @@ def test_prepare_with_inputs(engine, cle
     spec = filterinput(specs, 'yummy')
     unpacked = unpack_inputs(spec, inputdata)
     assert unpacked == {
+        'birthdate': dt(1973, 5, 20, 0, 0),
         'myfile.txt': b'some file',
-        'weight': 65,
-        'birthdate': dt(1973, 5, 20, 9, 0),
         'name': 'Babar',
-        'option': 'foo'
+        'option': 'foo',
+        'weight': 65
     }