xquery version "0.9-ml"
(:
 : SharePoint Connector - File upload manager API
 :
 : This API is used to assist the SharePoint API in keeping track of which
 : documents are in the process of being uploaded. This is necessary because
 : the SharePoint connector can issue multiple ItemUpdated events on a single
 : file which can cause it to be uploaded multiple times.
 :
 : The upload manager keeps track of which files have received upload requests
 : (i.e., SEND_CONTENT responses) and stores the URI and time of the request.
 : Subsequent interrogations of the URI will check the upload manager and will
 : cause the SEND_CONTENT request to become an OK. When the upload completes
 : and the SET_METADATA request is issued on the URI, the upload manager entry
 : for the URI is deleted. Upload manager entries will time-out and be deleted
 : after a specified upload wait duration (see defined variables). The optimum
 : value for this parameter is the time it takes to load a document with the
 : largest expected size. Thus, this value depends on document size and network
 : bandwidth and throughput.
 :
 : Copyright (c) 2002-2009 Mark Logic Corporation. All Rights Reserved.
 :)

module "http://marklogic.com/sharepoint/uploads"

declare namespace xh="http://www.w3.org/1999/xhtml"

default function namespace = "http://www.w3.org/2003/05/xpath-functions"

declare namespace mlsu = "http://marklogic.com/sharepoint/uploads"

define variable $mlsu:upload-dir-uri { "SharePointConnector/uploading" }
define variable $mlsu:upload-wait-duration { "PT60S" }


define function mlsu:uploads-reset()
{
  try {
    xdmp:directory-delete(concat($mlsu:upload-dir-uri, "/"))
  }
  catch ($e) {
    ()
  }
}

(: Insert a new document for $uri in the uploading directory. :)
define function mlsu:uploads-set(
  $uri as xs:string
) as empty()
{
  let $p := concat($mlsu:upload-dir-uri, "/", $uri)
  return
    if (not(exists(doc($p)))) then
      xdmp:document-insert($p, <uploading/>)
    else
      ()
}

(: Delete the document for $uri in the uploads directory :)
define function mlsu:uploads-unset(
  $uri as xs:string
) as empty()
{
  let $p := concat($mlsu:upload-dir-uri, "/", $uri)
  return
    try {
      xdmp:document-delete($p)
    }
    catch ($e) {
      ()
    }
}

(: Give a headstart of $mlsu:upload-wait-duration. When the headstart expires, delete the document. :)
define function mlsu:uploads-is-pending(
  $uri as xs:string
) as xs:boolean
{
  let $p := concat($mlsu:upload-dir-uri, "/", $uri)
  return
    if (not(exists(doc($p)))) then
      false()
    else
      let $d := current-dateTime() - doc($p)/property::prop:last-modified
      return
        if ($d < xdt:dayTimeDuration($mlsu:upload-wait-duration)) then
        (
          xdmp:trace("SPC requests", concat($uri, " upload pending")),
          true()
        )
        else
        (
          mlsu:uploads-unset($uri),
          false()
        )
}


