0

Seem to be having issues with a type mismatch, but I can't wrap my head around it, need a second pair of eyes, I find the Crystal type mismatch errors to be almost unreadable when dealing with databases.

Aliases (accounts.cr)

alias CampaignDetail = NamedTuple(id: Int32, list_id: Int32, list_name: String, list_status: String, is_triggered: String, trigger_data: String, sender_id: Int32, sender_name: String)
alias Sender = Array(Array(Sender | CampaignDetail)) | Array(Sender | CampaignDetail) | Array(String | Int32 | Nil)
alias CombinedCampaign = Array({id: Int32,
                                list_id: Int32,
                                list_name: String,
                                list_status: String,
                                is_triggered: String,
                                trigger_data: String,
                                sender_id: Int32,
                                sender_name: String})

alias AccountDetails = Array(NamedTuple(id_access: Int32,
                                        account_id: Int32,
                                        account_company: String,
                                        redis_host: String,
                                        redis_password: String,
                                        redis_port: Int16,
                                        db_host: String,
                                        db_username: String,
                                        db_password: String,
                                        db_port: Int32))

Operating Code (accounts.cr)

uncombined_campaign_data : Sender | CampaignDetail | CombinedCampaign
uncombined_campaign_data = Array(CampaignDetail).new
campaign_data : Array(CombinedCampaign)
campaign_data = Array(CombinedCampaign).new
@mysql_conn.db_proc(query_campaigns,
                    alternate_db: "*****_#{account[:account_id]}",
                    host: account[:db_host],
                    username: account[:db_username],
                    port: account[:db_port].to_s,
                    password: account[:db_password],
                    type: :select) do |results|

    uncombined_campaign_data << [results.read(Int32),
                                 results.read(Int32),
                                 results.read(String),
                                 results.read(String),
                                 results.read(String),
                                 results.read(String)
                                ]
end

query_sender = %{SELECT `sender`.`id`, `sender`.`name` FROM `******`.`sender`
                 WHERE `sender`.`id` IN (#{campaign_data.join(", ") {|campaign| "'" + campaign.not_nil![0].to_s+ "'" }})}

combined_campaign = CombinedCampaign.new
combined_campaign_data = Array(CombinedCampaign).new

@mysql_conn.db_proc(query_campaigns,
                    alternate_db: "**********#{account[:account_id]}",
                    host: account[:db_host],
                    username: account[:db_username],
                    port: account[:db_port].to_s,
                    password: account[:db_password],
                    type: :select) do |results|
    id = results.read(Int32)
    sender = results.read(String)
    campaign_data += campaign_data.map_with_index do |campaign, i|
        if campaign.not_nil![0] == id
            {
                id:           campaign[0].nil? ? 0 : campaign.as(Int32),
                list_id:      campaign[1].nil? ? 0 : campaign.as(Int32),
                list_name:    campaign[2].nil? ? "" : campaign.as(String),
                list_status:  campaign[3].nil? ? "" : campaign.as(String),
                is_triggered: campaign[4].nil? ? "" : campaign.as(String),
                trigger_data: campaign[5].nil? ? "" : campaign.as(String),
                sender_id:    id.nil? ? 0 : id.as(Int32),
                sender_name:  sender.nil? ? "" : sender.as(String)
            }
        else
            {

                id:            0,
                list_id:      0,
                list_name:    "",
                list_status:  "",
                is_triggered: "",
                trigger_data: "",
                sender_id:     0,
                sender_name:  ""
            }
        end
    end
    combined_campaign_data += combined_campaign
end
campaign_data = combined_campaign_data

Errors

Cycling between a couple of different errors when I try to fix:

in classes/accounts.cr:123: no overload matches 'Array(NamedTuple(id: Int32, list_id: Int32, list_name: String, list_status: String, is_triggered: String, trigger_data: String, sender_id: Int32, sender_name: String))#<<' with type Array(Int32 | String)
Overloads are:
 - Array(T)#<<(value : T)

    uncombined_campaign_data << [results.read(Int32),

in classes/accounts.cr:123: type must be (Array(Accounts::Sender | NamedTuple(id: Int32, list_id: Int32,
r_name: String)) | Array(Array(Accounts::Sender | NamedTuple(id: Int32, list_id: Int32, list_name: Strin
 | Array(Int32 | String | Nil) | Array(NamedTuple(id: Int32, list_id: Int32, list_name: String, list_sta
e(id: Int32, list_id: Int32, list_name: String, list_status: String, is_triggered: String, trigger_data:
ist_name: String, list_status: String, is_triggered: String, trigger_data: String, sender_id: Int32, sen
ring, is_triggered: String, trigger_data: String, sender_id: Int32, sender_name: String)))

    uncombined_campaign_data += [results.read(Int32),
    ^~~~~~~~~~~~~~~~~~~~~~~~

I don't understand how people really utilise these errors, as they always cripple my development time, spending a long time trying to decipher huuuge type mismatch messages.

If anyone could help with this it would be amazing, and also if you can provide any pointers on how best to debug a crystal compilation/runtime error as they are both nigh unreadable sometimes.

Community
  • 1
  • 1
Conner Stephen McCabe
  • 581
  • 4
  • 10
  • 20

1 Answers1

1

You are confusing NamedTuple, Tuple and Array which are three distinct types.

Since you are appending to an array of CampaignDetail you must also append a NamedTuple with the same keys:

uncombined_campaign_data << {id: results.read(Int32), list_id: … }
felixbuenemann
  • 579
  • 3
  • 18