def _iterGroups(ctx, container, serManager):
	"""yields GROUPs for the RD groups within container, taking params and
	fields from serManager's table.

	container can be a tableDef or a group.
	"""
	for group in container.groups:
		votGroup = V.GROUP(ucd=group.ucd, utype=group.utype, name=group.name)
		votGroup[V.DESCRIPTION[group.description]]

		for ref in group.columnRefs:
			votGroup[_makeRef(V.FIELDref, ref,
				serManager.table.tableDef, serManager)]

		for ref in group.paramRefs:
			votGroup[_makeRef(V.PARAMref, ref,
				serManager.table, serManager)]

		for param in group.params:
			votGroup[_makeVOTParam(ctx, param)]

		for subgroup in _iterGroups(ctx, group, serManager):
			votGroup[subgroup]

		yield votGroup
Ejemplo n.º 2
0
    def getVOT(self, ctx):
        # the main trouble here is: What if there's multiple foreign keys
        # into destTD?  To prevent multiple inclusions of a single
        # table, we add a reference to our serialised VOTable stan in
        # destTD's _FKR_serializedVOT attribute.  That will fail
        # if we produce two VOTables from the same table at the same time,
        # but let's worry about that later.

        destTD = self.value.inTable
        srcTD = self.value.parent

        pkDecl = V.GROUP[V.VODML[V.ROLE["vo-dml:ObjectTypeInstance.ID"]], [
            V.FIELDref(
                ref=ctx.getOrMakeIdFor(destTD.tableDef.getColumnByName(colName)
                                       )) for colName in self.foreignKey.dest
        ]]
        pkDecl(ID=ctx.getOrMakeIdFor(pkDecl))

        fkDecl = V.GROUP(ref=ctx.getOrMakeIdFor(pkDecl))[
            V.VODML[V.TYPE["vo-dml:ORMReference"]], [
                V.FIELDref(ref=ctx.getIdFor(srcTD.getColumnByName(colName)))
                for colName in self.foreignKey.source
            ]]

        targetVOT = getattr(destTD, "_FKR_serializedVOT", lambda: None)()
        # weakrefs are None if expired
        if targetVOT is None:
            targetVOT = ctx.makeTable(destTD)
            destTD._FKR_serializedVOT = weakref.ref(targetVOT)
            ctx.getEnclosingResource()[targetVOT]

        targetVOT[pkDecl]

        return fkDecl
Ejemplo n.º 3
0
    def getVOT(self, ctx):
        if id(self.objectReferenced) not in ctx.alreadyInTree:
            ctx.getEnclosingContainer(
            )[_the(  # fix this: dmvot.getSubtrees(ctx, self.objectReferenced))(
                ID=ctx.getOrMakeIdFor(self.objectReferenced))]
            ctx.alreadyInTree.add(id(self.objectReferenced))

        return V.GROUP(ref=ctx.getIdFor(self.objectReferenced))[
            V.VODML[V.TYPE["vo-dml:GROUPref"]],
            V.VODML[V.ROLE[common.completeVODMLId(ctx, self.name)]]]
    def asVOT(self, ctx, accessURL, linkIdTo=None):
        """returns VOTable stanxml for a description of this service.

		This is a RESOURCE as required by Datalink.

		linkIdTo is used to support data access descriptors embedded
		in descovery queries.  It is the id of the column containing
		the identifiers.  SSA can already provide this.  It ends up
		in a LINK child of the ID parameter.
		"""
        paramsByName, stcSpecs = {}, set()
        for param in self.inputKeys:
            paramsByName[param.name] = param
            if param.stc:
                stcSpecs.add(param.stc)

        def getIdFor(colRef):
            colRef.toParam = True
            return ctx.makeIdFor(paramsByName[colRef.dest])

        res = V.RESOURCE(
            ID=ctx.getOrMakeIdFor(self), type="meta", utype="adhoc:service")[
                [modelgroups.marshal_STC(ast, getIdFor) for ast in stcSpecs],
                V.PARAM(arraysize="*",
                        datatype="char",
                        name="accessURL",
                        ucd="meta.ref.url",
                        value=accessURL)]

        standardId = {
            "dlasync": "ivo://ivoa.net/std/SODA#async-1.0",
            "dlget": "ivo://ivoa.net/std/SODA#sync-1.0"
        }.get(self.rendName)
        if standardId:
            res[V.PARAM(arraysize="*",
                        datatype="char",
                        name="standardID",
                        value=standardId)]

        inputParams = V.GROUP(name="inputParams")
        res = res[inputParams]

        for ik in self.inputKeys:
            param = ctx.addID(
                ik, votablewrite.makeFieldFromColumn(ctx, V.PARAM, ik))
            if linkIdTo and ik.name == "ID":
                param = param(ref=linkIdTo)
            inputParams[param]

        return res
def _iterNotes(serManager):
	"""yields GROUPs for table notes.

	The idea is that the note is in the group's description, and the FIELDrefs
	give the columns that the note applies to.
	"""
	# add notes as a group with FIELDrefs, but don't fail on them
	for key, note in serManager.notes.iteritems():
		noteId = serManager.getOrMakeIdFor(note)
		noteGroup = V.GROUP(name="note-%s"%key, ID=noteId)[
			V.DESCRIPTION[note.getContent(targetFormat="text")]]
		for col in serManager:
			if col["note"] is note:
				noteGroup[V.FIELDref(ref=col["id"])]
		yield noteGroup
Ejemplo n.º 6
0
    def _run_queryData(self, service, inputTable, queryMeta):
        format = inputTable.getParam("FORMAT") or ""
        if format.lower() == "metadata":
            return self._makeMetadata(service)

        limits = [
            q for q in (inputTable.getParam("MAXREC", None),
                        inputTable.getParam("TOP")) if q
        ]
        if not limits:
            limits = [base.getConfig("ivoa", "dalDefaultLimit")]
        limit = min(min(limits), base.getConfig("ivoa", "dalHardLimit"))
        queryMeta["dbLimit"] = limit

        res = svcs.DBCore.run(self, service, inputTable, queryMeta)
        if len(res) == limit:
            queryStatus = "OVERFLOW"
            queryStatusBody = (
                "Exactly %s rows were returned.  This means your"
                " query probably reached the match limit.  Increase MAXREC." %
                limit)
        else:
            queryStatus = "OK"
            queryStatusBody = ""

        self._addPreviewLinks(res)

        # We wrap our result into a data instance since we need to set the
        #	result type
        data = rsc.wrapTable(res)
        data.setMeta("_type", "results")
        data.addMeta("_votableRootAttributes",
                     'xmlns:ssa="http://www.ivoa.net/xml/DalSsap/v1.0"')

        # The returnRaw property is a hack, mainly for unit testing;
        # The renderer would have to add the QUERY_STATUS here.
        if service.getProperty("returnData", False):
            return data

        # we fix tablecoding to td for now since nobody seems to like
        # binary tables and we don't have huge tables here.
        votCtx = votablewrite.VOTableContext(tablecoding="td")

        vot = votablewrite.makeVOTable(data, votCtx)
        pubDIDId = votCtx.getIdFor(res.tableDef.getColumnByName("ssa_pubDID"))
        resElement = vot.getChildDict()["RESOURCE"][0]
        resElement[
            V.INFO(name="SERVICE_PROTOCOL", value=self.ssapVersion)["SSAP"],
            V.INFO(name="QUERY_STATUS", value=queryStatus)[queryStatusBody]]

        datalinkId = service.getProperty("datalink", None)
        if datalinkId and res:
            dlService = self.rd.getById(datalinkId)
            dlCore = getDatalinkCore(dlService, res)

            # new and shiny datalink (keep)
            # (we're just using endpoint 0; it should a the sync service)
            dlEndpoint = dlCore.datalinkEndpoints[0]
            vot[dlEndpoint.asVOT(votCtx,
                                 dlService.getURL(dlEndpoint.rendName),
                                 linkIdTo=pubDIDId)]

            # Also point to the dl metadata service
            vot[V.RESOURCE(type="meta", utype="adhoc:service")[
                V.PARAM(name="standardID",
                        datatype="char",
                        arraysize="*",
                        value="ivo://ivoa.net/std/DataLink#links-1.0"),
                V.PARAM(name="accessURL",
                        datatype="char",
                        arraysize="*",
                        value=self.rd.getById(datalinkId).getURL("dlmeta")),
                V.GROUP(name="inputParams")[V.PARAM(
                    name="ID",
                    datatype="char",
                    arraysize="*",
                    ref=pubDIDId,
                    ucd="meta.id;meta.main"
                )[V.LINK(content_role="ddl:id-source", value="#" +
                         pubDIDId)]]]]

        return "application/x-votable+xml", votable.asString(vot)