
-- create load functions

create or replace function get_value(tname text, vtext text) returns bigint as $$
begin
  case tname
    when 'node' then
      return get_node(vtext);
    when 'text' then
      return get_text(vtext);
    when 'int' then
      return to_number(vtext, '99999999');
    else
      return 0;
  end case;
end;
$$ language plpgsql;


create or replace function get_node(vtext text, out value bigint) as $$
declare
  pfx text;
  vname text;
begin
  pfx := split_part(vtext, ':', 1);
  vname := split_part(vtext, ':', 2);
  select nodes.id into value from nodes, namespaces ns
    where ns.prefix = pfx
      and nodes.namespace = ns.id
      and nodes.name = vname;
  if not found then 
      insert into nodes (namespace, name)
        (select ns.id, vname from namespaces ns where ns.prefix = pfx)
        returning nodes.id into value;
  end if;
end;
$$ language plpgsql;


create or replace function get_text(vtext text, out value bigint) as $$
begin
  select texts.id into value from texts
    where text = vtext;
  if not found then 
      insert into texts (text) values (vtext)
        returning texts.id into value;
  end if;
end;
$$ language plpgsql;


create or replace function load_triple(
    stname text, stext text, ptext text,
    otname text, otext text, event bigint) returns bigint as $$
declare
  st smallint;
  sv bigint;
  pred bigint;
  ot smallint;
  ov bigint;
begin
  st := get_datatype(stname);
  ot := get_datatype(otname);
  sv := get_value(stname, stext);
  pred := get_value('node', ptext);
  ov := get_value(otname, otext);
  return load_triple(st, sv, pred, ot, ov, event);
end;
$$ language plpgsql;


create or replace function load_triple(
    st smallint, sv bigint, pred bigint,
    ot smallint, ov bigint, event bigint, out trid bigint) as $$
begin
  select tr.id into trid from triples tr
    where stype = st and svalue = sv and predicate = pred 
      and otype = ot and ovalue = ov;
  if not found then
    insert into triples (stype, svalue, predicate, otype, ovalue, creation)
      values (st, sv, pred, ot, ov, event)
      returning triples.id into trid;
  end if;
end;
$$ language plpgsql;


create or replace function load_namespace(
        nsiri text, nspfx text, out nsid int) as $$
begin
  nsid := get_nsiri(nsiri);
  if nsid is null then
    nsid := get_nsprefix(nspfx);
    if nsid is null then
      insert into namespaces as ns (iri, prefix)
        values (nsiri, nspfx)
        returning ns.id into nsid;
    end if;
  end if;
end;
$$ language plpgsql;


create or replace function load_datatype(
        name text, tname text, out dtid smallint) as $$
begin
  dtid := get_datatype(name);
  if dtid is null then
    insert into datatypes as dt (dtname, tablename)
      values (name, tname)
      returning dt.id into dtid;
  end if;
end;
$$ language plpgsql;


create or replace function load_datatype(name text, out dtid smallint) as $$
begin
  dtid := get_datatype(name);
  if dtid is null then
    insert into datatypes as dt (dtname) values (name)
      returning dt.id into dtid;
  end if;
end;
$$ language plpgsql;


-- simple SQL functions

create or replace function get_nsiri(nsiri text) returns int as $$
  select ns.id from namespaces ns where iri = nsiri;
$$ language sql;


create or replace function get_nsprefix(nspfx text) returns int as $$
  select ns.id from namespaces ns where prefix = nspfx;
$$ language sql;


create or replace function get_datatype(name text) returns smallint as $$
  select dt.id from datatypes dt where dtname = name;
$$ language sql;


create or replace function new_event() returns bigint as $$
  insert into events default values returning id;
$$ language sql;
