diff --git a/tctable/TCField.java b/tctable/TCField.java index 1e9cb19..4b37b3d 100644 --- a/tctable/TCField.java +++ b/tctable/TCField.java @@ -9,6 +9,7 @@ public class TCField { //Типы данных public static final int BD_NULL = 1000; //Столбец со значением всегда NULL + public static final int BD_UINT1_B = 27; //1 байт без знаковый Boolean public static final int BD_UINT1 = 0; //1 байт без знаковый public static final int BD_UINT2 = 1; //2 байта без знаковый public static final int BD_UINT4 = 3; //4 байта без знаковый @@ -23,11 +24,17 @@ public class TCField public static final int BD_FLOAT8 = 22; //8 байт double public static final int BD_SFLOAT8 = 26; //Почти тоже самое что и BD_UTF8_1 но с строке передаётся число public static final int BD_UTF8_1 = 100; //100 - utf8_1 string 1й байт размер строки в байтах + public static final int BD_UTF8_1_UUID = 103; //103 - utf8_1 string 1й байт размер строки в байтах + public static final int BD_UTF8_1_TIMESTAMP = 105; //103 - utf8_1 string 1й байт размер строки в байтах public static final int BD_UTF8_2 = 101; //101 - utf8_2 string 1х 2 байта размер строки в байтах public static final int BD_UTF8_4 = 102; //102 - utf8_4 string 1х 4 байта размер строки в байтах + public static final int BD_UTF8_4_JSONB = 104; //102 - utf8_4 string 1х 4 байта размер строки в байтах public static final int BD_BLOB_2 = 141; public static final int BD_BLOB_4 = 143; //Двоичные данные uint4 количество байт + public boolean u_exists=false; //Пользовательское поле (Для упрощения экспорта данных из базы в базу) + public String u_type=""; //Пользовательское поле + public String name=""; //Название столбца public int type=-1; //Тип данных public byte[] value=null; //Запакованые данные @@ -46,16 +53,19 @@ public class TCField this.type= TCField.BD_UTF8_2; //Defalt type //From PostgreSQL and MySQL if(type.equals("null")) { this.type= TCField.BD_NULL; } else - if(type.equals("bool") || type.equals("tinyint")) { this.type= TCField.BD_UINT1; } else + if(type.equals("bool")) { this.type= TCField.BD_UINT1_B; } else + if(type.equals("tinyint")) { this.type= TCField.BD_UINT1; } else if(type.equals("int4") || type.equals("int") || type.equals("serial") || type.equals("bigint")) { this.type= TCField.BD_INT4; } else //bigint немного неправильно потому что это 64 бита но для андрод приложения не сделал if(type.equals("int8")) { this.type= TCField.BD_INT8; } else if(type.equals("float4") || type.equals("float")) { this.type= TCField.BD_FLOAT4; } else if(type.equals("float8") || type.equals("NUMBER")) { this.type= TCField.BD_FLOAT8; } else if(type.equals("varchar") || type.equals("VARCHAR2")) { this.type= TCField.BD_UTF8_2; } else if(type.equals("text")) { this.type= TCField.BD_UTF8_4; } else + if(type.equals("jsonb")) { this.type= TCField.BD_UTF8_4_JSONB; } else if(type.equals("bytea") || type.equals("longblob")) { this.type= TCField.BD_BLOB_4; } else if(type.equals("timestamptz")) { this.type= TCField.BD_UTF8_1; } else - if(type.equals("timestamp")) { this.type= TCField.BD_UTF8_1; } else + if(type.equals("uuid")) { this.type= TCField.BD_UTF8_1_UUID; } else + if(type.equals("timestamp")) { this.type= TCField.BD_UTF8_1_TIMESTAMP; } else if(type.equals("date")) { this.type= TCField.BD_UTF8_1; } } @@ -82,7 +92,7 @@ public class TCField //Прочитать значение из потока в соответствии с типом public void ReadValue(InputStream fileHandle) throws IOException { - if(this.type== TCField.BD_UINT1) + if(this.type == TCField.BD_UINT1 || this.type == TCField.BD_UINT1_B) { value=new byte[1]; fileHandle.read(value); @@ -132,7 +142,7 @@ public class TCField value=new byte[8]; fileHandle.read(value); }else - if(this.type== TCField.BD_UTF8_1 || this.type== TCField.BD_SUINT8 || this.type== TCField.BD_SINT8 || this.type== TCField.BD_SFLOAT8) + if(this.type== TCField.BD_UTF8_1 || this.type== TCField.BD_UTF8_1_UUID || this.type== TCField.BD_UTF8_1_TIMESTAMP || this.type== TCField.BD_SUINT8 || this.type== TCField.BD_SINT8 || this.type== TCField.BD_SFLOAT8) { byte[] s=new byte[1]; fileHandle.read(s); @@ -153,7 +163,7 @@ public class TCField fileHandle.read(value); } }else - if(this.type== TCField.BD_UTF8_4) + if(this.type== TCField.BD_UTF8_4 || this.type== TCField.BD_UTF8_4_JSONB) { long s=Tools.readUInt(fileHandle); if(s==0) value=null; @@ -183,14 +193,14 @@ public class TCField try { if(value==null) result = ""; - if(type== TCField.BD_UINT1) result = String.valueOf(getUByteVal()); + if(type== TCField.BD_UINT1 || type== TCField.BD_UINT1_B) result = String.valueOf(getUByteVal()); if(type== TCField.BD_UINT4) result = String.valueOf(getUIntVal()); if(type== TCField.BD_UINT8) result = String.valueOf(getULongVal()); if(type== TCField.BD_INT4) result = String.valueOf(getIntVal()); if(type== TCField.BD_INT8) result = String.valueOf(getLongVal()); if(type== TCField.BD_FLOAT4) result = String.valueOf(getFloatVal()); if(type== TCField.BD_FLOAT8) result = String.valueOf(getDoubleVal()); - if(type== TCField.BD_UTF8_1 || type== TCField.BD_UTF8_2 || type== TCField.BD_UTF8_4 || type== TCField.BD_SUINT8 || type== TCField.BD_SINT8 || type== TCField.BD_SFLOAT8) + if(type== TCField.BD_UTF8_1 || type== TCField.BD_UTF8_1_UUID || type== TCField.BD_UTF8_1_TIMESTAMP || type== TCField.BD_UTF8_2 || type== TCField.BD_UTF8_4 || type== TCField.BD_UTF8_4_JSONB || type== TCField.BD_SUINT8 || type== TCField.BD_SINT8 || type== TCField.BD_SFLOAT8) { result = new String(value, "UTF8"); } @@ -309,7 +319,7 @@ public class TCField public short getUByteVal() { short val=0; - if(type==BD_UINT1) { + if(type==BD_UINT1 || type==BD_UINT1_B) { val = (short) (value[0] & 0xff); }else{ String sVal = getStrVal(); @@ -401,7 +411,7 @@ public class TCField boolean result=true; if(val==null) { value=null; - }else if(type== TCField.BD_UINT1) + }else if(type== TCField.BD_UINT1 || type== TCField.BD_UINT1_B) { if(val.equals("f") || val.equals("false")) val="0"; else if(val.equals("t") || val.equals("true")) val="1"; @@ -481,7 +491,7 @@ public class TCField }else if(type== TCField.BD_FLOAT8) { setDoubleVal(Double.parseDouble(val)); - }else if(type== TCField.BD_UTF8_1 || this.type== TCField.BD_SUINT8 || this.type== TCField.BD_SINT8 || this.type== TCField.BD_SFLOAT8) + }else if(type== TCField.BD_UTF8_1 || type== TCField.BD_UTF8_1_UUID || type== TCField.BD_UTF8_1_TIMESTAMP || this.type== TCField.BD_SUINT8 || this.type== TCField.BD_SINT8 || this.type== TCField.BD_SFLOAT8) { value=null; if(val!=null && !val.equals("")) @@ -528,7 +538,7 @@ public class TCField } } } - }else if(type== TCField.BD_UTF8_4) + }else if(type== TCField.BD_UTF8_4 || type== TCField.BD_UTF8_4_JSONB) { value=null; if(val!=null && !val.equals("")) diff --git a/tctable/TCTableTools.java b/tctable/TCTableTools.java index 5bdce52..a8d648b 100644 --- a/tctable/TCTableTools.java +++ b/tctable/TCTableTools.java @@ -40,7 +40,7 @@ public class TCTableTools { } //Напиши функцию: Получить ассоциативный массив название полей таблицы и их тип - public static Map getTableSchema(Connection connection, String schemaName, String tableName) { + public static Map getTableSchema(Connection connection, String tableName) { Map schemaMap = new HashMap<>(); String query = """ SELECT c.column_name, @@ -56,8 +56,10 @@ public class TCTableTools { AND c.table_name = ? """; try (PreparedStatement statement = connection.prepareStatement(query)) { - statement.setString(1, schemaName); - statement.setString(2, tableName); + String schema = Tools.beforeFirst(tableName,"."); + String table = Tools.afterLast(tableName,"."); + statement.setString(1, schema); + statement.setString(2, table); try (ResultSet resultSet = statement.executeQuery()) { while (resultSet.next()) { String columnName = resultSet.getString("column_name"); @@ -71,4 +73,73 @@ public class TCTableTools { return schemaMap; } + public static String getSQLUpdate(TCTable tbl) { + StringBuilder sql; + sql = new StringBuilder("update " + tbl.name + " set "); + for(int i=0;i + * <element><childName/></element> + * @param parent + * @param childName + * @return Дочерный элемент либо null, если элементов с таким именем нет + */ + public static Element getChild(Element parent, String childName){ + NodeList nl = parent.getChildNodes(); + for (int i = 0; i node элементом (instanceOf {@link Element}) + * и имеет ли имя "tagname" + * @param node + * @param tagname + * @return + */ + public static boolean isElement(Node node, String tagname){ + return node instanceof Element && node.getNodeName().equals(tagname); + } + +<<<<<<<< HEAD:xmltools/XMLTools.java +======== + //вернуть первый попавшийся узел среди дочерних + public static Node getFirstNodeOnName(Node node,String nodename) + { + Node[] mas=new Node[50]; //depth + int pos=0; + mas[pos] = node.getFirstChild(); + while (mas[pos] != null) + { + if(mas[pos].getNodeName().equals(nodename)) + { + return mas[pos]; + } + if(mas[pos].getFirstChild()!=null) + { + pos++; + mas[pos]=mas[pos-1].getFirstChild(); + }else + { + //если не идёт дальше пытаемся подняться в верх по дереву + while (true) + { + mas[pos] = mas[pos].getNextSibling(); + if (mas[pos]==null) + { + if(pos>0){ pos--; }else{ break; } + }else + { + break; + } + } + } + } + return null; + } + + /** + * Return first from childs in first deep level on name + * @param node Find in + * @param nodename Name node + * @return node + */ + public static Node getNodeOnName(Node node,String nodename) + { + if(node==null) return null; + Node nextNode = node.getFirstChild(); + while(nextNode != null) + { + if(nextNode.getNodeName().equals(nodename)) return nextNode; + nextNode=nextNode.getNextSibling(); + } + return null; + } + + //Сериализовать узел в строку + public static String getOuterXML(Node node) + { + DOMImplementationLS domImplementation = (DOMImplementationLS) node.getOwnerDocument().getImplementation(); + LSSerializer lsSerializer = domImplementation.createLSSerializer(); + if (!(node instanceof Document)) + { + lsSerializer.getDomConfig().setParameter("xml-declaration", false); + } + return lsSerializer.writeToString(node); + } + +>>>>>>>> bd22e57cbce7dba632e6c46bb0e627e3b0f388f7:xml/XMLTools.java + /** Найти узел по атрибуту + */ + public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val) + { + if(node==null) return null; + NodeList items = node.getChildNodes(); + for (int i=0;i0){ pos--; }else{ break; } + }else + { + break; + } + } + } + } + return null; + } + + /** + * Return first from childs in first deep level on name + * @param node Find in + * @param nodename Name node + * @return node + */ + public static Node getNodeOnName(Node node,String nodename) + { + if(node==null) return null; + Node nextNode = node.getFirstChild(); + while(nextNode != null) + { + if(nextNode.getNodeName().equals(nodename)) return nextNode; + nextNode=nextNode.getNextSibling(); +======== + public static Node findFirstNodeOnAttribute(Node node, String nodename,String attribute,String val) + { + Node result=null; + if(node==null) return result; + javax.xml.xpath.XPathFactory xPathfactory = javax.xml.xpath.XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr=null; + Object exprResult=null; + try { + expr = xpath.compile("//*/"+nodename+"[@"+attribute+"='" + val + "']"); + exprResult = expr.evaluate(node, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + +>>>>>>>> bd22e57cbce7dba632e6c46bb0e627e3b0f388f7:xml/XMLTools.java + } + return null; + } + + //Сериализовать узел в строку + public static String getOuterXML(Node node) + { + DOMImplementationLS domImplementation = (DOMImplementationLS) node.getOwnerDocument().getImplementation(); + LSSerializer lsSerializer = domImplementation.createLSSerializer(); + if (!(node instanceof Document)) + { + lsSerializer.getDomConfig().setParameter("xml-declaration", false); + } + return lsSerializer.writeToString(node); + } + + /** + * Поиск среди текущего и дочерних узлов + * @param {Node} node Корневой узел + * @param {String} nodename Имя первого попавшегося узла + * @returns {undefined} + */ + public static Node findFirstNode(Node node, String nodename) + { + Node result=null; + if(node==null) return result; + javax.xml.xpath.XPathFactory xPathfactory = javax.xml.xpath.XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr=null; + Object exprResult=null; + try { + expr = xpath.compile("//*/"+nodename); + exprResult = expr.evaluate(node, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) + result = nodeList.item(0); + return result; + } + + /** + * Найти узел по имени + * @param node + * @param nodename + * @return + */ + public static Node findFirstNode_v2(Node node, String nodename) + { + if(node==null || nodename==null) return null; + NodeList items = node.getChildNodes(); + for (int i=0;i>>>>>>> bd22e57cbce7dba632e6c46bb0e627e3b0f388f7:xml/XMLTools.java + /** Найти узел по атрибуту + */ + public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val) + { + if(node==null) return null; + NodeList items = node.getChildNodes(); + for (int i=0;i 0) + result = nodeList.item(0); + return result; + } + + /** + * Присвоить дочерние узлы первого дерева второму если их нет, иначе дополнить либо заменить. (Работает через рекурсию нужно для передачи параметров между окнами) + * @param {XML} first Узел где ханятся настройки + * @param {XML} second Узел к которому применяются настройки + * @param {String} name Имя атрибута по которому будут находиться одинаковые XML узлы + * @returns {undefined} + */ + public static void applyNodeToNode(Node first, Node second,String name) + { + if(first==null || second==null || name==null) return; + + //Если есть совпадающие узлы то передаём в рекурсию если нет то просто копируем + Node fn=first.getFirstChild(); + while (fn != null) + { + Node sn=null; + if(!fn.getNodeName().equals("#text") && !fn.getNodeName().equals("#cdata-section") && !fn.getNodeName().equals("#comment")) { //потому что для этих getAttribute вызывает ошибку + sn=findNodeOnAttribute(second,fn.getNodeName(),name,fn.getAttributes().getNamedItem(name).getNodeValue()); + } + + if(sn!=null) //Если по имени атрибуту совпали узлы + { + //Переписываем значения атрибутов из первого второму, если их нет то создаём. + for(int i=0;i>>>>>>> bd22e57cbce7dba632e6c46bb0e627e3b0f388f7:xml/XMLTools.java + /** Найти узел по атрибуту + */ + public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val) + { + if(node==null) return null; + NodeList items = node.getChildNodes(); + for (int i=0;i0){ pos--; }else{ break; } + }else + { + break; + } + } + } + } + return null; + } + + /** + * Return first from childs in first deep level on name + * @param node Find in + * @param nodename Name node + * @return node + */ + public static Node getNodeOnName(Node node,String nodename) + { + if(node==null) return null; + Node nextNode = node.getFirstChild(); + while(nextNode != null) + { + if(nextNode.getNodeName().equals(nodename)) return nextNode; + nextNode=nextNode.getNextSibling(); +======== + public static Node findFirstNodeOnAttribute(Node node, String nodename,String attribute,String val) + { + Node result=null; + if(node==null) return result; + javax.xml.xpath.XPathFactory xPathfactory = javax.xml.xpath.XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr=null; + Object exprResult=null; + try { + expr = xpath.compile("//*/"+nodename+"[@"+attribute+"='" + val + "']"); + exprResult = expr.evaluate(node, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + +>>>>>>>> bd22e57cbce7dba632e6c46bb0e627e3b0f388f7:xml/XMLTools.java + } + return null; + } + //Сериализовать узел в строку public static String getOuterXML(Node node) { @@ -216,6 +300,10 @@ public class XMLTools } return null; } +<<<<<<<< HEAD:xmltools/XMLTools.java +======== + +>>>>>>>> bd22e57cbce7dba632e6c46bb0e627e3b0f388f7:xml/XMLTools.java /** Найти узел по атрибуту */ public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val)