📄 xml.c
字号:
xmlschema = _SPI_strdup(map_sql_table_to_xmlschema(portal->tupDesc, InvalidOid, nulls, tableforest, targetns)); SPI_cursor_close(portal); SPI_finish(); PG_RETURN_XML_P(stringinfo_to_xmltype(query_to_xml_internal(query, NULL, xmlschema, nulls, tableforest, targetns, true)));}/* * Map SQL schema to XML and/or XML Schema document; see SQL/XML:2003 * section 9.4. */static StringInfoschema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level){ StringInfo result; char *xmlsn; List *relid_list; ListCell *cell; xmlsn = map_sql_identifier_to_xml_name(get_namespace_name(nspid), true, false); result = makeStringInfo(); xmldata_root_element_start(result, xmlsn, xmlschema, targetns, top_level); if (xmlschema) appendStringInfo(result, "%s\n\n", xmlschema); SPI_connect(); relid_list = schema_get_xml_visible_tables(nspid); SPI_push(); foreach(cell, relid_list) { Oid relid = lfirst_oid(cell); StringInfo subres; subres = table_to_xml_internal(relid, NULL, nulls, tableforest, targetns, false); appendStringInfoString(result, subres->data); appendStringInfoChar(result, '\n'); } SPI_pop(); SPI_finish(); xmldata_root_element_end(result, xmlsn); return result;}Datumschema_to_xml(PG_FUNCTION_ARGS){ Name name = PG_GETARG_NAME(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = _textout(PG_GETARG_TEXT_P(3)); char *schemaname; Oid nspid; schemaname = NameStr(*name); nspid = LookupExplicitNamespace(schemaname); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, NULL, nulls, tableforest, targetns, true)));}/* * Write the start element of the root element of an XML Schema mapping. */static voidxsd_schema_element_start(StringInfo result, const char *targetns){ appendStringInfoString(result, "<xsd:schema\n" " xmlns:xsd=\"" NAMESPACE_XSD "\""); if (strlen(targetns) > 0) appendStringInfo(result, "\n" " targetNamespace=\"%s\"\n" " elementFormDefault=\"qualified\"", targetns); appendStringInfoString(result, ">\n\n");}static voidxsd_schema_element_end(StringInfo result){ appendStringInfoString(result, "</xsd:schema>");}static StringInfoschema_to_xmlschema_internal(const char *schemaname, bool nulls, bool tableforest, const char *targetns){ Oid nspid; List *relid_list; List *tupdesc_list; ListCell *cell; StringInfo result; result = makeStringInfo(); nspid = LookupExplicitNamespace(schemaname); xsd_schema_element_start(result, targetns); SPI_connect(); relid_list = schema_get_xml_visible_tables(nspid); tupdesc_list = NIL; foreach(cell, relid_list) { Relation rel; rel = heap_open(lfirst_oid(cell), AccessShareLock); tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att)); heap_close(rel, NoLock); } appendStringInfoString(result, map_sql_typecoll_to_xmlschema_types(tupdesc_list)); appendStringInfoString(result, map_sql_schema_to_xmlschema_types(nspid, relid_list, nulls, tableforest, targetns)); xsd_schema_element_end(result); SPI_finish(); return result;}Datumschema_to_xmlschema(PG_FUNCTION_ARGS){ Name name = PG_GETARG_NAME(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = _textout(PG_GETARG_TEXT_P(3)); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xmlschema_internal(NameStr(*name), nulls, tableforest, targetns)));}Datumschema_to_xml_and_xmlschema(PG_FUNCTION_ARGS){ Name name = PG_GETARG_NAME(0); bool nulls = PG_GETARG_BOOL(1); bool tableforest = PG_GETARG_BOOL(2); const char *targetns = _textout(PG_GETARG_TEXT_P(3)); char *schemaname; Oid nspid; StringInfo xmlschema; schemaname = NameStr(*name); nspid = LookupExplicitNamespace(schemaname); xmlschema = schema_to_xmlschema_internal(schemaname, nulls, tableforest, targetns); PG_RETURN_XML_P(stringinfo_to_xmltype(schema_to_xml_internal(nspid, xmlschema->data, nulls, tableforest, targetns, true)));}/* * Map SQL database to XML and/or XML Schema document; see SQL/XML:2003 * section 9.5. */static StringInfodatabase_to_xml_internal(const char *xmlschema, bool nulls, bool tableforest, const char *targetns){ StringInfo result; List *nspid_list; ListCell *cell; char *xmlcn; xmlcn = map_sql_identifier_to_xml_name(get_database_name(MyDatabaseId), true, false); result = makeStringInfo(); xmldata_root_element_start(result, xmlcn, xmlschema, targetns, true); if (xmlschema) appendStringInfo(result, "%s\n\n", xmlschema); SPI_connect(); nspid_list = database_get_xml_visible_schemas(); SPI_push(); foreach(cell, nspid_list) { Oid nspid = lfirst_oid(cell); StringInfo subres; subres = schema_to_xml_internal(nspid, NULL, nulls, tableforest, targetns, false); appendStringInfoString(result, subres->data); appendStringInfoChar(result, '\n'); } SPI_pop(); SPI_finish(); xmldata_root_element_end(result, xmlcn); return result;}Datumdatabase_to_xml(PG_FUNCTION_ARGS){ bool nulls = PG_GETARG_BOOL(0); bool tableforest = PG_GETARG_BOOL(1); const char *targetns = _textout(PG_GETARG_TEXT_P(2)); PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xml_internal(NULL, nulls, tableforest, targetns)));}static StringInfodatabase_to_xmlschema_internal(bool nulls, bool tableforest, const char *targetns){ List *relid_list; List *nspid_list; List *tupdesc_list; ListCell *cell; StringInfo result; result = makeStringInfo(); xsd_schema_element_start(result, targetns); SPI_connect(); relid_list = database_get_xml_visible_tables(); nspid_list = database_get_xml_visible_schemas(); tupdesc_list = NIL; foreach(cell, relid_list) { Relation rel; rel = heap_open(lfirst_oid(cell), AccessShareLock); tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att)); heap_close(rel, NoLock); } appendStringInfoString(result, map_sql_typecoll_to_xmlschema_types(tupdesc_list)); appendStringInfoString(result, map_sql_catalog_to_xmlschema_types(nspid_list, nulls, tableforest, targetns)); xsd_schema_element_end(result); SPI_finish(); return result;}Datumdatabase_to_xmlschema(PG_FUNCTION_ARGS){ bool nulls = PG_GETARG_BOOL(0); bool tableforest = PG_GETARG_BOOL(1); const char *targetns = _textout(PG_GETARG_TEXT_P(2)); PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xmlschema_internal(nulls, tableforest, targetns)));}Datumdatabase_to_xml_and_xmlschema(PG_FUNCTION_ARGS){ bool nulls = PG_GETARG_BOOL(0); bool tableforest = PG_GETARG_BOOL(1); const char *targetns = _textout(PG_GETARG_TEXT_P(2)); StringInfo xmlschema; xmlschema = database_to_xmlschema_internal(nulls, tableforest, targetns); PG_RETURN_XML_P(stringinfo_to_xmltype(database_to_xml_internal(xmlschema->data, nulls, tableforest, targetns)));}/* * Map a multi-part SQL name to an XML name; see SQL/XML:2003 section * 9.2. */static char *map_multipart_sql_identifier_to_xml_name(char *a, char *b, char *c, char *d){ StringInfoData result; initStringInfo(&result); if (a) appendStringInfo(&result, "%s", map_sql_identifier_to_xml_name(a, true, true)); if (b) appendStringInfo(&result, ".%s", map_sql_identifier_to_xml_name(b, true, true)); if (c) appendStringInfo(&result, ".%s", map_sql_identifier_to_xml_name(c, true, true)); if (d) appendStringInfo(&result, ".%s", map_sql_identifier_to_xml_name(d, true, true)); return result.data;}/* * Map an SQL table to an XML Schema document; see SQL/XML:2003 * section 9.3. * * Map an SQL table to XML Schema data types; see SQL/XML:2003 section * 9.6. */static const char *map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns){ int i; char *xmltn; char *tabletypename; char *rowtypename; StringInfoData result; initStringInfo(&result); if (OidIsValid(relid)) { HeapTuple tuple; Form_pg_class reltuple; tuple = SearchSysCache(RELOID, ObjectIdGetDatum(relid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relid); reltuple = (Form_pg_class) GETSTRUCT(tuple); xmltn = map_sql_identifier_to_xml_name(NameStr(reltuple->relname), true, false); tabletypename = map_multipart_sql_identifier_to_xml_name("TableType", get_database_name(MyDatabaseId), get_namespace_name(reltuple->relnamespace), NameStr(reltuple->relname)); rowtypename = map_multipart_sql_identifier_to_xml_name("RowType", get_database_name(MyDatabaseId), get_namespace_name(reltuple->relnamespace), NameStr(reltuple->relname)); ReleaseSysCache(tuple); } else { if (tableforest) xmltn = "row"; else xmltn = "table"; tabletypename = "TableType"; rowtypename = "RowType"; } xsd_schema_element_start(&result, targetns); appendStringInfoString(&result, map_sql_typecoll_to_xmlschema_types(list_make1(tupdesc))); appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n" " <xsd:sequence>\n", rowtypename); for (i = 0; i < tupdesc->natts; i++) appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\"%s></xsd:element>\n", map_sql_identifier_to_xml_name(NameStr(tupdesc->attrs[i]->attname), true, false), map_sql_type_to_xml_name(tupdesc->attrs[i]->atttypid, -1), nulls ? " nillable=\"true\"" : " minOccurs=\"0\""); appendStringInfoString(&result, " </xsd:sequence>\n" "</xsd:complexType>\n\n"); if (!tableforest) { appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n" " <xsd:sequence>\n" " <xsd:element name=\"row\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n" " </xsd:sequence>\n" "</xsd:complexType>\n\n", tabletypename, rowtypename); appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmltn, tabletypename); } else appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmltn, rowtypename); xsd_schema_element_end(&result); return result.data;}/* * Map an SQL schema to XML Schema data types; see SQL/XML section * 9.7. */static const char *map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns){ char *dbname; char *nspname; char *xmlsn; char *schematypename; StringInfoData result; ListCell *cell; dbname = get_database_name(MyDatabaseId); nspname = get_namespace_name(nspid); initStringInfo(&result); xmlsn = map_sql_identifier_to_xml_name(nspname, true, false); schematypename = map_multipart_sql_identifier_to_xml_name("SchemaType", dbname, nspname, NULL); appendStringInfo(&result, "<xsd:complexType name=\"%s\">\n", schematypename); if (!tableforest) appendStringInfoString(&result, " <xsd:all>\n"); else appendStringInfoString(&result, " <xsd:sequence>\n"); foreach(cell, relid_list) { Oid relid = lfirst_oid(cell); char *relname = get_rel_name(relid); char *xmltn = map_sql_identifier_to_xml_name(relname, true, false); char *tabletypename = map_multipart_sql_identifier_to_xml_name(tableforest ? "RowType" : "TableType", dbname, nspname, relname); if (!tableforest) appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\"/>\n", xmltn, tabletypename); else appendStringInfo(&result, " <xsd:element name=\"%s\" type=\"%s\" minOccurs=\"0\" maxOccurs=\"unbounded\"/>\n", xmltn, tabletypename); } if (!tableforest) appendStringInfoString(&result, " </xsd:all>\n"); else appendStringInfoString(&result, " </xsd:sequence>\n"); appendStringInfoString(&result, "</xsd:complexType>\n\n"); appendStringInfo(&result, "<xsd:element name=\"%s\" type=\"%s\"/>\n\n", xmlsn, schematypename); return result.data;}/* * Map an SQL catalog to XML Schema data types; see SQL/XML section * 9.8. */static const char *map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns){ char *dbname; char *xmlcn; char *catalogtypename; StringInfoData result; ListCell *cell; dbname = get_database_name(MyDatabaseId); initStringInfo(&result); xmlcn = map_sql_identifier_to_xml_name(dbname, true, false); catalogtypename = map_multipart_sql_identifier_to_xml_name("Catalog
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -