| rev | 
   line source | 
| 
jbe/bsw@0
 | 
     1 --[[--
 | 
| 
jbe/bsw@0
 | 
     2 param.update_relationship{
 | 
| 
jbe/bsw@0
 | 
     3   param_name        = param_name,        -- name of request GET/POST request parameters containing primary keys for model B
 | 
| 
jbe/bsw@0
 | 
     4   id                = id,                -- value of the primary key for model A
 | 
| 
jbe/bsw@0
 | 
     5   connecting_model  = connecting_model,  -- model used for creating/deleting entries referencing both model A and B
 | 
| 
jbe/bsw@0
 | 
     6   own_reference     = own_reference,     -- field name for foreign key in the connecting model referencing model A 
 | 
| 
jbe/bsw@0
 | 
     7   foreign_reference = foreign_reference  -- field name for foreign key in the connecting model referencing model B
 | 
| 
jbe/bsw@0
 | 
     8 }
 | 
| 
jbe/bsw@0
 | 
     9 
 | 
| 
jbe/bsw@0
 | 
    10 This function updates a many-to-many relationship using a specified 'connecting_model' referencing both models.
 | 
| 
jbe/bsw@0
 | 
    11 
 | 
| 
jbe/bsw@0
 | 
    12 --]]--
 | 
| 
jbe/bsw@0
 | 
    13 
 | 
| 
jbe/bsw@0
 | 
    14 function param.update_relationship(args)
 | 
| 
jbe/bsw@0
 | 
    15   local param_name        = args.param_name
 | 
| 
jbe/bsw@0
 | 
    16   local id                = args.id
 | 
| 
jbe/bsw@0
 | 
    17   local connecting_model  = args.connecting_model
 | 
| 
jbe/bsw@0
 | 
    18   local own_reference     = args.own_reference
 | 
| 
jbe/bsw@0
 | 
    19   local foreign_reference = args.foreign_reference
 | 
| 
jbe/bsw@0
 | 
    20   local selected_ids = param.get_list(param_name, atom.integer)  -- TODO: support other types than integer too
 | 
| 
jbe/bsw@0
 | 
    21   local db    = connecting_model:get_db_conn()
 | 
| 
jbe/bsw@0
 | 
    22   local table = connecting_model:get_qualified_table()
 | 
| 
jbe/bsw@0
 | 
    23   if #selected_ids == 0 then
 | 
| 
jbe/bsw@0
 | 
    24     db:query{
 | 
| 
jbe/bsw@0
 | 
    25       'DELETE FROM ' .. table .. ' WHERE "' .. own_reference .. '" = ?',
 | 
| 
jbe/bsw@0
 | 
    26       args.id
 | 
| 
jbe/bsw@0
 | 
    27     }
 | 
| 
jbe/bsw@0
 | 
    28   else
 | 
| 
jbe/bsw@0
 | 
    29     local selected_ids_sql = { sep = ", " }
 | 
| 
jbe/bsw@0
 | 
    30     for idx, value in ipairs(selected_ids) do
 | 
| 
jbe/bsw@0
 | 
    31       selected_ids_sql[idx] = {"?::int8", value}
 | 
| 
jbe/bsw@0
 | 
    32     end
 | 
| 
jbe/bsw@0
 | 
    33     db:query{
 | 
| 
jbe/bsw@0
 | 
    34       'DELETE FROM ' .. table ..
 | 
| 
jbe/bsw@0
 | 
    35       ' WHERE "' .. own_reference .. '" = ?' ..
 | 
| 
jbe/bsw@0
 | 
    36       ' AND NOT "' .. foreign_reference .. '" IN ($)',
 | 
| 
jbe/bsw@0
 | 
    37       args.id,
 | 
| 
jbe/bsw@0
 | 
    38       selected_ids_sql
 | 
| 
jbe/bsw@0
 | 
    39     }
 | 
| 
jbe/bsw@0
 | 
    40     -- TODO: use VALUES SQL command, instead of this dirty array trick
 | 
| 
jbe/bsw@0
 | 
    41     db:query{
 | 
| 
jbe/bsw@0
 | 
    42       'INSERT INTO ' .. table ..
 | 
| 
jbe/bsw@0
 | 
    43       ' ("' .. own_reference .. '", "' .. foreign_reference .. '")' ..
 | 
| 
jbe/bsw@0
 | 
    44       ' SELECT ?, "subquery"."foreign" FROM (' ..
 | 
| 
jbe/bsw@0
 | 
    45         'SELECT (ARRAY[$])[i] AS "foreign"' ..
 | 
| 
jbe/bsw@0
 | 
    46         ' FROM generate_series(1, ?) AS "dummy"("i")' ..
 | 
| 
jbe/bsw@0
 | 
    47         ' EXCEPT SELECT "' .. foreign_reference .. '" AS "foreign"' ..
 | 
| 
jbe/bsw@0
 | 
    48         ' FROM ' .. table ..
 | 
| 
jbe/bsw@0
 | 
    49         ' WHERE "' .. own_reference .. '" = ?' ..
 | 
| 
jbe/bsw@0
 | 
    50       ') AS "subquery"',
 | 
| 
jbe/bsw@0
 | 
    51       args.id,
 | 
| 
jbe/bsw@0
 | 
    52       selected_ids_sql,
 | 
| 
jbe/bsw@0
 | 
    53       #selected_ids,
 | 
| 
jbe/bsw@0
 | 
    54       args.id
 | 
| 
jbe/bsw@0
 | 
    55     }
 | 
| 
jbe/bsw@0
 | 
    56   end
 | 
| 
jbe/bsw@0
 | 
    57 end
 |