

-- Tout le reste du fichier se trouvant sous cette ligne est sous licence MIT

-- Copyright 2019 Michel Petit / Cogito Ergo Dev
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
CREATE OR REPLACE FUNCTION short_token(base TEXT, size INT)
RETURNS TEXT AS $$

DECLARE
  token TEXT;
BEGIN
    IF base = 'base64' THEN
      token := rtrim(encode(gen_random_bytes(size), 'base64'), '=');
      token := replace(token, '/', '_');
      token := replace(token, '+', '-');
    ELSIF base = 'hex' THEN
      token := encode(gen_random_bytes(size), 'hex');
    ELSIF base = 'dec' THEN
      token := hex2dec(encode(gen_random_bytes(size), 'hex'));
    ELSE
      RAISE EXCEPTION 'Bad value for "base" argument. It must be "base64", "hex" or "dec".';
    END IF;
  RETURN token;
END;
$$ language 'plpgsql';




CREATE OR REPLACE FUNCTION unique_short_token()
RETURNS TRIGGER AS $$

DECLARE
  token TEXT;
  query TEXT;
  found TEXT;
BEGIN

  query := 'SELECT token FROM ' || quote_ident(TG_TABLE_NAME) || ' WHERE token=';

  LOOP
    token := short_token(CAST(TG_ARGV[0] AS TEXT), CAST(TG_ARGV[1] AS INT));
    
    EXECUTE query || quote_literal(token)
    INTO    found;

    IF found IS NULL THEN
      EXIT;
    END IF;
  END LOOP;

  NEW.token = token;

  RETURN NEW;
END;
$$ language 'plpgsql';




DROP TRIGGER IF EXISTS trigger_unique_short_token ON examples;




DROP TRIGGER IF EXISTS trigger_unique_short_token ON examples2;




DROP TRIGGER IF EXISTS trigger_unique_short_token ON examples3;