-- This is undoubtedly one of the more complex bits of code I've
-- written recently, and I do wish there had been macros because
-- there's a lot of hand-written, copy-pasted code here around the
-- basic content of a note; it would have been nice to be able to DRY
-- that out.

-- This expression creates a table, 'notetree', that contains all of
-- the notes nested under a page.  Each entry in the table includes
-- the note's parent's internal and external ids so that applications
-- can build an actual tree out of a vec of these things.

-- TODO: Extensive testing to validate that the nodes are delivered
-- *in nesting order* to the client.

SELECT
  parent_id,
  parent_uuid,
  note_id,
  note_uuid,
  content,
  position,
  notetype,
  creation_date,
  updated_date,
  lastview_date,
  deleted_date

FROM (

  WITH RECURSIVE notetree(
    parent_id,
    parent_uuid,
    id,
    uuid,
    content,
    position,
    notetype,
    creation_date,
    updated_date,
    lastview_date,
    deleted_date,
    cycle) AS

-- ROOT expression    
     SELECT
       notes.id,
       notes.uuid,
       notes.id,
       notes.uuid,
       notes.content,
       0,  -- Root notes are always in position 0
       notes.notetype,
       notes.creation_date,
       notes.updated_date,
       notes.lastview_date,
       notes.deleted_date,
	   ','||notes.id||','  -- Cycle monitor
     FROM notes
	   INNER JOIN pages ON pages.note_id = notes.id
     WHERE
       pages.slug = ? AND notes.notetype = "root"

-- RECURSIVE expression
     UNION SELECT
	   notetree.id,
	   notetree.uuid,
	   notes.id,
	   notes.uuid,
	   notes.content,
	   note_relationships.position,
	   notes.notetype,
	   notes.creation_date,
	   notes.updated_date,
	   notes.lastview_date,
	   notes.deleted_date,
	   notetree.cycle||notes.id||','
	 FROM notes
	   INNER JOIN note_relationships ON notes.id = note_relationships.note_id
	   -- For a given ID in the level of notetree in *this* recursion,
	   -- we want each note's branches one level down.
	   INNER JOIN notetree ON note_relationships.parent_id = notetree.id
	   -- And we want to make sure there are no cycles.  There shouldn't
	   -- be; we're supposed to prevent those.  But you never know.
	   WHERE
         notetree.cycle NOT LIKE '%,'||notes.id||',%'
	   ORDER BY note_relationships.position);

