Bläddra i källkod

exported Storage xsd

Piotr Labudda 8 år sedan
förälder
incheckning
95f72f1466
3 ändrade filer med 287 tillägg och 282 borttagningar
  1. 2 279
      SE/se-lib/Route/Storage.php
  2. 1 3
      SE/se-lib/Route/Storage/AclStruct.php
  3. 284 0
      SE/se-lib/Route/Storage/TestXsd.php

+ 2 - 279
SE/se-lib/Route/Storage.php

@@ -60,7 +60,7 @@ class Route_Storage extends RouteBase {
 							'config?' => ($item['hasConfig']) ? '<span class="label label-success">TAK</span>' : '<span class="text text-muted">brak</span>',
 							'obiekty' => UI::h('a', [ 'href' => $this->getLink('tableList', [ 'idStorage' => $item['idZasob'] ]) ], "obiekty"),
 							'raw info' => UI::h('a', [ 'href' => $this->getLink('rawInfo', [ 'idStorage' => $item['idZasob'] ]) ], "raw info"),
-							'xsd' => UI::h('a', [ 'href' => $this->getLink('xsd', [ 'idStorage' => $item['idZasob'] ]) ], "xsd"),
+							'xsd' => UI::h('a', [ 'href' => Router::getRoute('Storage_TestXsd')->getLink('', [ 'idStorage' => $item['idZasob'] ]) ], "xsd"),
 						];
 					}, $sourceStorage->getItems())
 					, [
@@ -224,7 +224,7 @@ class Route_Storage extends RouteBase {
 								UI::h('a', [ 'href' => $this->getLink('rawInfo', [ 'idStorage' => $idStorage, 'table' => $item['name'] ]) ], "raw info"),
 								UI::h('a', [ 'href' => Router::getRoute('ViewTableAjax')->getLink('', ['namespace' => $item['namespace']]) ], "view table"),
 								UI::h('a', [ 'href' => Router::getRoute('ViewObject')->getLink('', ['namespace' => $item['namespace']]) ], "view object"),
-								// 'xsd' => UI::h('a', [ 'href' => $this->getLink('xsd', [ 'idStorage' => $idStorage ]) ], "xsd"),
+								// 'xsd' => UI::h('a', [ 'href' => Router::getRoute('Storage_TestXsd')->getLink('', [ 'idStorage' => $idStorage ]) ], "xsd"),
 								UI::h('a', [ 'href' => "wfs-data.php/default_db/?SERVICE=WFS&VERSION=1.0.0&SRSNAME=EPSG:3003&REQUEST=DescribeFeatureType&TYPENAME={$typeName}" ], "wfs DescribeFeatureType"),
 								UI::h('a', [ 'href' => "wfs-data.php/default_db/?SERVICE=WFS&VERSION=1.0.0&SRSNAME=EPSG:3003&REQUEST=DescribeFeatureTypeAdvanced&TYPENAME={$typeName}" ], "wfs DescribeFeatureTypeAdvanced"),
 								UI::h('a', [ 'href' => "wfs-data.php/default_db/?SERVICE=WFS&VERSION=1.0.0&SRSNAME=EPSG:3003&REQUEST=GetFeature&TYPENAME={$typeName}&MAXFEATURES=10" ], "wfs GetFeature (max: 10)"),
@@ -531,283 +531,6 @@ class Route_Storage extends RouteBase {
 		return $return;
 	}
 
-	public function xsdAction() {
-		$idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
-		$storage = DB::getStorage($idStorage);
-		$tableRealList = $storage->getTableList();
-		$srvName = $_SERVER['SERVER_NAME'];
-		$storageZasobId = $storage->getZasobId();
-		$objNs = "p5_{$storageZasobId}_{$tblName}";
-		$objNsUri = "https://biuro.biall-net.pl/api/{$storageZasobId}/{$tblName}";
-		$p5TypePrefix = "p5Type";
-		$p5TypeNsUri = "http://biuro.biall-net.pl/p5/schema/types";
-		$p5TypeNsLocation = "http://biuro.biall-net.pl/p5/schema/types.xsd";
-		header('Content-type: text/plain; charset=utf-8');// TODO: test
-
-		//header('Content-type: application/xml; charset=utf-8');
-		$xmlWriter = new XMLWriter();
-		$xmlWriter->openUri('php://output');
-		$xmlWriter->setIndent(true);
-		if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
-		$xmlWriter->startDocument('1.0', 'UTF-8');
-		$xmlWriter->startElement('xs:schema');
-		$xmlWriter->writeAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
-		$xmlWriter->writeAttribute('xmlns:vc', 'http://www.w3.org/2007/XMLSchema-versioning');
-		$xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
-		$xmlWriter->writeAttribute('elementFormDefault', 'qualified');
-		$xmlWriter->writeAttribute('targetNamespace', $objNsUri);
-		$xmlWriter->writeAttribute('vc:minVersion', '1.1');
-
-		$xmlWriter->startElement('xs:import');
-		$xmlWriter->writeAttribute('namespace', $p5TypeNsUri);
-		$xmlWriter->writeAttribute('schemaLocation', $p5TypeNsLocation);
-		$xmlWriter->endElement();// xs:import
-
-		foreach ($tableRealList as $tbl) {
-			$tblName = $tbl['table_name'];
-			$this->tableXsdViewXmlWriter($xmlWriter, $idStorage, $tblName);
-		}
-
-		$xmlWriter->endElement();// xs:schema
-		$xmlWriter->endDocument();
-	}
-
-	public function tableXsdAction() {
-		$idStorage = V::get('idStorage', '', $_GET);
-		$tblName = V::get('table', '', $_GET, 'word');
-		if (empty($tblName)) die("Wrong table name");
-		header('Content-type: text/plain; charset=utf-8');// TODO: test
-
-		$storage = DB::getStorage($idStorage);
-		$storageZasobId = $storage->getZasobId();
-		$objNs = "p5_{$storageZasobId}_{$tblName}";
-		$objNsUri = "https://biuro.biall-net.pl/api/{$storageZasobId}/{$tblName}";
-		$p5TypePrefix = "p5Type";
-		$p5TypeNsUri = "http://biuro.biall-net.pl/p5/schema/types";
-		$p5TypeNsLocation = "http://biuro.biall-net.pl/p5/schema/types.xsd";
-
-		//header('Content-type: application/xml; charset=utf-8');
-		$xmlWriter = new XMLWriter();
-		$xmlWriter->openUri('php://output');
-		$xmlWriter->setIndent(true);
-		if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
-		$xmlWriter->startDocument('1.0', 'UTF-8');
-		$xmlWriter->startElement('xs:schema');
-		$xmlWriter->writeAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
-		$xmlWriter->writeAttribute('xmlns:vc', 'http://www.w3.org/2007/XMLSchema-versioning');
-		$xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
-		$xmlWriter->writeAttribute('elementFormDefault', 'qualified');
-		$xmlWriter->writeAttribute('targetNamespace', $objNsUri);
-		$xmlWriter->writeAttribute('vc:minVersion', '1.1');
-
-		$xmlWriter->startElement('xs:import');
-		$xmlWriter->writeAttribute('namespace', $p5TypeNsUri);
-		$xmlWriter->writeAttribute('schemaLocation', $p5TypeNsLocation);
-		$xmlWriter->endElement();// xs:import
-		$this->tableXsdViewXmlWriter($xmlWriter, $idStorage, $tblName);
-		$xmlWriter->endElement();// xs:schema
-		$xmlWriter->endDocument();
-	}
-
-	public function tableXsdViewXmlWriter(&$xmlWriter, $idStorage, $tblName) {
-		$storage = DB::getStorage($idStorage);
-		$schema = Schema_TableFactory::build($tblName, $idStorage, $_SERVER['SERVER_NAME']);
-		$struct = $schema->getStruct();
-		DBG::_('DBG', '>1', "struct", $struct, __CLASS__, __FUNCTION__, __LINE__);
-
-		$typeName = "{$tblName}Type";
-
-		$xmlWriter->startElement('xs:complexType');
-		$xmlWriter->writeAttribute('name', $typeName);
-		$xmlWriter->startElement('xs:sequence');
-
-		$foreignKeys = [];
-		{
-			$dbName = DB::getPDO($idStorage)->getDatabaseName();
-			if ('mysql' === DB::getPDO($idStorage)->getType()) {
-				$foreignKeys = DB::getPDO($idStorage)->fetchAll("
-					SELECT i.TABLE_SCHEMA, i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME
-					FROM information_schema.TABLE_CONSTRAINTS i
-					LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
-					WHERE i.TABLE_SCHEMA = :db_name
-						and i.TABLE_NAME = :tbl_name
-						and i.CONSTRAINT_TYPE = 'FOREIGN KEY'
-					ORDER BY i.TABLE_NAME
-				", [
-					':db_name' => $dbName,
-					':tbl_name' => $tblName,
-				]);
-				// if ('CRM_WSKAZNIK' === $tblName) { // @example: CRM_WSKAZNIK.ID_ZASOB => CRM_LISTA_ZASOBOW.ID
-				// 	$foreignKeys = [
-				// 		[	'TABLE_SCHEMA' => "SES_USERS2"
-				// 		,	'TABLE_NAME' => "CRM_WSKAZNIK"
-				// 		,	'CONSTRAINT_TYPE' => "FOREIGN KEY"
-				// 		,	'CONSTRAINT_NAME' => "zasob"
-				// 		,	'COLUMN_NAME' => "ID_ZASOB"
-				// 		,	'REFERENCED_TABLE_NAME' => "CRM_LISTA_ZASOBOW"
-				// 		,	'REFERENCED_COLUMN_NAME' => "ID"
-				// 		]
-				// 	];
-				// }
-				// $xmlWriter->writeComment("\$foreignKeys: " . var_export($foreignKeys, true));
-				// TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
-				// *	*	FOREIGN KEY	*	*	*	*
-			}
-		}
-
-		foreach ($struct as $field) {
-			$xmlWriter->startElement('xs:element');
-			$xmlWriter->writeAttribute('name', $field['name']);
-			$xmlWriter->writeAttribute('minOccurs', 0);// TODO: set minOccurs by default, etc.
-			if ($field['is_nullable']) $xmlWriter->writeAttribute('nillable', 'true');
-			if (null !== $field['default_value']) {
-				$xmlWriter->writeAttribute('default', $field['default_value']);
-			} else if (null === $field['default_value'] && $field['is_nullable']) {
-				$xmlWriter->writeAttribute('default', $field['default_value']);
-			} else {
-				// TODO: Schema BUG?
-			}
-
-			if (empty($field['p5_restrictions'])) {
-				$xmlWriter->writeAttribute('type', "p5Type:{$field['p5_type']}");
-			} else {
-				$xmlWriter->startElement('xs:simpleType');
-				$xmlWriter->writeAttribute('base', "p5Type:{$field['p5_type']}");
-				$xmlWriter->startElement('xs:restriction');
-				if (!empty($field['p5_restrictions']['enumeration'])) {
-					foreach ($field['p5_restrictions']['enumeration'] as $enumValue) {
-						$xmlWriter->startElement('xs:enumeration');
-						$xmlWriter->writeAttribute('value', $enumValue);
-						$xmlWriter->endElement();// xs:enumeration
-					}
-				} else {
-					// TODO: another restrictions...
-				}
-				$xmlWriter->endElement();// xs:restriction
-				$xmlWriter->endElement();// xs:simpleType
-			}
-			$xmlWriter->endElement();// xs:element
-		}
-		if (!empty($foreignKeys)) {
-			foreach ($foreignKeys as $key) {
-				$xmlWriter->startElement('xs:element');
-				$refPrefix = (DB::getPDO()->getZasobId() === $idStorage) ? 'p5_default_db' : "p5_zasob_{$idStorage}";
-				$xmlWriter->writeAttribute('ref', "{$refPrefix}:{$key['REFERENCED_TABLE_NAME']}");
-					$xmlWriter->startElement('xs:annotation');
-						$xmlWriter->startElement('xs:appinfo');
-							$xmlWriter->startElement('system_cache__appinfo:flat_relation_cache');
-							$xmlWriter->writeAttribute("system_cache__appinfo:name", $key['COLUMN_NAME']);
-							$xmlWriter->writeAttribute("system_cache__appinfo:xpath", "{$refPrefix}:{$key['REFERENCED_TABLE_NAME']}/{$key['REFERENCED_COLUMN_NAME']}");
-							$xmlWriter->endElement();// system_cache__appinfo:flat_relation_cache
-						$xmlWriter->endElement();// xs:appinfo
-					$xmlWriter->endElement();// xs:annotation
-				$xmlWriter->endElement();// xs:element
-			}
-		}
-		$xmlWriter->endElement();// xs:sequence
-		$xmlWriter->endElement();// xs:complexType
-		return;
-
-		// <xs:element maxOccurs="1" minOccurs="0" name="{$fldName}" nillable="true" type="xs:integer"/>
-		$pKeyField = 'ID';//$storageObject->getPrimaryKeyFieldName();
-		//DBG::_(true, true, "struct", $struct, __CLASS__, __FUNCTION__, __LINE__);
-		foreach ($struct as $field) {
-			$fldName = $vField->getName();
-			$fldType = $vField->getType();
-			$xsdType = $fldType->getTypeForXsd();
-
-			if ($fldType->hasDefault()) {
-				$fldDefault = $fldType->getDefault();
-				if (!empty($fldDefault) || '0' === $fldDefault) {
-					$elNode->setAttribute('default', $fldDefault);
-				}
-			}
-
-			$fldRestrictions = $fldType->getRestrictions();
-			if (empty($fldRestrictions)) {
-				$elNode->setAttribute('type', "{$p5TypePrefix}:{$xsdType}");
-			} else {
-				$sType = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:simpleType');
-				$elNode->appendChild($sType);
-				$sTypeRes = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:restriction');
-				$sType->appendChild($sTypeRes);
-				$sTypeRes->setAttribute('base', "{$p5TypePrefix}:{$xsdType}");
-
-				$enumList = $fldType->getEnumeration();
-				if (empty($enumList)) {
-					foreach ($fldRestrictions as $restricionName => $restrictionValue) {
-						if ('maxLength' == $restricionName) {
-							$sTypeResMaxLength = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxLength');
-							$sTypeRes->appendChild($sTypeResMaxLength);
-							$sTypeResMaxLength->setAttribute('value', $restrictionValue);
-						} else if ('minLength' == $restricionName) {
-							$sTypeResMinLength = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minLength');
-							$sTypeRes->appendChild($sTypeResMinLength);
-							$sTypeResMinLength->setAttribute('value', $restrictionValue);
-						} else if ('pattern' == $restricionName) {
-							$sTypeResPattern = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:pattern');
-							$sTypeRes->appendChild($sTypeResPattern);
-							$sTypeResPattern->setAttribute('value', $restrictionValue);
-						} else if ('fractionDigits' == $restricionName) {
-							$sTypeResFractionDigits = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:fractionDigits');
-							$sTypeRes->appendChild($sTypeResFractionDigits);
-							$sTypeResFractionDigits->setAttribute('value', $restrictionValue);
-						} else if ('totalDigits' == $restricionName) {
-							$sTypeResTotalDigits = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:totalDigits');
-							$sTypeRes->appendChild($sTypeResTotalDigits);
-							$sTypeResTotalDigits->setAttribute('value', $restrictionValue);
-						} else if ('maxExclusive' == $restricionName) {
-							$sTypeResMaxExclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxExclusive');
-							$sTypeRes->appendChild($sTypeResMaxExclusive);
-							$sTypeResMaxExclusive->setAttribute('value', $restrictionValue);
-						} else if ('minExclusive' == $restricionName) {
-							$sTypeResMinExclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minExclusive');
-							$sTypeRes->appendChild($sTypeResMinExclusive);
-							$sTypeResMinExclusive->setAttribute('value', $restrictionValue);
-						} else if ('maxInclusive' == $restricionName) {
-							$sTypeResMaxInclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxInclusive');
-							$sTypeRes->appendChild($sTypeResMaxInclusive);
-							$sTypeResMaxInclusive->setAttribute('value', $restrictionValue);
-						} else if ('minInclusive' == $restricionName) {
-							$sTypeResMinInclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minInclusive');
-							$sTypeRes->appendChild($sTypeResMinInclusive);
-							$sTypeResMinInclusive->setAttribute('value', $restrictionValue);
-						}
-						/* TODO: xsd restrictions:
-							enumeration	Defines a list of acceptable values
-							fractionDigits	Specifies the maximum number of decimal places allowed. Must be equal to or greater than zero
-							length	Specifies the exact number of characters or list items allowed. Must be equal to or greater than zero
-							maxExclusive	Specifies the upper bounds for numeric values (the value must be less than this value)
-							maxInclusive	Specifies the upper bounds for numeric values (the value must be less than or equal to this value)
-							maxLength	Specifies the maximum number of characters or list items allowed. Must be equal to or greater than zero
-							minExclusive	Specifies the lower bounds for numeric values (the value must be greater than this value)
-							minInclusive	Specifies the lower bounds for numeric values (the value must be greater than or equal to this value)
-							minLength	Specifies the minimum number of characters or list items allowed. Must be equal to or greater than zero
-							pattern	Defines the exact sequence of characters that are acceptable
-							totalDigits	Specifies the exact number of digits allowed. Must be greater than zero
-							whiteSpace	Specifies how white space (line feeds, tabs, spaces, and carriage returns) is handled
-						*/
-					}
-				} else {
-					foreach ($enumList as $enumValue) {
-						$sTypeResEnum = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:enumeration');
-						$sTypeRes->appendChild($sTypeResEnum);
-						$sTypeResEnum->setAttribute('value', $enumValue);
-					}
-				}
-			}
-		}
-
-		$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:element');
-		$rootNode->appendChild($elNode);
-		$elNode->setAttribute('name', $tblName);
-		$elNode->setAttribute('type', "{$objNs}:{$typeName}");
-
-		header('Content-type: application/xml');
-		echo $dom->saveXML();
-		exit;
-	}
-
 	public function navView() {
 		$backLabel = 'back';
 		$backLink = 'index.php?_route=Storage';

+ 1 - 3
SE/se-lib/Route/Storage/AclStruct.php

@@ -231,9 +231,7 @@ class Route_Storage_AclStruct extends RouteBase {
 					'title' => "Uprawnienia - analiza użycia komórek w procesach"
 				], "Uprawnienia (analiza użycia)"),
 				UI::h('a', [
-					// $idStorage = V::get('idStorage', '', $_GET);
-					// $tblName = V::get('table', '', $_GET, 'word');
-					'href' => Router::getRoute('Storage')->getLink('tableXsd', [ 'idStorage' => $idStorage, 'table' => "{$tblName}" ]),
+					'href' => Router::getRoute('Storage_TestXsd')->getLink('tableXsd', [ 'idStorage' => $idStorage, 'table' => "{$tblName}" ]),
 					'class' => "btn btn-md btn-link",
 				], "xsd"),
 			]),

+ 284 - 0
SE/se-lib/Route/Storage/TestXsd.php

@@ -0,0 +1,284 @@
+<?php
+
+Lib::loadClass('RouteBase');
+
+class Route_Storage_TestXsd extends RouteBase {
+
+	public function defaultAction() {
+		$idStorage = V::get('idStorage', 0, $_REQUEST, 'int');
+		$storage = DB::getStorage($idStorage);
+		$tableRealList = $storage->getTableList();
+		$srvName = $_SERVER['SERVER_NAME'];
+		$storageZasobId = $storage->getZasobId();
+		$objNs = "p5_{$storageZasobId}_{$tblName}";
+		$objNsUri = "https://biuro.biall-net.pl/api/{$storageZasobId}/{$tblName}";
+		$p5TypePrefix = "p5Type";
+		$p5TypeNsUri = "http://biuro.biall-net.pl/p5/schema/types";
+		$p5TypeNsLocation = "http://biuro.biall-net.pl/p5/schema/types.xsd";
+		header('Content-type: text/plain; charset=utf-8');// TODO: test
+
+		//header('Content-type: application/xml; charset=utf-8');
+		$xmlWriter = new XMLWriter();
+		$xmlWriter->openUri('php://output');
+		$xmlWriter->setIndent(true);
+		if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
+		$xmlWriter->startDocument('1.0', 'UTF-8');
+		$xmlWriter->startElement('xs:schema');
+		$xmlWriter->writeAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
+		$xmlWriter->writeAttribute('xmlns:vc', 'http://www.w3.org/2007/XMLSchema-versioning');
+		$xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
+		$xmlWriter->writeAttribute('elementFormDefault', 'qualified');
+		$xmlWriter->writeAttribute('targetNamespace', $objNsUri);
+		$xmlWriter->writeAttribute('vc:minVersion', '1.1');
+
+		$xmlWriter->startElement('xs:import');
+		$xmlWriter->writeAttribute('namespace', $p5TypeNsUri);
+		$xmlWriter->writeAttribute('schemaLocation', $p5TypeNsLocation);
+		$xmlWriter->endElement();// xs:import
+
+		foreach ($tableRealList as $tbl) {
+			$tblName = $tbl['table_name'];
+			$this->tableXsdViewXmlWriter($xmlWriter, $idStorage, $tblName);
+		}
+
+		$xmlWriter->endElement();// xs:schema
+		$xmlWriter->endDocument();
+	}
+
+	public function tableXsdAction() {
+		$idStorage = V::get('idStorage', '', $_GET);
+		$tblName = V::get('table', '', $_GET, 'word');
+		if (empty($tblName)) die("Wrong table name");
+		header('Content-type: text/plain; charset=utf-8');// TODO: test
+
+		$storage = DB::getStorage($idStorage);
+		$storageZasobId = $storage->getZasobId();
+		$objNs = "p5_{$storageZasobId}_{$tblName}";
+		$objNsUri = "https://biuro.biall-net.pl/api/{$storageZasobId}/{$tblName}";
+		$p5TypePrefix = "p5Type";
+		$p5TypeNsUri = "http://biuro.biall-net.pl/p5/schema/types";
+		$p5TypeNsLocation = "http://biuro.biall-net.pl/p5/schema/types.xsd";
+
+		//header('Content-type: application/xml; charset=utf-8');
+		$xmlWriter = new XMLWriter();
+		$xmlWriter->openUri('php://output');
+		$xmlWriter->setIndent(true);
+		if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404);
+		$xmlWriter->startDocument('1.0', 'UTF-8');
+		$xmlWriter->startElement('xs:schema');
+		$xmlWriter->writeAttribute('xmlns:xs', 'http://www.w3.org/2001/XMLSchema');
+		$xmlWriter->writeAttribute('xmlns:vc', 'http://www.w3.org/2007/XMLSchema-versioning');
+		$xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
+		$xmlWriter->writeAttribute('elementFormDefault', 'qualified');
+		$xmlWriter->writeAttribute('targetNamespace', $objNsUri);
+		$xmlWriter->writeAttribute('vc:minVersion', '1.1');
+
+		$xmlWriter->startElement('xs:import');
+		$xmlWriter->writeAttribute('namespace', $p5TypeNsUri);
+		$xmlWriter->writeAttribute('schemaLocation', $p5TypeNsLocation);
+		$xmlWriter->endElement();// xs:import
+		$this->tableXsdViewXmlWriter($xmlWriter, $idStorage, $tblName);
+		$xmlWriter->endElement();// xs:schema
+		$xmlWriter->endDocument();
+	}
+
+	public function tableXsdViewXmlWriter(&$xmlWriter, $idStorage, $tblName) {
+		$storage = DB::getStorage($idStorage);
+		$schema = Schema_TableFactory::build($tblName, $idStorage, $_SERVER['SERVER_NAME']);
+		$struct = $schema->getStruct();
+		DBG::_('DBG', '>1', "struct", $struct, __CLASS__, __FUNCTION__, __LINE__);
+
+		$typeName = "{$tblName}Type";
+
+		$xmlWriter->startElement('xs:complexType');
+		$xmlWriter->writeAttribute('name', $typeName);
+		$xmlWriter->startElement('xs:sequence');
+
+		$foreignKeys = [];
+		{
+			$dbName = DB::getPDO($idStorage)->getDatabaseName();
+			if ('mysql' === DB::getPDO($idStorage)->getType()) {
+				$foreignKeys = DB::getPDO($idStorage)->fetchAll("
+					SELECT i.TABLE_SCHEMA, i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME
+					FROM information_schema.TABLE_CONSTRAINTS i
+					LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
+					WHERE i.TABLE_SCHEMA = :db_name
+						and i.TABLE_NAME = :tbl_name
+						and i.CONSTRAINT_TYPE = 'FOREIGN KEY'
+					ORDER BY i.TABLE_NAME
+				", [
+					':db_name' => $dbName,
+					':tbl_name' => $tblName,
+				]);
+				// if ('CRM_WSKAZNIK' === $tblName) { // @example: CRM_WSKAZNIK.ID_ZASOB => CRM_LISTA_ZASOBOW.ID
+				// 	$foreignKeys = [
+				// 		[	'TABLE_SCHEMA' => "SES_USERS2"
+				// 		,	'TABLE_NAME' => "CRM_WSKAZNIK"
+				// 		,	'CONSTRAINT_TYPE' => "FOREIGN KEY"
+				// 		,	'CONSTRAINT_NAME' => "zasob"
+				// 		,	'COLUMN_NAME' => "ID_ZASOB"
+				// 		,	'REFERENCED_TABLE_NAME' => "CRM_LISTA_ZASOBOW"
+				// 		,	'REFERENCED_COLUMN_NAME' => "ID"
+				// 		]
+				// 	];
+				// }
+				// $xmlWriter->writeComment("\$foreignKeys: " . var_export($foreignKeys, true));
+				// TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE, CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
+				// *	*	FOREIGN KEY	*	*	*	*
+			}
+		}
+
+		foreach ($struct as $field) {
+			$xmlWriter->startElement('xs:element');
+			$xmlWriter->writeAttribute('name', $field['name']);
+			$xmlWriter->writeAttribute('minOccurs', 0);// TODO: set minOccurs by default, etc.
+			if ($field['is_nullable']) $xmlWriter->writeAttribute('nillable', 'true');
+			if (null !== $field['default_value']) {
+				$xmlWriter->writeAttribute('default', $field['default_value']);
+			} else if (null === $field['default_value'] && $field['is_nullable']) {
+				$xmlWriter->writeAttribute('default', $field['default_value']);
+			} else {
+				// TODO: Schema BUG?
+			}
+
+			if (empty($field['p5_restrictions'])) {
+				$xmlWriter->writeAttribute('type', "p5Type:{$field['p5_type']}");
+			} else {
+				$xmlWriter->startElement('xs:simpleType');
+				$xmlWriter->writeAttribute('base', "p5Type:{$field['p5_type']}");
+				$xmlWriter->startElement('xs:restriction');
+				if (!empty($field['p5_restrictions']['enumeration'])) {
+					foreach ($field['p5_restrictions']['enumeration'] as $enumValue) {
+						$xmlWriter->startElement('xs:enumeration');
+						$xmlWriter->writeAttribute('value', $enumValue);
+						$xmlWriter->endElement();// xs:enumeration
+					}
+				} else {
+					// TODO: another restrictions...
+				}
+				$xmlWriter->endElement();// xs:restriction
+				$xmlWriter->endElement();// xs:simpleType
+			}
+			$xmlWriter->endElement();// xs:element
+		}
+		if (!empty($foreignKeys)) {
+			foreach ($foreignKeys as $key) {
+				$xmlWriter->startElement('xs:element');
+				$refPrefix = (DB::getPDO()->getZasobId() === $idStorage) ? 'p5_default_db' : "p5_zasob_{$idStorage}";
+				$xmlWriter->writeAttribute('ref', "{$refPrefix}:{$key['REFERENCED_TABLE_NAME']}");
+					$xmlWriter->startElement('xs:annotation');
+						$xmlWriter->startElement('xs:appinfo');
+							$xmlWriter->startElement('system_cache__appinfo:flat_relation_cache');
+							$xmlWriter->writeAttribute("system_cache__appinfo:name", $key['COLUMN_NAME']);
+							$xmlWriter->writeAttribute("system_cache__appinfo:xpath", "{$refPrefix}:{$key['REFERENCED_TABLE_NAME']}/{$key['REFERENCED_COLUMN_NAME']}");
+							$xmlWriter->endElement();// system_cache__appinfo:flat_relation_cache
+						$xmlWriter->endElement();// xs:appinfo
+					$xmlWriter->endElement();// xs:annotation
+				$xmlWriter->endElement();// xs:element
+			}
+		}
+		$xmlWriter->endElement();// xs:sequence
+		$xmlWriter->endElement();// xs:complexType
+		return;
+
+		// <xs:element maxOccurs="1" minOccurs="0" name="{$fldName}" nillable="true" type="xs:integer"/>
+		$pKeyField = 'ID';//$storageObject->getPrimaryKeyFieldName();
+		//DBG::_(true, true, "struct", $struct, __CLASS__, __FUNCTION__, __LINE__);
+		foreach ($struct as $field) {
+			$fldName = $vField->getName();
+			$fldType = $vField->getType();
+			$xsdType = $fldType->getTypeForXsd();
+
+			if ($fldType->hasDefault()) {
+				$fldDefault = $fldType->getDefault();
+				if (!empty($fldDefault) || '0' === $fldDefault) {
+					$elNode->setAttribute('default', $fldDefault);
+				}
+			}
+
+			$fldRestrictions = $fldType->getRestrictions();
+			if (empty($fldRestrictions)) {
+				$elNode->setAttribute('type', "{$p5TypePrefix}:{$xsdType}");
+			} else {
+				$sType = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:simpleType');
+				$elNode->appendChild($sType);
+				$sTypeRes = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:restriction');
+				$sType->appendChild($sTypeRes);
+				$sTypeRes->setAttribute('base', "{$p5TypePrefix}:{$xsdType}");
+
+				$enumList = $fldType->getEnumeration();
+				if (empty($enumList)) {
+					foreach ($fldRestrictions as $restricionName => $restrictionValue) {
+						if ('maxLength' == $restricionName) {
+							$sTypeResMaxLength = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxLength');
+							$sTypeRes->appendChild($sTypeResMaxLength);
+							$sTypeResMaxLength->setAttribute('value', $restrictionValue);
+						} else if ('minLength' == $restricionName) {
+							$sTypeResMinLength = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minLength');
+							$sTypeRes->appendChild($sTypeResMinLength);
+							$sTypeResMinLength->setAttribute('value', $restrictionValue);
+						} else if ('pattern' == $restricionName) {
+							$sTypeResPattern = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:pattern');
+							$sTypeRes->appendChild($sTypeResPattern);
+							$sTypeResPattern->setAttribute('value', $restrictionValue);
+						} else if ('fractionDigits' == $restricionName) {
+							$sTypeResFractionDigits = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:fractionDigits');
+							$sTypeRes->appendChild($sTypeResFractionDigits);
+							$sTypeResFractionDigits->setAttribute('value', $restrictionValue);
+						} else if ('totalDigits' == $restricionName) {
+							$sTypeResTotalDigits = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:totalDigits');
+							$sTypeRes->appendChild($sTypeResTotalDigits);
+							$sTypeResTotalDigits->setAttribute('value', $restrictionValue);
+						} else if ('maxExclusive' == $restricionName) {
+							$sTypeResMaxExclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxExclusive');
+							$sTypeRes->appendChild($sTypeResMaxExclusive);
+							$sTypeResMaxExclusive->setAttribute('value', $restrictionValue);
+						} else if ('minExclusive' == $restricionName) {
+							$sTypeResMinExclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minExclusive');
+							$sTypeRes->appendChild($sTypeResMinExclusive);
+							$sTypeResMinExclusive->setAttribute('value', $restrictionValue);
+						} else if ('maxInclusive' == $restricionName) {
+							$sTypeResMaxInclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:maxInclusive');
+							$sTypeRes->appendChild($sTypeResMaxInclusive);
+							$sTypeResMaxInclusive->setAttribute('value', $restrictionValue);
+						} else if ('minInclusive' == $restricionName) {
+							$sTypeResMinInclusive = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:minInclusive');
+							$sTypeRes->appendChild($sTypeResMinInclusive);
+							$sTypeResMinInclusive->setAttribute('value', $restrictionValue);
+						}
+						/* TODO: xsd restrictions:
+							enumeration	Defines a list of acceptable values
+							fractionDigits	Specifies the maximum number of decimal places allowed. Must be equal to or greater than zero
+							length	Specifies the exact number of characters or list items allowed. Must be equal to or greater than zero
+							maxExclusive	Specifies the upper bounds for numeric values (the value must be less than this value)
+							maxInclusive	Specifies the upper bounds for numeric values (the value must be less than or equal to this value)
+							maxLength	Specifies the maximum number of characters or list items allowed. Must be equal to or greater than zero
+							minExclusive	Specifies the lower bounds for numeric values (the value must be greater than this value)
+							minInclusive	Specifies the lower bounds for numeric values (the value must be greater than or equal to this value)
+							minLength	Specifies the minimum number of characters or list items allowed. Must be equal to or greater than zero
+							pattern	Defines the exact sequence of characters that are acceptable
+							totalDigits	Specifies the exact number of digits allowed. Must be greater than zero
+							whiteSpace	Specifies how white space (line feeds, tabs, spaces, and carriage returns) is handled
+						*/
+					}
+				} else {
+					foreach ($enumList as $enumValue) {
+						$sTypeResEnum = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:enumeration');
+						$sTypeRes->appendChild($sTypeResEnum);
+						$sTypeResEnum->setAttribute('value', $enumValue);
+					}
+				}
+			}
+		}
+
+		$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xs:element');
+		$rootNode->appendChild($elNode);
+		$elNode->setAttribute('name', $tblName);
+		$elNode->setAttribute('type', "{$objNs}:{$typeName}");
+
+		header('Content-type: application/xml');
+		echo $dom->saveXML();
+		exit;
+	}
+
+}