Module: Heya::Campaigns::Queries
- Defined in:
- lib/heya/campaigns/queries.rb
Constant Summary collapse
- NEXT_STEP_SUBQUERY =
"(WITH steps AS (SELECT * FROM (VALUES :steps_values) AS m (step_gid,campaign_gid,position))\n SELECT m.step_gid FROM steps AS m\n WHERE m.campaign_gid = :campaign_gid\n AND m.position > coalesce((SELECT m.position FROM heya_campaign_receipts AS r\n INNER JOIN steps AS m ON m.step_gid = r.step_gid\n AND m.campaign_gid = :campaign_gid\n WHERE r.user_type = heya_campaign_memberships.user_type\n AND r.user_id = heya_campaign_memberships.user_id\n ORDER BY m.position DESC\n LIMIT 1), -1)\n ORDER BY m.position ASC\n LIMIT 1\n) = :step_gid\n"- ACTIVE_CAMPAIGN_SUBQUERY =
"(WITH heya_campaigns AS (SELECT * FROM (VALUES :campaigns_values) AS campaigns (campaign_gid,position))\nSELECT memberships.campaign_gid FROM heya_campaign_memberships AS memberships\n INNER JOIN heya_campaigns AS campaigns\n ON campaigns.campaign_gid = memberships.campaign_gid\n WHERE memberships.user_type = heya_campaign_memberships.user_type\n AND memberships.user_id = heya_campaign_memberships.user_id\n AND memberships.concurrent = FALSE\n ORDER BY campaigns.position DESC, memberships.created_at ASC\n LIMIT 1\n) = :campaign_gid\n"- UsersForStep =
Given a campaign and a step, UsersForStep returns the users who should complete the step.
->(campaign, step) { wait_threshold = Time.now.utc - step.wait # Safeguard to make sure we never complete the same step twice. receipt_query = CampaignReceipt .select("heya_campaign_receipts.user_id") .where(user_type: campaign.user_class.name) .where("heya_campaign_receipts.step_gid = ?", step.gid) # https://www.postgresql.org/docs/9.4/queries-values.html steps_values = campaign.steps.map { |m| ActiveRecord::Base.sanitize_sql_array( ["(?, ?, ?)", m.gid, campaign.gid, m.position] ) }.join(", ") priority = Heya.config.campaigns.priority.reverse.map { |c| c.is_a?(String) ? c : c.name } campaigns_values = Heya.campaigns.map { |c| ActiveRecord::Base.sanitize_sql_array( ["(?, ?)", c.gid, priority.index(c.name) || -1] ) }.join(", ") users = campaign.users users .where.not(id: receipt_query) .where(NEXT_STEP_SUBQUERY.gsub(":steps_values", steps_values), { campaign_gid: campaign.gid, step_gid: step.gid }) .merge( users .where("heya_campaign_memberships.concurrent = ?", true) .or( users.where(ACTIVE_CAMPAIGN_SUBQUERY.gsub(":campaigns_values", campaigns_values), { campaign_gid: campaign.gid }) ) ) .where( "heya_campaign_memberships.last_sent_at <= ?", wait_threshold ) }
- UsersCompletedStep =
Given a campaign and a step, UsersCompletedStep returns the users who have completed the step.
->(campaign, step) { receipt_query = CampaignReceipt .select("heya_campaign_receipts.user_id") .where(user_type: campaign.user_class.name) .where("heya_campaign_receipts.step_gid = ?", step.gid) campaign.users .where(id: receipt_query) }
- CampaignMembershipsForUpdate =
Given a campaign and a user, CampaignMembershipsForUpdate returns the user’s campaign memberships which should be updated concurrently.
->(campaign, user) { membership = CampaignMembership.where(user: user, campaign_gid: campaign.gid).first if membership.concurrent? CampaignMembership .where(user: user, campaign_gid: campaign.gid) else CampaignMembership .where(user: user, concurrent: false) end }
- OrphanedCampaignMemberships =
Given a campaign, OrphanedCampaignMemberships returns the campaign memberships which belong to users who no longer exist in the database.
->(campaign) { CampaignMembership .where(campaign_gid: campaign.gid) .where(user_type: campaign.user_class.base_class.name) .where.not(user_id: campaign.users.select("id")) }