feat(schedule): optimize set_schedule with update-first approach
Changed the set_schedule function to first attempt updating existing records before inserting new ones. This improves efficiency by avoiding unnecessary insert conflicts and subsequent updates. The logic now: 1. Tries to update matching existing schedule first 2. Only performs insert if no matching record was found 3. Maintains same functionality but with better performance
This commit is contained in:
parent
02c36a8888
commit
72f7081acb
3 changed files with 43 additions and 4 deletions
10
migrations/6.0.6.sql
Normal file
10
migrations/6.0.6.sql
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
-- Migration 6.0.6: Add unique constraint for system_automations
|
||||||
|
-- Fixes error: "there is no unique or exclusion constraint matching the ON CONFLICT specification"
|
||||||
|
|
||||||
|
ALTER TABLE public.system_automations
|
||||||
|
ADD CONSTRAINT system_automations_bot_kind_param_unique
|
||||||
|
UNIQUE (bot_id, kind, param);
|
||||||
|
|
||||||
|
-- Add index for the new constraint
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_system_automations_bot_kind_param
|
||||||
|
ON public.system_automations (bot_id, kind, param);
|
||||||
19
migrations/6.0.7.sql
Normal file
19
migrations/6.0.7.sql
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- Migration 6.0.7: Fix clicks table primary key
|
||||||
|
-- Required by Diesel before we can run other migrations
|
||||||
|
|
||||||
|
-- Create new table with proper structure
|
||||||
|
CREATE TABLE IF NOT EXISTS public.new_clicks (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
campaign_id text NOT NULL,
|
||||||
|
email text NOT NULL,
|
||||||
|
updated_at timestamptz DEFAULT now() NULL,
|
||||||
|
CONSTRAINT new_clicks_campaign_id_email_key UNIQUE (campaign_id, email)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Copy data from old table
|
||||||
|
INSERT INTO public.new_clicks (campaign_id, email, updated_at)
|
||||||
|
SELECT campaign_id, email, updated_at FROM public.clicks;
|
||||||
|
|
||||||
|
-- Drop old table and rename new one
|
||||||
|
DROP TABLE public.clicks;
|
||||||
|
ALTER TABLE public.new_clicks RENAME TO clicks;
|
||||||
|
|
@ -38,10 +38,11 @@ pub fn execute_set_schedule(
|
||||||
is_active.eq(true),
|
is_active.eq(true),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = diesel::insert_into(system_automations)
|
// First try to update existing record
|
||||||
.values(&new_automation)
|
let update_result = diesel::update(system_automations)
|
||||||
.on_conflict((bot_id, kind, param))
|
.filter(bot_id.eq(bot_uuid))
|
||||||
.do_update()
|
.filter(kind.eq(TriggerKind::Scheduled as i32))
|
||||||
|
.filter(param.eq(script_name))
|
||||||
.set((
|
.set((
|
||||||
schedule.eq(cron),
|
schedule.eq(cron),
|
||||||
is_active.eq(true),
|
is_active.eq(true),
|
||||||
|
|
@ -49,6 +50,15 @@ pub fn execute_set_schedule(
|
||||||
))
|
))
|
||||||
.execute(&mut *conn)?;
|
.execute(&mut *conn)?;
|
||||||
|
|
||||||
|
// If no rows were updated, insert new record
|
||||||
|
let result = if update_result == 0 {
|
||||||
|
diesel::insert_into(system_automations)
|
||||||
|
.values(&new_automation)
|
||||||
|
.execute(&mut *conn)?
|
||||||
|
} else {
|
||||||
|
update_result
|
||||||
|
};
|
||||||
|
|
||||||
Ok(json!({
|
Ok(json!({
|
||||||
"command": "set_schedule",
|
"command": "set_schedule",
|
||||||
"schedule": cron,
|
"schedule": cron,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue