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:system_cache__appinfo', 'http://biuro.biall-net.pl/xmlschema_procesy5/default_db_xml_cache/appinfo.xsd');
$xmlWriter->writeAttribute("xmlns:{$p5TypePrefix}", $p5TypeNsUri);
if(DB::getPDO()->getZasobId() === $idStorage) {} else {
$xmlWriter->writeAttribute('xmlns:p5_zasob_'.$idStorage, $objNsUri ); //brakuje deklaracji xmlns dla innego zasobu
}
$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}"; // conforming to xmlschema engine property
$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 is not like others xsd. objects
$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');
$xmlWriter->writeAttribute('name', $key['COLUMN_NAME']); //todo may not be unique - to be set table__x3A__name
$refPrefix = (DB::getPDO()->getZasobId() === $idStorage) ? 'p5_default_db' : "p5_zasob_{$idStorage}";
$xmlWriter->writeAttribute('type', "{$refPrefix}:{$key['REFERENCED_TABLE_NAME']}"); //it is better to show it as type to be than translated to references than having fake ref
$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;
//
$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;
}
}