commit e21bba7f0bdfce45dbe3d9fb6b9c4178a7639bd5 Author: kaj dijkstra Date: Thu Dec 25 09:56:43 2025 +0100 First Commit. diff --git a/demo.js b/demo.js new file mode 100644 index 0000000..28d0aa2 --- /dev/null +++ b/demo.js @@ -0,0 +1,41 @@ + +import database from "./source/database.js"; + +import querySQL from "./source/querySQL.js"; + +import joinSQL from "./source/joinSQL.js"; + + + +database.createTable( "user" ); + +database.addColumn( "name", "VARCHAR", "user" ); + + + +var query = new querySQL( ); + +query.type = "insert"; + +query.table = "user"; + +query.setValue( "name", "john" ); + +var result = database.query( query ); + + + +var query = new querySQL( ); + +query.type = "select"; + +query.table = "user"; + +query.find( "name", "john" ); + + +var result = database.query( query ); + +console.log( result ); + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..617f041 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "type": "module", + "name": "Unify", + "license-key": "", + "version": "1.0.0", + "description": "Unify", + "main": "http://localhost:3000", + "node-remote": "http://localhost:3000", + "module": "./node-esm.js", + "window": { + "width": 1430, + "height": 750, + "icon": "icon.png" + }, + "chromium-args": "--enable-devtools --child-clean-exit --enable-node-worker", + "nodemonConfig": { + "ignore": [ + "configs/*.js", + "assets/*", + "*/imports.js", + "*/plugins.js", + "*/config.js", + "*configs/*", + "*framework/cache/*", + "*/bundle.js" + ] + } + +} diff --git a/source/consoleColors.js b/source/consoleColors.js new file mode 100644 index 0000000..d39fbf5 --- /dev/null +++ b/source/consoleColors.js @@ -0,0 +1,199 @@ +/* + + Copyright (c) 2020, 2023, The Unified Company. + + This code is part of Unify. + + This program is free software; you can redistribute it and/or modify + it under the terms of the ESA Software Community License - Strong Copyleft LICENSE, + as published by the ESA. + See the ESA Software Community License - Strong Copyleft LICENSE, for more details. + + https://unifyjs.org + +*/ + + +class consoleColors{ + + colors = new Array(); + + backgroundColors = new Array(); + + + addColor( colorName, colorCode ) { + + var color = new Object(); + + color.name = colorName; + + color.code = colorCode; + + this.colors.push( color ); + + } + + addBackgroundColor( colorName, colorCode ) { + + var color = new Object(); + + color.name = colorName; + + color.code = colorCode; + + this.backgroundColors.push( color ); + + } + + constructor() { + + this.createTextColors(); + + this.createBackgroundColors(); + + return this.createMethods(); + + } + + createTextColors() { + + this.addColor( "white", 37 ); + + this.addColor( "black", 30 ); + + this.addColor( "blue", 34 ); + + this.addColor( "cyan", 36 ); + + this.addColor( "green", 32 ); + + this.addColor( "magenta", 35 ); + + this.addColor( "red", 31 ); + + this.addColor( "yellow", 33 ); + + this.addColor( "brightBlack", 90 ); + + this.addColor( "brightRed", 91 ); + + this.addColor( "brightGreen", 92 ); + + this.addColor( "brightYellow", 93 ); + + this.addColor( "brightBlue", 94 ); + + this.addColor( "brightMagenta", 95 ); + + this.addColor( "brightCyan", 96 ); + + this.addColor( "brightWhite", 97 ); + + } + + createBackgroundColors() { + + this.addBackgroundColor( "bgBlack", 40 ); + + this.addBackgroundColor( "bgRed", 41 ); + + this.addBackgroundColor( "bgGreen", 42 ); + + this.addBackgroundColor( "bgYellow", 43 ); + + this.addBackgroundColor( "bgBlue", 44 ); + + this.addBackgroundColor( "bgMagenta", 45 ); + + this.addBackgroundColor( "bgCyan", 46 ); + + this.addBackgroundColor( "bgWhite", 47 ); + + this.addBackgroundColor( "bgBrightBlack", 100 ); + + this.addBackgroundColor( "bgBrightRed", 101 ); + + this.addBackgroundColor( "bgBrightGreen", 102 ); + + this.addBackgroundColor( "bgBrightYellow", 103 ); + + this.addBackgroundColor( "bgBrightBlue", 104 ); + + this.addBackgroundColor( "bgBrightMagenta", 105 ); + + this.addBackgroundColor( "bgBrightCyan", 106 ); + + this.addBackgroundColor( "bgBrightWhite", 107 ); + + } + + createMethodsForTextColor( color, colorMethods ) { + + var name = color.name; + + var code = color.code; + + var open = '\u001b[' + code + 'm'; + + var close = '\u001b[39m'; + + colorMethods[ name ] = function ( value ) { + + return open + value + close; + + } + + } + + createMethodsForBackgroundColor( color, colorMethods ) { + + var name = color.name; + + var code = color.code; + + var open = '\u001b[' + code + 'm'; + + var close = '\u001b[49m'; + + + colorMethods[ name ] = function ( value ) { + + return open + value + close; + + } + + } + + createMethods() { + + var colors = this.colors; + + + var colorMethods = new Array(); + + for ( var i = 0; i < colors.length; i++ ) { + + var textColor = colors[i]; + + this.createMethodsForTextColor( textColor, colorMethods ); + + } + + + var backgroundColors = this.backgroundColors; + + for ( var i = 0; i < backgroundColors.length; i++ ) { + + var backgroundColor = backgroundColors[i]; + + this.createMethodsForBackgroundColor( backgroundColor, colorMethods ); + + } + + return colorMethods; + + } + +} + +export default new consoleColors(); \ No newline at end of file diff --git a/source/css.js b/source/css.js new file mode 100644 index 0000000..12791f6 --- /dev/null +++ b/source/css.js @@ -0,0 +1,637 @@ +/* + + Copyright (c) 2020, 2023, The Unified Company. + + This code is part of Unify. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE, + as published by the Free Software Foundation. + See the GNU AFFERO GENERAL PUBLIC LICENSE, for more details. + + https://unifyjs.org + +*/ + +import cssRules from './cssRules.js'; + +import document from './document.js'; + +import cssManager from './cssManager.js'; + +import tools from './tools.js'; + +import definitions from './definitions.js'; + + +export default class css{ + + cssCache = new cssManager(); + + global_css = ""; + + skipBoxTerms = new Array( "box-sizing", "box-shadow", "box-reflect", "box-decoration-break" ); + + constructor() { + + this.boxTermWithoutPrefix = new Array(); + + for (var i = 0; i < this.skipBoxTerms.length; i++) { + + var boxTerm = this.skipBoxTerms[i] + + this.boxTermWithoutPrefix[i] = boxTerm.replace("box-") + + } + + } + + PerformPropertyGridCorrection( property ) { + + for ( var i = 0; i < this.skipBoxTerms.length; i++ ) { + + if( this.boxTermWithoutPrefix[ i ].includes( property ) ) { + + property = this.skipBoxTerms[ i ]; + + } + + } + + return property; + + } + + parseObject( object ){ + + var objectName = object.propertyName; + + object.__proto__.css = new cssRules(); + + object.__proto__.boxRules = new cssRules(); + + object.__proto__.cssRules = new cssRules(); + + + object.cssRules.addStyleListener( "hover", ":hover" ); + + object.cssRules.addStyleListener( "visited", ":visited" ); + + object.cssRules.addStyleListener( "link", ":link" ); + + object.cssRules.addStyleListener( "active", ":active" ); + + + object.cssRules.addStyleListener( "placeholder", "::placeholder" ); + + object.cssRules.addStyleListener( "scrollbar", "::-webkit-scrollbar" ); + + object.cssRules.addStyleListener( "scrollbarTrack", "::-webkit-scrollbar-track" ); + + object.cssRules.addStyleListener( "scrollbarThumb", "::-webkit-scrollbar-thumb" ); + + object.cssRules.addStyleListener( "scrollbarThumbHover", "::-webkit-scrollbar-thumb:hover" ); + + + } + + parseCSSValue( value ) { + + if( typeof value == "number" ) { + + value += "px"; + } + + return value; + + } + + createStyleRule( normalizedProperty, value ){ + + if( !value ) { + + return ""; + + } + + value = this.parseCSSValue( value ); + + normalizedProperty = this.PerformPropertyGridCorrection( normalizedProperty ); + + return "\t" + normalizedProperty + ":" + value + "; \n"; + + } + + compareUpperCase( term ) { + + const compare = function( current ){ if( term.indexOf( current ) != -1 ){ return true; } } + + const n = definitions.alphabet; + + var map = n.map( compare ); + + return map; // [false, false, true, false] where true is where higher case is + + } + + + hasUpperCase( a ) { + + let regExp = /[A-Z]/; + + return regExp.test( a ); + + } + + replaceUpperCase( word ) { + + var map = this.compareUpperCase( word ); + + var letter = definitions.alphabet[ map.indexOf( true ) ]; + + return word.replace( letter, "-" + letter.toLowerCase() ); + + } + + normalizePropertyName( name ) { + + return tools.firstLowerCase( name.replace("__", "").replace("box", "") ); + + } + + // needs caching + normalizeProperty( name ) { + + // webkit -> -webkit + if( name.slice( 0, 6 ) == "webkit" ) { + + name = "-" + name; + + } + + for (var i = 0; i < 6; i++) { + + if( this.hasUpperCase( name ) ) { + + name = this.replaceUpperCase( name ); // backgroundColor -> background-color-and-something + + } + + } + + return name; + + } + + setter( object, domStyleObject, propertyName, property, value ) { + + object[ "__" + propertyName ] = value; + + value = this.parseCSSValue( value ); + + property = this.PerformPropertyGridCorrection( property ); + + var NSTabNames = new Array("svg", "circle") + + // todo : doesnt work properly + //if( NSTabNames.includes( object.element.tagName ) ) { + + // domStyleObject.setAttributeNS( null, property, value ); + + //} else { + + domStyleObject.setProperty( property, value ); + + //} + + } + + createSetter( property, objectProperty, object, domStyleObject ) { + + var css = this; + + object[ "__" + objectProperty ] = object[ objectProperty ]; + + object.__defineSetter__( objectProperty, this.setter.bind( this, object, domStyleObject, objectProperty, property ) ); + + } + + getter( object, objectProperty, value ) { + + var newValue = object[ "__" + objectProperty ]; + + if(typeof newValue == "string") { + + var chars = newValue.split(); + + if( chars[chars.length-2] == "p" && chars[chars.length-1] == "x" ) { + + chars = chars.slice(0, -2); + + newValue = chars.join(); + + } + + } + + if( tools.isCustomNumber( newValue ) ) { + + return parseFloat( newValue ); + + } else { + + return newValue; + + } + + } + + createGetter( property, objectProperty, object, domStyleObject ) { + + object.__defineGetter__( objectProperty, this.getter.bind( this, object, objectProperty ) ); + + } + + parseProperty( property, object ) { + + var propertyName = property.name; + + var propertyValue = property.value; + + var normalizedProperty = this.normalizeProperty( propertyName ); + + //if( propertyName == "gridArea" && propertyValue == "none" ) { + + // return false; + + //} + + var slicedProperty = propertyName.toLowerCase().slice( 0, 3 ); + + if( slicedProperty == "box" ) { + + object.boxRules.style += this.parseCssTerm( object, propertyName, propertyValue, object.elements[0], "box" ); + + } else { + + object.css.style += this.parseCssTerm( object, propertyName, propertyValue, object.element ) + + } + + this.parseExtraStyleSuffixes( object, propertyName, propertyValue ); + + } + + parseExtraStyleSuffixes( object, propertyName, propertyValue ) { + + var styleTypes = object.cssRules.styleTypes; + + for ( var i = 0; i < styleTypes.length; i++ ) { + + var cssType = styleTypes[i]; + + var propertyTerm = cssType.propertyTerm; + + var slicedProperty = propertyName.slice( 0, propertyTerm.length ); + + + if( slicedProperty == propertyTerm && propertyName.length > slicedProperty.length ) { + + cssType.css += this.parseCssTerm( object, propertyName, propertyValue, object.elements[0], propertyTerm ); + + } + + } + + } + + parseCssTerm( object, propertyName, propertyValue, element, term = "" ) { + + var cssPropertyName = tools.firstLowerCase( propertyName.replace( term, "" ) ); + + var normalizedProperty = this.normalizeProperty( cssPropertyName ); + + if( this.propertyIsStyle( normalizedProperty ) ) { + + // Setters and getters don't work yet for special suffixes. + if( !term || term == "box" ) { + + this.createSetter( normalizedProperty, propertyName, object, element.style ); + + this.createGetter( normalizedProperty, propertyName, object, element.style ); + + } + + return this.createStyleRule( normalizedProperty, propertyValue ); + + } else { + + return ""; + + } + + } + + clearCache() { + + this.cssCache.rules = new Array(); + + } + + parseCssRule( object, objectPropertyName, propertyName, propertyValue ) { + + var normalizedProperty = this.normalizeProperty( objectPropertyName ); + + object.boxRules.style += this.createStyleRule( normalizedProperty, propertyValue ); + + + this.createSetter( objectPropertyName, propertyName, object, object.elements[0].style ); + + this.createGetter( objectPropertyName, propertyName, object, object.elements[0].style ); + + } + + createSelector( className, afterTerm ) { + + var selector = "." + className; + + selector += "." + this.device; + + selector += "." + this.os; + + selector += "." + this.tint; + + // this doesnt work yet. + if( afterTerm ) { + + selector += afterTerm; + + } + + //selector += "," + selector.replace( "_" + id, "" ); + + return selector; + + } + + createStyleSheet( object ){ + + var objectName = tools.createCSSClassName( object ); + + var body = object.css.style; + + + if( object.customElement ) { + + var selector = this.createSelector( objectName + "Element" ); + + this.global_css += this.cssCache.getRule( selector, body ); + + + var selector = this.createSelector( objectName + "Grid" ); + + this.global_css += this.cssCache.getRule( selector, body ); + + } else { + + var selector = this.createSelector( objectName + "Grid" ); + + this.global_css += this.cssCache.getRule( selector, body ); + + } + + if( object.boxRules ) { + + var selector = this.createSelector( objectName + "Box" ); + + var body = object.boxRules.style; + + this.global_css += this.cssCache.getRule( selector, body ); + + } + + + + var styleTypes = object.cssRules.styleTypes; + + for (var i = 0; i < styleTypes.length; i++) { + + var cssType = styleTypes[i]; + + if( object.useCustomElement ) { + + var selector = this.createSelector( objectName + "Element", cssType.cssSuffix ); + + } else { + + var selector = this.createSelector( objectName + "Grid", cssType.cssSuffix ); + + } + + var body = cssType.css; + + if( body != "" ) { + + //console.log("cssType.cssSuffix", cssType.cssSuffix); + + this.global_css += this.cssCache.getRule( selector, body ); + + } + + } + + + + if( !object.parent ) { + + this.writeCssToPage( this.global_css ); + + this.global_css = ""; + + } + + if( object.dynamic ) { + + this.writeCssToPage( this.global_css ); + + this.global_css = ""; + + } + + } + + writeCssToPage( css ) { + + if( css == "" ) { + + return false; + + } + + var style = document.createElement("style"); + + style.innerHTML = css; + + document.head.appendChild( style ); + + } + + removeStripe( name ) { + + var splitName = name.split("-"); + + if( splitName.length > 1 ) { + + return splitName[1].toLowerCase(); + + } else { + + return name; + + } + + } + + getStyleSheetObject(){ + + if( !document.body ) { + + return definitions.css; +/* + var array = JSON.parse(cssDef); + + var object = new Object(); + + for (var i = 0; i < array.length; i++) { + + var def = array[i]; + + if( this.hasUpperCase( def ) ) { + + object[ this.replaceUpperCase( def ) ] = ''; + + console.log( this.replaceUpperCase( def ) ); + + } else { + + object[ def ] = ''; + + } + } +*/ + return object; + + } + + if( document.body.style ) { + + var bodyStyle = document.body.style; + + bodyStyle.webkitBoxShadow = ""; + + return bodyStyle; + + } + + if( document.body.styleSheets ) { + + // fix please!!!! not allowed + return document.styleSheets[1].cssRules[0].style; + + } else { + + return document.customStyleTerms; + + } + + } + + camelCaseToDash( name ) { + + for ( var i = 0; i < 4; i++ ) { + + if( this.hasUpperCase( name ) ) { + + name = this.replaceUpperCase( name ); // backgroundColor -> background-color + + } + + } + + return name; + + } + + removeBoxPrefix( name ) { + + if( !name.includes("webkit-box") ) { + + name = name.replace("box", "").toLowerCase(); + + } + + return name; + + } + + checkBoxSpecialCase( name ) { + + for (var i = 0; i < this.boxTermWithoutPrefix.length; i++) { + + if( this.boxTermWithoutPrefix[ i ].includes( name ) ) { + + return true; + + } + + } + + } + + propertyIsStyle( name ){ + + name = this.camelCaseToDash( name ); + + name = this.removeBoxPrefix( name ); + + + + if( this.checkBoxSpecialCase( name ) ) { + + return true; + + } + + + var styleTerms = this.getStyleSheetObject(); + + if( typeof styleTerms[ name ] == "string" ) { + + return true; + + } else { + + return false; + + } + + } + + propertyHasStyle( name ){ + + var styleTerms = Object.keys( definitions.css ); + + if( styleTerms.includes( name.toLowerCase() ) ) { + + return true; + + } else { + + return false; + + } + + } + +} + diff --git a/source/cssManager.js b/source/cssManager.js new file mode 100644 index 0000000..fc54a30 --- /dev/null +++ b/source/cssManager.js @@ -0,0 +1,63 @@ +/* + + Copyright (c) 2020, 2023, The Unified Company. + + This code is part of Unify. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE, + as published by the Free Software Foundation. + See the GNU AFFERO GENERAL PUBLIC LICENSE, for more details. + + https://unifyjs.org + +*/ + +import tools from './tools.js'; + +export default class cssManager{ + + rules = new Array(); + + addRule( selector, body ) { + + var rule = new Object(); + + rule.selector = selector; + rule.body = body; + + this.rules[ selector ] = body; + + } + + composeCss( selector, body ) { + + if( body == "") { + + return ""; + + } + + return "\n" + selector + "{ " + "\n" + body + "\n" + " } " + "\n"; + + } + + getRule( selector, body ) { + + selector = tools.cleanRollup( selector ); + + if( this.rules[ selector ] ) { + + return ""; + + } else { + + this.addRule( selector, body ); + + return this.composeCss( selector, body ); + + } + + } + +} diff --git a/source/cssRules.js b/source/cssRules.js new file mode 100644 index 0000000..4720c54 --- /dev/null +++ b/source/cssRules.js @@ -0,0 +1,39 @@ +/* + + Copyright (c) 2020, 2023, The Unified Company. + + This code is part of Unify. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE, + as published by the Free Software Foundation. + See the GNU AFFERO GENERAL PUBLIC LICENSE, for more details. + + https://unifyjs.org + +*/ + +export default class cssRules{ + + style = ""; + + styleTypes = new Array(); + + addStyleListener( propertyTerm, cssSuffix ) { + + var styleType = new Object(); + + styleType.propertyTerm = propertyTerm; + + styleType.cssSuffix = cssSuffix; + + styleType.css = ""; + + this.styleTypes.push( styleType ); + + } + + + +} + diff --git a/source/database.js b/source/database.js new file mode 100644 index 0000000..627a2b1 --- /dev/null +++ b/source/database.js @@ -0,0 +1,1606 @@ +/* + + Copyright (c) 2020, 2023, The Unified Company. + +*/ + +import tools from './tools.js'; + +import querySQL from './querySQL.js'; + +import document from './document.js'; + +import DATATYPE from './datatype.js'; + +import path from 'path'; + +import sqlite from './sqlite.js'; + +import sqlite3 from 'better-sqlite3'; + + +class databaseManager{ + + database; + + type = "update"; + + sqlite = new sqlite(); + + collisionID = 0; + + serverID = 0; + + + async connect() { + + if( !document.doctype ) { + + this.sqlite.setup(); + + this.database = this.sqlite.db; + + } + + } + + createTimeUUID() { + + const timestamp = Date.now(); + + ++this.collisionID; + + var padddedCollisionID = String( this.collisionID % 9 ).padStart( 2, '0' ) + + var TimeUUID = parseFloat( timestamp + "" + this.serverID + "" + padddedCollisionID ); + + return TimeUUID; + + } + + query( query, execute = true ) { + + if( query.type == "insert" ) { + + query.setValue( "id", this.createTimeUUID() ); + + } + + if( execute && !query.root ) { + + query.root = true; + + } + + if( !query.name ) { + + query.name = query.table; + + } + + + var queryString = this.parseQuery( query ); + + //console.log("query", query); + + if( execute ) { + + return this.executeQuery( queryString, query ); + + } + + return queryString; + + } + + parseFilter( query ) { + + var searchable = query.filter.search; + + + + if( searchable ) { + + //console.log("query.filter", query, searchable); + + return this.parseSearch( searchable, query, 0 ); + + } else { + + return false; + + } + + } + + tabLevel( level ) { + + var tabs = ""; + + for (var i = 0; i < level; i++) { + + tabs += "\t"; + + } + + return tabs; + + } + + parseSearchOperator( a, b, searchable, query, level ) { + + //console.log("parseSearchOperator", searchable); + + var tabs = this.tabLevel( level ) + " "; + + var subEnd = ""; + + var begin = "\n" + tabs; + + var end = tabs + "\n"; + + + switch( searchable.operator.replaceAll(/\s/g,'')) { + + case "LIKE" : + + b = "'%" + tools.htmlEntities( b ) + "%'"; + + break; + + case "=" : + + b = "'" + tools.htmlEntities( b ) + "'"; + + + + break; + + case "OR": + + searchable.operator = " " + tabs + searchable.operator + ""; + + subEnd = tabs; + + break; + + case "AND": + + searchable.operator = "\n " + tabs + searchable.operator + "\n"; + + subEnd = tabs; + + break; + + default: + + } + + + return begin + "( " + a + " " + searchable.operator + " " + b + subEnd + " ) " + end; + + } + + parsePath( searchable, filterAddress, query ) { + + var path = searchable.path; + + var parts = path.split("/"); + + var columnName = parts.pop(); + + var filterAddress = parts.join("/") + "/"; + + this.findMatchingQuery( filterAddress, query, searchable, path ); + + } + + validateSearchables( a ) { + + if( typeof a == "string" ) { + + return true; + + } + + + if( a.operator ) { + + return true; + + } + + if( !a.queryName ) { + + return false; + + } + + return true; + + } + + parseSearch( searchable, query, level ) { + + if( searchable.operator ) { + + level++; + + + var a = this.parseSearch( searchable.a, query, level ); + + var b = this.parseSearch( searchable.b, query, level ); + +/* + var invalidA = this.validateSearchables( searchable.a ) + + var invalidB = this.validateSearchables( searchable.b ) + + if( !invalidA ) { + + + return false; + + } + + if( !invalidB ) { + + return false; + + } + + if( !a && typeof a != "string" ) { + + return b; + + } + + if( !b && typeof b != "string" ) { + + return a; + + } +*/ + return this.parseSearchOperator( a, b, searchable, query, level ); + + } + + if( searchable.path ) { + + var filterAddress = ""; + + this.parsePath( searchable, filterAddress, query ); + + if( !searchable.queryName ) { + + //return false; + + } + + } + + + if( typeof searchable == "string" ) { + + return searchable; + + } + + if( searchable.queryName ) { + + return searchable.queryName; + + } + + + } + + findMatchingQueryJoins( query, filterAddress, searchable ) { + + for( var c = 0; c< query.joins.length; c++ ) { + + var join = query.joins[c]; + + console.log("search join", join); + + //this.findMatchingQuery( filterAddress, join, searchable ); + + } + + } + + findMatchingQueryUnions( query, filterAddress, searchable ) { + + for (var i = 0; i < query.union.length; i++) { + + var union = query.union[i]; + + this.findMatchingQuery( filterAddress, union, searchable ); + + } + + } + + findMatchingQuery( filterAddress, query, searchable, path ) { + + //console.log( "query.filterAddress", query.filterAddress ); + + //console.log( "searchable.path", filterAddress ); + + var parts = path.split("/"); + + //console.log("parts", parts); + + if( parts.length == 3 ) { + + parts.shift(); + + } + + searchable.queryName = parts.join("."); + + +/* + if( query.filterAddress == filterAddress ) { + + var parts = path.split("/"); + + console.log("parts", parts); + + + searchable.queryName = path.replace("./", query.name + "."); + + } else { + + + searchable.queryName = path; + + console.log("filterAddress", filterAddress); + + console.log("filterAddress", searchable); + + var parts = filterAddress.split("/") + + //console.log("parts", parts); + + this.findMatchingQueryJoins( query, filterAddress, searchable ); + + //this.findMatchingQueryUnions( query, filterAddress, searchable ); + + } +*/ + } + + insertRow( table ) { + + var query = new querySQL( ); + + query.type = "insert"; + + query.addObject( table ); + + var collection = table.getCollection(); + + if( collection ) { + + query.setColumn( "joined", true ); // todo : fix : set boolean on setColumn + + } else { + + query.setColumn( "joined", false ); + + } + + var row = this.query( query ); + + return row.lastInsertRowid; + + } + + updateChildren( query ) { + + var objects = query.objects; + + for( var c = 0; c < objects.length; c++ ) { + + var object = objects[c]; + + var values = new Array(); + + var children = object.getChildren(); + + for( var c = 0; c < children.length; c++ ) { + + var child = children[c]; + + if( child.datatype ) { + + values.push( child.value ); + + } + } + + } + + } + + exec( queryString ) { + + return this.database.prepare( queryString ).all(); + + } + + prepare( queryString ) { + + return this.database.prepare( queryString ).all(); + + } + + performUpdateQuery( queryString, query ) { + + if( query.objects.length < 2 ) { + + var update = this.database.prepare( queryString ); + + update.run( query.getValues() ); + + } + + if( query.debug ) { + + console.log(); + console.log( queryString ); + console.log(); + console.log( query.getValues() ); + console.log(); + + } + + if( query.objects.length > 1 ) { + + var id = this.updateChildren( query ); + + } else { + + if( global.syncClient && query.sync ) { + + var id = query.getWhereByColumnName("id"); + + global.syncClient.sendMessage( queryString, query, id ); + + } + + + } + + //if( global.syncClient && query.sync ) { + + // global.syncClient.sendMessage( queryString, query, output.lastInsertRowid ); + + //} + + // query.queryUpdateChildren(); + + } + + performInsertQuery( queryString, query ) { + + var insert = this.database.prepare( queryString ); + + if( query.debug ) { + + console.log( queryString ); + + } + + var output = insert.run( query.getValues() ); + + if( global.syncClient && query.sync) { + + var id = query.getWhereByColumnName("id"); + + global.syncClient.sendMessage( queryString, query, output.lastInsertRowid ); + + } + + return output; + + } + + performDeleteQuery( queryString, query ) { + + if( query.debug ) { + + console.log(queryString ); + + } + + var output = this.database.prepare( queryString ).run(); + + if( global.syncClient && query.sync ) { + + global.syncClient.sendMessage( queryString, query, output.lastInsertRowid ); + + } + + return output; + + } + + executeQuery( queryString, query ) { + + console.log( queryString ); + + switch( query.type.toLowerCase() ) { + + case "update": + + return this.performUpdateQuery( queryString, query ); + + break; + + case "insert": + + return this.performInsertQuery( queryString, query ); + + break; + + case "select": + + return this.database.prepare( queryString ).all(); + + break; + + case "count": + + return this.database.prepare( queryString ).pluck().get(); + + break; + + case "delete": + + return this.performDeleteQuery( queryString, query ); + + break; + + } + + } + + runQuery( queryString ) { + + return this.database.prepare( queryString ).all(); + + } + + parseQueryItems( query, queryID ) { + + var items = Object.entries( query ); + + var queryString = ""; + + for( var c = 0; c < items.length; c++ ){ + + var currentQuery = items[c]; + + var name = tools.getClassNameByEntry( currentQuery ); + var value = tools.getObjectByEntry( currentQuery ); + + queryString += this.parseTerm( name, value, query, queryID ); + + } + + queryString += "\n"; + + return queryString; + + } + + parseQueryJoins( query ) { + + var queryString = ""; + + for(var c = 0; c< query.joins.length; c++) { + + var join = query.joins[c]; + + join.parent = query; + join.queryID = c; + + queryString += this.parseQuery( join, c ); + + } + + return queryString; + + } + + parseQueryUnions( query, queryString ) { + + var parsedUnionQuerys = new Array(); + + for (var i = 0; i < query.union.length; i++) { + + var union = query.union[i]; + + union.root = true; + + parsedUnionQuerys[i] = this.query( union, false ); + + + } + + if( parsedUnionQuerys.length > 0 ) { + + return queryString = "SELECT * from ( " + parsedUnionQuerys.join(" \nUNION\n ") + ") "; + + } else { + + return queryString; + + } + + } + + finalizeItems( query, items, queryID, stackedQuery ) { + + var queryString = ""; + + for( var c = 0; c < items.length; c++){ + + var currentQuery = items[c]; + + var name = tools.getClassNameByEntry( currentQuery ); + + var value = tools.getObjectByEntry( currentQuery ); + + + queryString += this.parseStacked( name, value, query, queryID, stackedQuery ); + + } + + return queryString; + } + + finalizeQuery( query, queryID ) { + + var queryString = ""; + + if( tools.getClassName( query ) == "querySQL" && query.root ) { + + var stackedQuery = new Object(); + + stackedQuery.where = new Array(); + + stackedQuery.groups = new Array(); + + stackedQuery.order = new Array(); + + this.stackQuerys( query, stackedQuery ); + + var items = Object.entries( stackedQuery ); + + queryString = this.finalizeItems( query, items, queryID, stackedQuery ); + + } + + return queryString; + } + + parseQuery( query, queryID = false ) { + + var queryString = ""; + + + + + if( query.filter && query.filter.search ) { + + + + query.searchQuery = this.parseFilter( query ); + + //console.log("query.searchQuery", query.getClassName(), query.searchQuery, query); + + if( tools.getClassName( query ) == "joinSQL" ) { + + query.parent.searchQuery = query.searchQuery; + + } + + + + } + + queryString += this.parseQueryItems( query, queryID ); + + queryString += this.parseQueryJoins( query ); + + queryString = this.parseQueryUnions( query, queryString ); + + queryString += this.finalizeQuery( query, queryID ); + + return queryString; + + } + + stackOrder( query, stackedQuery ) { + + var order = query.order; + + for ( var i = 0; i < order.length; i++ ) { + + var orderStatement = new Object(); + + orderStatement.query = query; + + orderStatement.columnName = order[ i ]; + + stackedQuery.order.push( orderStatement ); + + } + + } + + stackWhere( query, stackedQuery ) { + + var where = query.where; + + for (var i = 0; i < where.length; i++) { + + var whereStatements = where[i]; + + whereStatements.query = query; + + stackedQuery.where.push( whereStatements ); + + } + + } + + stackGroups( query, stackedQuery ) { + + var groups = query.groups; + + for (var i = 0; i < groups.length; i++) { + + var group = groups[i]; + + group.query = query; + + stackedQuery.groups.push( group ); + + } + + } + + stackQuerys( query, stackedQuery ) { + + + this.stackOrder( query, stackedQuery ); + + this.stackWhere( query, stackedQuery ); + + this.stackGroups( query, stackedQuery ); + + + if( query.limit ) { + + stackedQuery.limit = query.limit; + + } + + if( query.offset ) { + + stackedQuery.offset = query.offset; + + } + + if( query.direction ) { + + stackedQuery.direction = query.direction; + + } + + + for (var i = 0; i < query.joins.length; i++) { + + this.stackQuerys( query.joins[i], stackedQuery ); + + } + + } + + parseTerm( name, value, query, queryID ){ + + var queryString = ""; + + switch( name.toLowerCase() ) { + + case "type": + + queryString += this.parseType( value, query, queryID ); + + break; + + case "columns": + + queryString += this.parseColumns( value, query.type, query ); + + break; + + + case "table": + + queryString += this.parseTableStatement( value, query ); + + break; + + case "values": + + queryString += this.parseValues( query ); + + break; + + case "groupby": + + queryString += this.parseGroupByStatement( value, query ); + + break; + + case "count": + + + break; + + } + + return queryString; + + } + + parseGroupByStatement( value, query ){ + + var groups = value; + + var groupStatements = new Array(); + + for (var i = 0; i < groups.length; i++) { + + var currentGroup = groups[i]; + + var queryString = currentGroup.query.name + "." + currentGroup.columnName; + + groupStatements.push( queryString ); + + } + + if( groupStatements.length > 0 ) { + + return " group by " + groupStatements.join(","); + + } else { + + return ""; + + } + + } + + parseStacked( name, value, query, queryID, stackedQuery ){ + + var queryString = ""; + + switch( name.toLowerCase() ) { + + case "where": + + queryString += this.parseWhereStatements( value, query ); + + break; + + case "groups": + + queryString += this.parseGroupByStatement( value, query ); + + break; + + case "order": + + queryString += this.parseOrderBy( value, query, stackedQuery ); + + break; + + case "limit": + + queryString += this.parseLimit( value ); + + break; + + case "offset": + + queryString += this.parseOffset( value ); + + break; + + } + + return queryString; + + } + + + + parseEndTerm( name, value, query, queryID ){ + + var queryString = ""; + + switch( name.toLowerCase() ) { + + case "order": + + queryString += this.parseOrderBy( value, query ); + + break; + + } + + return queryString; + + } + + parseLimit( limit ) { + + var queryString = ""; + + if( limit ) { + + console.log("limits", limit ); + + queryString += " LIMIT " + parseInt( limit ); + + + } + + return queryString; + + } + + parseOffset( offset ) { + + var queryString = ""; + + if( offset ) { + + queryString += " OFFSET " + parseInt( offset ); + + } + + return queryString; + + } + + createOrderParts( orderStatements, value ) { + + var orderParts = new Array(); + + for ( var i = 0; i < orderStatements.length; i++ ) { + + var orderStatement = orderStatements[i]; + + var columnName = orderStatement.columnName; + + var query = orderStatement.query; + + orderParts.push( tools.htmlEntities( columnName ) ); + + } + + return orderParts; + + } + + parseOrderBy( orderStatements, query, stackedQuery ) { + + var orderParts = this.createOrderParts( orderStatements ); + + var queryString = ""; + + if( orderParts.length > 0 ) { + + queryString += " ORDER BY " + orderParts.join(","); + + //console.log("parsing order by:", stackedQuery ); + + if( query.direction ) { + + //if( stackedQuery.direction.toLowerCase() == "asc" || stackedQuery.direction.toLowerCase() == "desc" ) { + + queryString += " " + query.direction + " "; + + //} + + } else { + + + /* + if( stackedQuery.direction ) { + + //if( stackedQuery.direction.toLowerCase() == "asc" || stackedQuery.direction.toLowerCase() == "desc" ) { + + queryString += " " + stackedQuery.direction + " "; + + //} + + } +*/ + + } + + } + + return queryString; + + } + + getQuotationTerm( where ) { + + var quotation = ""; + + if( where.quotation ) { + + if( where.type == "LIKE" ) { + + var quotation = "'%" + + } else { + + var quotation = "'" + + } + + } + + if( typeof where.value == "boolean" ) { + + var quotation = "" + + if( where.value ) { + + //where.value == 1; + + } else { + + //where.value == 0; + } + + } + + if( where.value == "false" ) { + + var quotation = "" + + //where.value == 0; + + } + + return quotation; + + } + + parseWhereStatement( where, ANDStatements, ORStatements ) { + + var subQuery = where.query; + + var tableName = subQuery.name + "."; + + var quotation = this.getQuotationTerm( where ); + + var quotationEnd = tools.reverseString( quotation ); + + + if( where.type != "" ) { + + var whereString = " " + tableName + where.columnName + " " + where.type + " " + quotation + where.value + quotationEnd; + + if( !where.or ) { + + ANDStatements.push( whereString ); + + } else { + + ORStatements.push( whereString ); + + } + + } + + } + + + parseWhereStatements( value, query ) { + + var queryString = ""; + + if( value.length > 0 ) { + + queryString += " where\n " + + } + + var ANDStatements = new Array(); + + var ORStatements = new Array(); + + + for( var b = 0; b < value.length;b++ ){ + + var where = value[ b ]; + + this.parseWhereStatement( where, ANDStatements, ORStatements ); + + } + + if( ORStatements.length > 0 ) { + + ANDStatements.push( "(" + ORStatements.join("\n OR\n") + ")" ); // Custom for the logical operators + + } + + queryString += ANDStatements.join("\n AND\n"); + + //console.log( "query.searchQuery", query.searchQuery); + + if( query.searchQuery ) { + + queryString += "\n AND\n " + query.searchQuery; + + } + + return queryString; + + } + + stackJoinIDS( query ) { + + var select_join_id = ""; + + for( var c = 0; c < query.joins.length; c++ ) { + + var join = query.joins[c]; + + if( c == 0 ) { + + select_join_id += "," + query.table + ".id as join_id"; + + } else { + + select_join_id += "," + query.table + ".id as join_id_" + c; + + } + + } + + return select_join_id; + + } + + parseColumns( value, queryType, query ) { + + if( queryType == "select" ) { + + if( value.length == 0 ) { + + var select_join_id = this.stackJoinIDS( query ); + + return " * " + select_join_id + " "; + + } else { + + return " " + value.join(", "); + + } + } + + return ""; + + } + + + parseTableStatement( value, query ) { + + var type = query.type; + + if( type == "select" ) { + + var select = " From " + value; + + if( query.name ) { + + select += " AS " + query.name + " "; + + } + + return select; + + } + + if( type != "join" ) { + + return value; + + } + + return ""; + + } + + parseInsertValues( query, values ) { + + var valueString = new Array( values.length ).fill("?").join(", "); + + var columnNames = query.getColumnNames(); + + return "(" + columnNames + ") VALUES (" + valueString + ")"; + + } + + parseUpdateValues( values ) { + + var updateArray = new Array(); + + for( var c = 0; c < values.length;c++ ) { + + var column = values[c]; + + updateArray[c] = column.name + " = ?"; + + } + + if( values.length == 0 ) { + + return ""; + + } + + return " SET " + updateArray.join(", "); + + } + + parseValues( query ) { + + var values = query.values; + + var type = query.type.toLowerCase(); + + switch( type ) { + + case "insert": + + return this.parseInsertValues( query, values ); + + break; + + case "update": + + return this.parseUpdateValues( values ); + + break; + + default: + + return ""; + + } + + } + + parseType( value, query, queryID ) { + + switch( value.toLowerCase() ) { + + case "select": + + return value; + + break; + + case "count": + + return "select count (*) from "; + + break; + + case "insert": + + return "Insert into "; + + break; + + case "update": + + return "update "; + + break; + + case "delete": + + return "DELETE FROM "; + + break; + + case "join": + + if( query.parent ) { + + return this.queryJoin( query, "", queryID, query.parent ); + + } + + break; + + } + + } + + queryJoin( join, queryString, joinID, parentTable ) { + + if( !parentTable.name ) { + + parentTable.name = parentTable.table; + + } + + var left = join.left; + var right = join.right; + + if( !right.table ) { + + right.table = parentTable.name; + } + + if( !left.column ) { + + left.column = "id"; + + } + + var joinType = "INNER"; + + if( join.joinType ) { + + joinType = join.joinType; + + } + + var table; + + if( join.table ) { + + table = join.table; + + } else { + + table = left.table; + + } + + if( left.table && left.column && right.table && right.column ) { + + var ON = " \n ON " + left.table + "." + left.column + " = " + right.table + "." + right.column; + + } else { + + var ON = ""; + + } + + var AS = " as " + join.name; + + return " " + joinType + " JOIN " + table + AS + ON; + + } + + + subQuery( join, queryString, name ) { + + var querys = join.querys; + + for(var c = 0; c 0x7fffffff) throw new RangeError('Option "timeout" cannot be greater than 2147483647'); + if (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the "verbose" option to be a function'); + if (nativeBindingPath != null && typeof nativeBindingPath !== 'string') throw new TypeError('Expected the "nativeBinding" option to be a string'); + + // Load the native addon + let addon; + + if ( nativeBindingPath == null ) { + + //console.log("loading Better_sqlite3.node") + + var platform = process.platform; + + var version = process.versions.modules; + + var architecture = process.arch; + + var betterSqliteVersion = "8.1.0"; + + var folderName = "better-sqlite3-v"+ betterSqliteVersion +"-node-v" + version + "-" + platform + "-" + architecture; + + + + addon = DEFAULT_ADDON || (DEFAULT_ADDON = require('../binaries/'+ folderName + "/Release/better_sqlite3.node")); + } else { + addon = require(path.resolve(nativeBindingPath).replace(/(\.node)?$/, '.node')); + } + if (!addon.isInitialized) { + addon.setErrorConstructor(SqliteError); + addon.isInitialized = true; + } + + // Make sure the specified directory exists + if (!anonymous && !fs.existsSync(path.dirname(filename))) { + throw new TypeError('Cannot open database because the directory does not exist'); + } + + Object.defineProperties(this, { + [util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) }, + ...wrappers.getters, + }); +} + +const wrappers = require('./methods/wrappers'); +Database.prototype.prepare = wrappers.prepare; +Database.prototype.transaction = require('./methods/transaction'); +Database.prototype.pragma = require('./methods/pragma'); +Database.prototype.backup = require('./methods/backup'); +Database.prototype.serialize = require('./methods/serialize'); +Database.prototype.function = require('./methods/function'); +Database.prototype.aggregate = require('./methods/aggregate'); +Database.prototype.table = require('./methods/table'); +Database.prototype.loadExtension = wrappers.loadExtension; +Database.prototype.exec = wrappers.exec; +Database.prototype.close = wrappers.close; +Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers; +Database.prototype.unsafeMode = wrappers.unsafeMode; +Database.prototype[util.inspect] = require('./methods/inspect'); + +module.exports = Database; diff --git a/source/node_modules/better-sqlite3/lib/index.js b/source/node_modules/better-sqlite3/lib/index.js new file mode 100644 index 0000000..a66e32e --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/index.js @@ -0,0 +1,3 @@ +'use strict'; +module.exports = require('./database'); +module.exports.SqliteError = require('./sqlite-error'); diff --git a/source/node_modules/better-sqlite3/lib/methods/aggregate.js b/source/node_modules/better-sqlite3/lib/methods/aggregate.js new file mode 100644 index 0000000..0417362 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/aggregate.js @@ -0,0 +1,43 @@ +'use strict'; +const { getBooleanOption, cppdb } = require('../util'); + +module.exports = function defineAggregate(name, options) { + // Validate arguments + if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string'); + if (typeof options !== 'object' || options === null) throw new TypeError('Expected second argument to be an options object'); + if (!name) throw new TypeError('User-defined function name cannot be an empty string'); + + // Interpret options + const start = 'start' in options ? options.start : null; + const step = getFunctionOption(options, 'step', true); + const inverse = getFunctionOption(options, 'inverse', false); + const result = getFunctionOption(options, 'result', false); + const safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2; + const deterministic = getBooleanOption(options, 'deterministic'); + const directOnly = getBooleanOption(options, 'directOnly'); + const varargs = getBooleanOption(options, 'varargs'); + let argCount = -1; + + // Determine argument count + if (!varargs) { + argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0); + if (argCount > 0) argCount -= 1; + if (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments'); + } + + this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly); + return this; +}; + +const getFunctionOption = (options, key, required) => { + const value = key in options ? options[key] : null; + if (typeof value === 'function') return value; + if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`); + if (required) throw new TypeError(`Missing required option "${key}"`); + return null; +}; + +const getLength = ({ length }) => { + if (Number.isInteger(length) && length >= 0) return length; + throw new TypeError('Expected function.length to be a positive integer'); +}; diff --git a/source/node_modules/better-sqlite3/lib/methods/backup.js b/source/node_modules/better-sqlite3/lib/methods/backup.js new file mode 100644 index 0000000..fe541b7 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/backup.js @@ -0,0 +1,67 @@ +'use strict'; +const fs = require('fs'); +const path = require('path'); +const { promisify } = require('util'); +const { cppdb } = require('../util'); +const fsAccess = promisify(fs.access); + +module.exports = async function backup(filename, options) { + if (options == null) options = {}; + + // Validate arguments + if (typeof filename !== 'string') throw new TypeError('Expected first argument to be a string'); + if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object'); + + // Interpret options + filename = filename.trim(); + const attachedName = 'attached' in options ? options.attached : 'main'; + const handler = 'progress' in options ? options.progress : null; + + // Validate interpreted options + if (!filename) throw new TypeError('Backup filename cannot be an empty string'); + if (filename === ':memory:') throw new TypeError('Invalid backup filename ":memory:"'); + if (typeof attachedName !== 'string') throw new TypeError('Expected the "attached" option to be a string'); + if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string'); + if (handler != null && typeof handler !== 'function') throw new TypeError('Expected the "progress" option to be a function'); + + // Make sure the specified directory exists + await fsAccess(path.dirname(filename)).catch(() => { + throw new TypeError('Cannot save backup because the directory does not exist'); + }); + + const isNewFile = await fsAccess(filename).then(() => false, () => true); + return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null); +}; + +const runBackup = (backup, handler) => { + let rate = 0; + let useDefault = true; + + return new Promise((resolve, reject) => { + setImmediate(function step() { + try { + const progress = backup.transfer(rate); + if (!progress.remainingPages) { + backup.close(); + resolve(progress); + return; + } + if (useDefault) { + useDefault = false; + rate = 100; + } + if (handler) { + const ret = handler(progress); + if (ret !== undefined) { + if (typeof ret === 'number' && ret === ret) rate = Math.max(0, Math.min(0x7fffffff, Math.round(ret))); + else throw new TypeError('Expected progress callback to return a number or undefined'); + } + } + setImmediate(step); + } catch (err) { + backup.close(); + reject(err); + } + }); + }); +}; diff --git a/source/node_modules/better-sqlite3/lib/methods/function.js b/source/node_modules/better-sqlite3/lib/methods/function.js new file mode 100644 index 0000000..f4406d4 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/function.js @@ -0,0 +1,31 @@ +'use strict'; +const { getBooleanOption, cppdb } = require('../util'); + +module.exports = function defineFunction(name, options, fn) { + // Apply defaults + if (options == null) options = {}; + if (typeof options === 'function') { fn = options; options = {}; } + + // Validate arguments + if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string'); + if (typeof fn !== 'function') throw new TypeError('Expected last argument to be a function'); + if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object'); + if (!name) throw new TypeError('User-defined function name cannot be an empty string'); + + // Interpret options + const safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2; + const deterministic = getBooleanOption(options, 'deterministic'); + const directOnly = getBooleanOption(options, 'directOnly'); + const varargs = getBooleanOption(options, 'varargs'); + let argCount = -1; + + // Determine argument count + if (!varargs) { + argCount = fn.length; + if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError('Expected function.length to be a positive integer'); + if (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments'); + } + + this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly); + return this; +}; diff --git a/source/node_modules/better-sqlite3/lib/methods/inspect.js b/source/node_modules/better-sqlite3/lib/methods/inspect.js new file mode 100644 index 0000000..cd9fd6d --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/inspect.js @@ -0,0 +1,7 @@ +'use strict'; +const DatabaseInspection = function Database() {}; + +module.exports = function inspect(depth, opts) { + return Object.assign(new DatabaseInspection(), this); +}; + diff --git a/source/node_modules/better-sqlite3/lib/methods/pragma.js b/source/node_modules/better-sqlite3/lib/methods/pragma.js new file mode 100644 index 0000000..a275ab0 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/pragma.js @@ -0,0 +1,12 @@ +'use strict'; +const { getBooleanOption, cppdb } = require('../util'); + +module.exports = function pragma(source, options) { + if (options == null) options = {}; + if (typeof source !== 'string') throw new TypeError('Expected first argument to be a string'); + if (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object'); + const simple = getBooleanOption(options, 'simple'); + + const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true); + return simple ? stmt.pluck().get() : stmt.all(); +}; diff --git a/source/node_modules/better-sqlite3/lib/methods/serialize.js b/source/node_modules/better-sqlite3/lib/methods/serialize.js new file mode 100644 index 0000000..4f1374f --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/serialize.js @@ -0,0 +1,16 @@ +'use strict'; +const { cppdb } = require('../util'); + +module.exports = function serialize(options) { + if (options == null) options = {}; + + // Validate arguments + if (typeof options !== 'object') throw new TypeError('Expected first argument to be an options object'); + + // Interpret and validate options + const attachedName = 'attached' in options ? options.attached : 'main'; + if (typeof attachedName !== 'string') throw new TypeError('Expected the "attached" option to be a string'); + if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string'); + + return this[cppdb].serialize(attachedName); +}; diff --git a/source/node_modules/better-sqlite3/lib/methods/table.js b/source/node_modules/better-sqlite3/lib/methods/table.js new file mode 100644 index 0000000..eac658e --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/table.js @@ -0,0 +1,189 @@ +'use strict'; +const { cppdb } = require('../util'); + +module.exports = function defineTable(name, factory) { + // Validate arguments + if (typeof name !== 'string') throw new TypeError('Expected first argument to be a string'); + if (!name) throw new TypeError('Virtual table module name cannot be an empty string'); + + // Determine whether the module is eponymous-only or not + let eponymous = false; + if (typeof factory === 'object' && factory !== null) { + eponymous = true; + factory = defer(parseTableDefinition(factory, 'used', name)); + } else { + if (typeof factory !== 'function') throw new TypeError('Expected second argument to be a function or a table definition object'); + factory = wrapFactory(factory); + } + + this[cppdb].table(factory, name, eponymous); + return this; +}; + +function wrapFactory(factory) { + return function virtualTableFactory(moduleName, databaseName, tableName, ...args) { + const thisObject = { + module: moduleName, + database: databaseName, + table: tableName, + }; + + // Generate a new table definition by invoking the factory + const def = apply.call(factory, thisObject, args); + if (typeof def !== 'object' || def === null) { + throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`); + } + + return parseTableDefinition(def, 'returned', moduleName); + }; +} + +function parseTableDefinition(def, verb, moduleName) { + // Validate required properties + if (!hasOwnProperty.call(def, 'rows')) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`); + } + if (!hasOwnProperty.call(def, 'columns')) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`); + } + + // Validate "rows" property + const rows = def.rows; + if (typeof rows !== 'function' || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`); + } + + // Validate "columns" property + let columns = def.columns; + if (!Array.isArray(columns) || !(columns = [...columns]).every(x => typeof x === 'string')) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`); + } + if (columns.length !== new Set(columns).size) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`); + } + if (!columns.length) { + throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`); + } + + // Validate "parameters" property + let parameters; + if (hasOwnProperty.call(def, 'parameters')) { + parameters = def.parameters; + if (!Array.isArray(parameters) || !(parameters = [...parameters]).every(x => typeof x === 'string')) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`); + } + } else { + parameters = inferParameters(rows); + } + if (parameters.length !== new Set(parameters).size) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`); + } + if (parameters.length > 32) { + throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`); + } + for (const parameter of parameters) { + if (columns.includes(parameter)) { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`); + } + } + + // Validate "safeIntegers" option + let safeIntegers = 2; + if (hasOwnProperty.call(def, 'safeIntegers')) { + const bool = def.safeIntegers; + if (typeof bool !== 'boolean') { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`); + } + safeIntegers = +bool; + } + + // Validate "directOnly" option + let directOnly = false; + if (hasOwnProperty.call(def, 'directOnly')) { + directOnly = def.directOnly; + if (typeof directOnly !== 'boolean') { + throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`); + } + } + + // Generate SQL for the virtual table definition + const columnDefinitions = [ + ...parameters.map(identifier).map(str => `${str} HIDDEN`), + ...columns.map(identifier), + ]; + return [ + `CREATE TABLE x(${columnDefinitions.join(', ')});`, + wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName), + parameters, + safeIntegers, + directOnly, + ]; +} + +function wrapGenerator(generator, columnMap, moduleName) { + return function* virtualTable(...args) { + /* + We must defensively clone any buffers in the arguments, because + otherwise the generator could mutate one of them, which would cause + us to return incorrect values for hidden columns, potentially + corrupting the database. + */ + const output = args.map(x => Buffer.isBuffer(x) ? Buffer.from(x) : x); + for (let i = 0; i < columnMap.size; ++i) { + output.push(null); // Fill with nulls to prevent gaps in array (v8 optimization) + } + for (const row of generator(...args)) { + if (Array.isArray(row)) { + extractRowArray(row, output, columnMap.size, moduleName); + yield output; + } else if (typeof row === 'object' && row !== null) { + extractRowObject(row, output, columnMap, moduleName); + yield output; + } else { + throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`); + } + } + }; +} + +function extractRowArray(row, output, columnCount, moduleName) { + if (row.length !== columnCount) { + throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`); + } + const offset = output.length - columnCount; + for (let i = 0; i < columnCount; ++i) { + output[i + offset] = row[i]; + } +} + +function extractRowObject(row, output, columnMap, moduleName) { + let count = 0; + for (const key of Object.keys(row)) { + const index = columnMap.get(key); + if (index === undefined) { + throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`); + } + output[index] = row[key]; + count += 1; + } + if (count !== columnMap.size) { + throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`); + } +} + +function inferParameters({ length }) { + if (!Number.isInteger(length) || length < 0) { + throw new TypeError('Expected function.length to be a positive integer'); + } + const params = []; + for (let i = 0; i < length; ++i) { + params.push(`$${i + 1}`); + } + return params; +} + +const { hasOwnProperty } = Object.prototype; +const { apply } = Function.prototype; +const GeneratorFunctionPrototype = Object.getPrototypeOf(function*(){}); +const identifier = str => `"${str.replace(/"/g, '""')}"`; +const defer = x => () => x; diff --git a/source/node_modules/better-sqlite3/lib/methods/transaction.js b/source/node_modules/better-sqlite3/lib/methods/transaction.js new file mode 100644 index 0000000..25a3519 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/transaction.js @@ -0,0 +1,75 @@ +'use strict'; +const { cppdb } = require('../util'); +const controllers = new WeakMap(); + +module.exports = function transaction(fn) { + if (typeof fn !== 'function') throw new TypeError('Expected first argument to be a function'); + + const db = this[cppdb]; + const controller = getController(db, this); + const { apply } = Function.prototype; + + // Each version of the transaction function has these same properties + const properties = { + default: { value: wrapTransaction(apply, fn, db, controller.default) }, + deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) }, + immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) }, + exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) }, + database: { value: this, enumerable: true }, + }; + + Object.defineProperties(properties.default.value, properties); + Object.defineProperties(properties.deferred.value, properties); + Object.defineProperties(properties.immediate.value, properties); + Object.defineProperties(properties.exclusive.value, properties); + + // Return the default version of the transaction function + return properties.default.value; +}; + +// Return the database's cached transaction controller, or create a new one +const getController = (db, self) => { + let controller = controllers.get(db); + if (!controller) { + const shared = { + commit: db.prepare('COMMIT', self, false), + rollback: db.prepare('ROLLBACK', self, false), + savepoint: db.prepare('SAVEPOINT `\t_bs3.\t`', self, false), + release: db.prepare('RELEASE `\t_bs3.\t`', self, false), + rollbackTo: db.prepare('ROLLBACK TO `\t_bs3.\t`', self, false), + }; + controllers.set(db, controller = { + default: Object.assign({ begin: db.prepare('BEGIN', self, false) }, shared), + deferred: Object.assign({ begin: db.prepare('BEGIN DEFERRED', self, false) }, shared), + immediate: Object.assign({ begin: db.prepare('BEGIN IMMEDIATE', self, false) }, shared), + exclusive: Object.assign({ begin: db.prepare('BEGIN EXCLUSIVE', self, false) }, shared), + }); + } + return controller; +}; + +// Return a new transaction function by wrapping the given function +const wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() { + let before, after, undo; + if (db.inTransaction) { + before = savepoint; + after = release; + undo = rollbackTo; + } else { + before = begin; + after = commit; + undo = rollback; + } + before.run(); + try { + const result = apply.call(fn, this, arguments); + after.run(); + return result; + } catch (ex) { + if (db.inTransaction) { + undo.run(); + if (undo !== rollback) after.run(); + } + throw ex; + } +}; diff --git a/source/node_modules/better-sqlite3/lib/methods/wrappers.js b/source/node_modules/better-sqlite3/lib/methods/wrappers.js new file mode 100644 index 0000000..1d4673e --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/methods/wrappers.js @@ -0,0 +1,54 @@ +'use strict'; +const { cppdb } = require('../util'); + +exports.prepare = function prepare(sql) { + return this[cppdb].prepare(sql, this, false); +}; + +exports.exec = function exec(sql) { + this[cppdb].exec(sql); + return this; +}; + +exports.close = function close() { + this[cppdb].close(); + return this; +}; + +exports.loadExtension = function loadExtension(...args) { + this[cppdb].loadExtension(...args); + return this; +}; + +exports.defaultSafeIntegers = function defaultSafeIntegers(...args) { + this[cppdb].defaultSafeIntegers(...args); + return this; +}; + +exports.unsafeMode = function unsafeMode(...args) { + this[cppdb].unsafeMode(...args); + return this; +}; + +exports.getters = { + name: { + get: function name() { return this[cppdb].name; }, + enumerable: true, + }, + open: { + get: function open() { return this[cppdb].open; }, + enumerable: true, + }, + inTransaction: { + get: function inTransaction() { return this[cppdb].inTransaction; }, + enumerable: true, + }, + readonly: { + get: function readonly() { return this[cppdb].readonly; }, + enumerable: true, + }, + memory: { + get: function memory() { return this[cppdb].memory; }, + enumerable: true, + }, +}; diff --git a/source/node_modules/better-sqlite3/lib/sqlite-error.js b/source/node_modules/better-sqlite3/lib/sqlite-error.js new file mode 100644 index 0000000..28a9a18 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/sqlite-error.js @@ -0,0 +1,20 @@ +'use strict'; +const descriptor = { value: 'SqliteError', writable: true, enumerable: false, configurable: true }; + +function SqliteError(message, code) { + if (new.target !== SqliteError) { + return new SqliteError(message, code); + } + if (typeof code !== 'string') { + throw new TypeError('Expected second argument to be a string'); + } + Error.call(this, message); + descriptor.value = '' + message; + Object.defineProperty(this, 'message', descriptor); + Error.captureStackTrace(this, SqliteError); + this.code = code; +} +Object.setPrototypeOf(SqliteError, Error); +Object.setPrototypeOf(SqliteError.prototype, Error.prototype); +Object.defineProperty(SqliteError.prototype, 'name', descriptor); +module.exports = SqliteError; diff --git a/source/node_modules/better-sqlite3/lib/util.js b/source/node_modules/better-sqlite3/lib/util.js new file mode 100644 index 0000000..0328c84 --- /dev/null +++ b/source/node_modules/better-sqlite3/lib/util.js @@ -0,0 +1,12 @@ +'use strict'; + +exports.getBooleanOption = (options, key) => { + let value = false; + if (key in options && typeof (value = options[key]) !== 'boolean') { + throw new TypeError(`Expected the "${key}" option to be a boolean`); + } + return value; +}; + +exports.cppdb = Symbol(); +exports.inspect = Symbol.for('nodejs.util.inspect.custom'); diff --git a/source/node_modules/better-sqlite3/package.json b/source/node_modules/better-sqlite3/package.json new file mode 100644 index 0000000..ffb5b33 --- /dev/null +++ b/source/node_modules/better-sqlite3/package.json @@ -0,0 +1,4 @@ +{ + "name":"better-sqlite3", + "main": "lib/index.js" +} diff --git a/source/node_modules/better-sqlite3/unify b/source/node_modules/better-sqlite3/unify new file mode 100644 index 0000000..64bc189 --- /dev/null +++ b/source/node_modules/better-sqlite3/unify @@ -0,0 +1,5 @@ +// binaries 108 = v18.17.0 + +// https://sourceforge.net/projects/better-sqlite3.mirror/files/v8.1.0/ + +// https://nodejs.org/en/download/releases \ No newline at end of file diff --git a/source/querySQL.js b/source/querySQL.js new file mode 100644 index 0000000..fc95c38 --- /dev/null +++ b/source/querySQL.js @@ -0,0 +1,483 @@ + + +import tools from './tools.js'; + +export default class querySQL{ + + __className = "querySQL"; + + type = "select"; + + columns = new Array(); + + table; + + sync = true; + + + values = new Array(); + + objects = new Array(); + + where = new Array(); + + groups = new Array(); + + union = new Array(); + + order = new Array(); + + direction; + + limit; + + count; + + from; + + to; + + joins = new Array(); + + filter = false; + + filterAddress = ""; + + + + constructor( query ) { + + if( query ) { + + var items = Object.entries( query ); + + var queryString = ""; + + for(var c = 0; c' : 'gt', + '"' : 'quot', + '&' : 'amp', + '\'' : '#39' + }; + + var regexString = '['; + + for(var key in escapeChars) { + + regexString += key; + + } + + regexString += ']'; + + var regex = new RegExp( regexString, 'g'); + + return str.replace(regex, function( m ) { + + return '&' + escapeChars[ m ] + ';'; + + }); + + } + + reverseString( string ) { + + var splitString = string.split(""); + + var reverseArray = splitString.reverse(); + + var joinArray = reverseArray.join(""); + + return joinArray; + + } + + + + slash( path ) { + + const isExtendedLengthPath = /^\\\\\?\\/.test(path); + + if ( isExtendedLengthPath ) { + + return path; + + } + + return path.replace(/\\/g, '/'); + + } + + serializeString( json ) { + + if( Buffer.isBuffer( json ) ) { + + return json.toString(); + + } else { + + return json; + } + + } + + isJsonString( str ) { + + try { + + JSON.parse( str ); + + } catch (e) { + + return false; + + } + + return true; + + } + + serializeJSON( json ) { + + if( this.isJsonString( json ) ) { + + return JSON.parse( json ); + + } + + } + + createOrderedArray( array ) { + + var keys = Object.keys( array ); + + var output = new Array(); + + for ( var i = 0; i < keys.length; i++ ) { + + var key = keys[i]; + + output[ i ] = array[ key ]; + + } + + return output; + + } + + getEnvironment() { + + if( typeof document != "undefined" ) { + + return "Browser"; + + } + + if( global ) { + + return "Node" + + } + + } + + // Security + getObjectByPath( application, applicationPath ) { + + var objectName = applicationPath.pop(); + + //console.log("getObjectByPath", objectName); + + if( !application[ objectName ] || typeof objectName != "string" ) { + + throw new Error('Get object by Path Failed, Faulty path'); + + } + + var currentApplication = application[ objectName ]; + + if( !currentApplication ) { + + throw new Error( 'Get object by Path Failed, Faulty path' ); + + } + + if( applicationPath.length > 0 ) { + + return this.getObjectByPath( currentApplication, applicationPath ); + + } else { + + return currentApplication; + + } + + } + + isNumber( value ) { + + return ( typeof value === 'number' && isFinite( value ) ); + + } + + isNumberObject( n ) { + + return ( Object.prototype.toString.apply( n ) === '[object Number]' ); + + } + + isCustomNumber( n ) { + + return this.isNumber( n ) || this.isNumberObject( n ); + + } + + structuredClone( object ) { + + var prototype = Object.getPrototypeOf( object ); + + var create = Object.create( prototype ); + + return Object.assign( create , object ); + + } + + extendedClassIsColumn() { + + + } + + isUnifyColumn( object ) { + + var extendedClasses = this.getExtendedClassesMulti( object ); + + var isColumn = false; + + for ( var j = 0; j < extendedClasses.length; j++ ) { + + var extendedClass = extendedClasses[j] + + var className = this.getClassName( extendedClass ); + + if( className == "column" ) { + + isColumn = object; + + } + + } + + return isColumn; + + } + + filterPrims( item, prims, type ) { + + if( prims[ type ].hasOwnProperty( item ) ) { + + return false; + + } else { + + prims[ type ][ item ] = true; + + return true; + + } + + } + + filterObjects( item ) { + + var filterObjects = this.filterObjects; + + if( filterObjects.indexOf( item ) >= 0 ) { + + return false; + + } else { + + filterObjects.push( item ); + + return filterObjects; + + } + + } + + uniqueFilter( item ) { + + var type = typeof item; + + var prims = this.prims; + + if( type in prims ) { + + return this.filterPrims( item, prims, type ); + + } else { + + return this.filterObjects( item ); + + } + + } + + uniqueArrayRows( a ) { + + this.prims = new Object(); + + this.prims.boolean = new Object(); + + this.prims.number = new Object(); + + this.prims.string = new Object(); + + + this.filterObjects = new Array(); + + + return a.filter( this.uniqueFilter.bind( this ) ); + + } + + simpleClone( object ) { + + var prototype = Object.getPrototypeOf( object ); + + var created = Object.create( prototype ); + + let clone = Object.assign( created, object ); + + return clone; + + } + + getPrototypeRecursive( object, properties = new Array() ) { + + properties.push( ...Object.getOwnPropertyNames( object ) ) + + var prototype = Object.getPrototypeOf( object ) + + if( prototype ) { + + return this.getPrototypeRecursive( prototype, properties ); + + } else { + + return properties; + + } + + } + + filterFunctions( element, index, arr ) { + + var nextElement = arr[ index + 1]; + + var elementType = typeof this[ element ]; + + if ( element != nextElement && elementType == "function" ){ + + return true; + + } + + } + + getAllFuncs( object ) { + + var properties = this.getPrototypeRecursive( object ); + + var sorted = properties.sort(); + + var filterd = sorted.filter( this.filterFunctions.bind( object ) ) + + return filterd; + + } + + createRandomKey( numCharacters ) { + + var token = ""; + + for ( var i = 0; i < numCharacters; i++ ) { + + token += Math.floor( Math.random() * 10 ); + + } + + return token; + + } + + isCSSProperty( propertyName ) { + + var object = definitions.css; + + if( typeof object[propertyName] !== 'undefined' ) { + + return true; + + } else { + + return false; + + } + + } + + hasUserPrototype( obj ) { + + return obj.constructor !== Object; + + } + + addTabToArrayLines( lines, numSpaces ) { + + var tabbedRows = new Array(); + + for ( var i = 0; i < lines.length; i++ ) { + + var row = lines[i]; + + tabbedRows[i] = "".padEnd( numSpaces ) + row; + + } + + return tabbedRows; + + } + + addTabToBeginOfString( string, numSpaces ) { + + var lines = string.split("\n"); + + var tabbedRows = this.addTabToArrayLines( lines, numSpaces ); + + return tabbedRows.join("\n"); + + } + + addTabToBegin( string, numSpaces ) { + + if( typeof string == "string" ) { + + return this.addTabToBeginOfString( string, numSpaces ); + + } else { + + return string; + } + + } + + getChildFromEntry( parent, entry, children ) { + + const invalid = new Array( "parent", "table", "user" ); + + var name = this.getClassNameByEntry( entry ); + + var child = this.getObjectByEntry( entry ); + + + if( !this.isUnifyObject( name, child ) ) { + + return false; + + } + + if( invalid.includes( name ) ) { + + return false; + + } + + child.propertyName = name; + + child.parent = parent; + + children.push( child ); + + } + + getChildren( object, bindParent = true ) { + + var children = new Array(); + + var entries = Object.entries( object ); + + for( var c = 0; c < entries.length; c++ ){ + + var entry = entries[ c ]; + + this.getChildFromEntry( object, entry, children ); + + } + + return children; + + } + + addPropertyToArray( property, properties ) { + + const invalid = new Array( "user" ); + + if( this.isUnifyObject( property.name, property.value ) ) { + + return false; + + } + + if( invalid.includes( property.name ) ) { + + return false; + + } + + properties.push( property ); + + } + + createPropertyFromEntry( entry ) { + + var name = this.getClassNameByEntry( entry ); + + var object = this.getObjectByEntry( entry ); + + + var property = new Object(); + + property.name = name; + + property.value = object; + + return property; + + } + + getProperties( object ) { + + var properties = new Array(); + + var entries = Object.entries( object ); + + for( var c = 0; c < entries.length; c++ ){ + + var entry = entries[c]; + + var property = this.createPropertyFromEntry( entry ) ; + + + this.addPropertyToArray( property, properties ) + + } + + return properties; + + } + + replaceChildWithFragment( source, newType ) { + + const frag = document.createDocumentFragment(); + + while ( source.firstChild ) { + + frag.appendChild( source.firstChild ); + + } + + const newElem = document.createElement( newType ); + + newElem.appendChild( frag ); + + source.parentNode.replaceChild( newElem, source ); + + } + + replaceElement( source, newType, parentElement ) { + + if( parentElement ) { + + source.parentNode = parentElement; + + } + + if( source.tagName != newType.toUpperCase() ) { + + this.replaceChildWithFragment( source, newType ); + + } + + } + + parseObject( object ) { + + var entries = Object.entries( object ); + + return entries[0]; + + } + + getFirstEntry( object ) { + + var entries = Object.entries( object ); + + if( entries[0] ) { + + return entries[0]; + + } else { + + return false; + + } + + } + + getExtendedClass( object ) { + + if( !object.prototype ) { + + object = object.constructor; + + } + + return object.prototype.__proto__; + + } + + removeDuplicates( arr ) { + + return arr.filter( ( item, index ) => arr.indexOf( item ) === index ); + + } + + removeEmptyRows( arr ) { + + return arr.filter( n => n ); + + } + + isVisible( element ) { + + if( !element ) { + + return false; + + } + + if( !element.offsetWidth ) { + + return false; + + } + + return element.offsetWidth > 0 || element.offsetHeight > 0; + + } + + getExtendedObjects( object ) { + + if( !object.getClassName ) { + + return false; + + } + + if( typeof document == "undefined" ){ + + var extendedObjects = global.extendMap[ object.getClassName() ]; + + } else { + + var extendedObjects = document.extendMap[ object.getClassName() ]; + + } + + return extendedObjects; + + } + + getSingleExtendedClassInArray( object ) { + + if( !object.prototype ) { + + object = object.constructor; + + } + + var extendedClass = this.getExtendedClass( object ); + + if( !extendedClass ) { + + return false; + + } else { + + return new Array( new extendedClass.constructor() ); + + } + + } + + getExtendedClassesMulti( object ) { + + var extendedObjects = this.getExtendedObjects( object ); + + if( extendedObjects ) { + + return extendedObjects; + + } else { + + return this.getSingleExtendedClassInArray( object ); + + } + + } + + getExtendedClassName( object ) { + + return this.getClassName( this.getExtendedClass( object ) ); + + } + + logError( message ) { + + console.log( this.consoleColors().red( message ) ); + + } + + debugVar( object, variable ) { + + var colors = this.consoleColors(); + + var path = this.getApplicationPath(object); + + var pathColor = colors.red( "(" + path.toString() + ")" ); + + var variableColor = colors.magenta( variable ); + + console.log( variableColor + pathColor ); + + } + + logParameter2( parameter2 ) { + + if( typeof parameter2 == "string" ) { + + console.log( parameter2 ); + + } else { + + this.logObject( parameter2 ); + + } + + } + + log( parameter1, parameter2, parameter3 ) { + + var colors = this.consoleColors(); + + if( typeof parameter1 == "string" ) { + + console.log( colors.yellow("\n\n" + parameter1) ); + + } else { + + this.logObject( parameter1 ); + + } + + if( parameter2 ) { + + this.logParameter2( parameter2 ); + + } + + } + + log( ...value ) { + + for (var i = 0; i < value.length; i++) { + + console.log( util.inspect( value[i], { showHidden: false, depth: 1, colors: true }) ) + + } + + } + + + logObject( object ) { + + var colors = this.consoleColors(); + + var path = this.getApplicationPath(object); + + var pathColor = colors.red( "(" + path.reverse().toString() + ")" ); + + + console.log( pathColor + " " + this.getClassName( object ) ); + + console.log( this.serialize( object ) ); + + } + + saveImportDefault( importObject ) { + + if( importObject.default ) { + + return importObject.default; + + } else { + + console.log("error2 ", url, " does not exist"); + + } + + } + + async saveImport( url ) { + + var importObject = await import( url ); + + if( importObject ) { + + return this.saveImportDefault( importObject ); + + } else { + + console.log("error1 ", url, " does not exist"); + + } + + } + + getApplicationDepth( object ) { + + return this.getApplicationPath( object ).length; + + } + + getParentApplicationPath( object, array ) { + + array.push( object.propertyName ); + + return this.getApplicationPath( object.parent, array ); + + } + + getApplicationPath( object, array = new Array() ) { + + if( object.parent ) { + + return this.getParentApplicationPath( object, array ) + + } else { + + return array; + + } + + } + + getClassName( object ) { + + if( object.__className ) { + + return object.__className; + + } + + if( !object ) { + + return false; + + } + + return object.constructor.name; + + //var rollupFix = object.constructor.name.split("$")[0].split("$")[0]; + + //var webPackFix = rollupFix.split("_") + + //return rollupFix; + + //return webPackFix[webPackFix.length-1]; + + } + + getID( object ){ + + if( object.id ){ + + return object.id; + + } else { + + return ""; + + } + + } + + getClassNameByObject( object ) { + + if( typeof object == "string" ) { + + return object; + + } + + var entry = this.parseObject( object ); + + var className = this.getClassNameByEntry( entry ); + + return className; + + } + + getClassNameByEntry( entry ) { + + return entry[0]; + + } + + getObjectByEntry( entry ) { + + if( entry[1] ) { + + return entry[1]; + + } else { + + return false; + + } + + } + + logObject( object, message ) { + + if( object.debug ) { + + console.log( message, object.getClassName(), "\n" ); + + } + + } + + + getFirstEntryName( object ) { + + var entries = Object.entries( object ); + + return entries[0][0]; + + } + + delay( millisec ) { + + return new Promise(resolve => { + setTimeout(() => { resolve('') }, millisec); + }) + + } + + + getPropertyNameWithID( object ) { + + if( object.id ) { + + // bug // + "_" + object.id; todo: Make that only id is added when css content differs from other rows/ids + // object.propertyName.replace( object.id, "" ) is, Unify objects rendered by rendercollections have an id in the propertyName + // This results in double ids + + return this.CamelCase( object.propertyName ) + "_" + object.id; + + } else { + + return this.CamelCase( object.propertyName ); + + } + + if( !propertyName ) { + + return ""; + + } + + } + + createCSSClassName( object ) { + + var propertyName = this.getPropertyNameWithID( object ); + + if( object.parent ) { + + object = object.parent; + + } + + return this.getClassName( object ) + propertyName; + + } + + CamelCase( string ){ + + if( !string ) { + + return false; + + } + + string = string.toUpperCase(); + + string = string[0].toUpperCase() + string.slice( 1, string.length ).toLowerCase(); + + return string; + + } + + firstLowerCase( string ){ + + if( string ) { + + return string[0].toLowerCase() + string.slice( 1, string.length ); + + } else { + + return false; + + } + + } + + cleanRollup( term ) { + + return term; + + // Deprecated + //return term.replaceAll("$0", "").replaceAll("$1", "").replaceAll("$2", ""); + + } + + cleanEntry( entry ) { + + const invalid = new Array( "parent", "table", "user", "objectToManipulate" ); + + var name = this.getClassNameByEntry( entry ); + + var object = this.getObjectByEntry( entry ); + + if( invalid.includes( name ) ) { + + delete object[name]; + + } + + } + + cleanObject( object ) { + + var entries = Object.entries( this ); + + for ( var i = 0; i < entries.length; i++ ) { + + var entry = entries[i]; + + this.cleanEntry( entry ); + + } + + } + + objectExtendsTablePrimitive( object ) { + + var extendedClass = this.getExtendedClass( object ); + + if( !extendedClass ) { + + return false; + + } + + var className = this.getClassName( extendedClass ); + + if( className == "table" ) { + + return true; + + } else { + + return false; + + } + + } + + objectIsTable( object ) { + + if( !object ) { + + return false; + + } + + if( !object.prototype ) { + + object = object.constructor; + + } + + return this.objectExtendsTablePrimitive( object ); + + } + + extendIsRenderCollection( object ) { + + var extendedClass = this.getExtendedClass( object ); + + var className = this.getClassName( extendedClass ); + + if( className == "renderCollection" ) { + + return true; + + } else { + + return false; + + } + + } + + objectIsRenderCollection( object ) { + + var className = this.getClassName( object ); + + if( className == "renderCollection" ) { + + return true; + + } + + if( !object.prototype ) { + + object = object.constructor; + + } + + return this.extendIsRenderCollection( object ); + + } + + getTableName( object ) { + + if( !this.objectIsTable( object ) ) { + + object = this.getTableFromObject( object ); + + } + + var className = this.getClassName( object ); + + return className; + + } + + isTableInHierarchy( object ) { + + + } + + getParentWithTable( object, tableName ) { + + if( this.getClassName( this.getTableFromObject( object ) ) == tableName ) { + + return object; + + } else { + + return this.getParentWithTable( object.parent, tableName ); + + } + + } + + classNameIsTable( className ) { + + // todo deprecated? + //if( className == "table" || className == "unify_table_table" || className == "server_table_table" || className == "table_table" ) { + + if( className == "table" ){ + + return true; + + } else { + + return false; + + } + + } + + evaluateExtendedClass( object, extendedClass ) { + + var className = this.getClassName( extendedClass ); + + if( this.classNameIsTable( className ) ) { + + return object; + + } + + var table = this.getTableFromObject( extendedClass ); + + if( table ) { + + return table; + + } else { + + return false; + + } + + } + + getTableFromExtendedClasses( object, extendedClasses ) { + + for ( var i = 0; i < extendedClasses.length; i++ ) { + + var extendedClass = extendedClasses[i]; + + var table = this.evaluateExtendedClass( object, extendedClass ); + + if( table ) { + + return table; + + } + + } + + } + + getTableFromObject( object ) { + + if( object.table ) { + + return object.table; + + } + + var className = this.getClassName( object ); + + if( className ) { + + var extendedClasses = this.getExtendedClassesMulti( object ); + + return this.getTableFromExtendedClasses( object, extendedClasses ); + + } else { + + console.log("classname not found",object); + + } + + } + + isServerValue( name, value ){ + + const invalid = new Array( "style", "type", "label", "flexDirection", "boxPadding", "width", "DOM_ELEMENT" ); + + const valid = new Array( "rows" ); + + if( valid.includes( name ) ){ + + return true; + + } + + if( invalid.includes( name ) ){ + + return false; + + } + + if( this.css.propertyIsStyle( name ) ) { + + return false; + + } + + if( typeof value == "number" ){ + + return true; + + } + + if( typeof value == "string" ){ + + return true; + + } else { + + return false; + + } + + } + + deleteNormalBrowserEvent( object, browserEvent ) { + + if( object[ browserEvent ] ) { + + delete object[ browserEvent ]; + + } + + } + + deleteServerBrowserEvent( object, browserEvent ) { + + if( object[ "server" + this.CamelCase( browserEvent ) ] ) { + + delete object[ "server" + this.CamelCase( browserEvent ) ]; + + } + + } + + + groomBrowserEvents( object ) { + + var browserEvents = definitions.browserEvents; + + for ( var i = 0; i < browserEvents.length; i++ ) { + + var browserEvent = browserEvents[ i ]; + + this.deleteNormalBrowserEvent( object, browserEvent ); + + this.deleteServerBrowserEvent( object, browserEvent ); + + } + + } + + getCircularReplacer( key, value ) { + + if ( typeof value === "object" && value !== null ) { + + if ( this.seen.has( value ) ) { + + return; + + } + + this.seen.add( value ); + + } + + return value; + + } + + sizeOf( object ) { + + this.seen = new WeakSet(); + + var stringObject = JSON.stringify( object, this.getCircularReplacer.bind( this ) ); + // OR stringObject = JSON.stringify( object, ( key, value ) => this.getCircularReplacer( key, value ) ); + + var finalObject = JSON.parse( stringObject ); + + return global.objectSizeof( finalObject ); + + } + + groomCssProperties( object, propertyName ) { + + var propertyNameWithoutBox = propertyName.replace("box", ""); + + if( this.css.propertyHasStyle( propertyNameWithoutBox ) ) { + + delete object[ propertyName ]; + + } + + } + + groomRemainingProperties( object, propertyName, propertyValue ) { + + //if( !this.isServerValue( propertyName, propertyValue ) && !this.isUnifyObject(propertyName, propertyValue ) ) { + + // delete object[ propertyName ]; + + //} + + } + + groomPermissionMethods( object ) { + + if( object.enableWRITE ) { + + delete object.enableWRITE; + + } + + if( object.disableWRITE ) { + + delete object.disableWRITE; + + } + + if( object.enableREAD ) { + + delete object.enableREAD; + + } + + if( object.disableREAD ) { + + delete object.disableREAD; + + } + + if( object.enableDELETE ) { + + delete object.enableDELETE; + + } + + if( object.disableDELETE ) { + + delete object.disableDELETE; + + } + + } + + groomBrowserMethods( object ) { + + if( object.create ) { + + delete object.create; + + } + + if( object.update ) { + + delete object.update; + + } + + if( object.afterLoad ) { + + delete object.afterLoad; + + } + + } + + groomEntry( entry, object ) { + + var propertyName = this.getClassNameByEntry( entry ); + + var propertyValue = this.getObjectByEntry( entry ); + + + this.groomPermissionMethods( object ); + + this.groomBrowserMethods( object ); + + this.groomBrowserEvents( object ); + + this.groomCssProperties( object, propertyName ); + + this.groomRemainingProperties( object, propertyName, propertyValue ); + + + if( this.isUnifyObject(propertyName, propertyValue ) ) { + + this.groomApplicationObject( propertyValue ); + + } + + return object; + + } + + groomApplicationObject( object ) { + + var entries = Object.entries( object ); + + for( var c = 0; c < entries.length; c++ ) { + + var entry = entries[c]; + + this.groomEntry( entry, object ); + + } + + return object; + + } + + serializeEntry( entry, serializedObject ) { + + var propertyName = this.getClassNameByEntry( entry ); + + var propertyValue = this.getObjectByEntry( entry ); + + this.serializeProperty( propertyName, propertyValue, serializedObject ); + + } + + serializeEntries( entries ) { + + var serializedObject = new Object(); + + for( var c = 0; c < entries.length; c++ ) { + + var entry = entries[c]; + + this.serializeEntry( entry, serializedObject ); + + } + + return serializedObject; + + } + + serialize( object, is_root = true, cut ){ + + var entries = Object.entries( object ); + + this.serializeEntries( entries ); + + return this.createOuterObject( object, serializedObject, is_root ); + + } + + serializeServerProperty( object, propertyName, propertyValue ) { + + object[ propertyName ] = propertyValue; + + } + + serializedUnifyObject( object, propertyName, propertyValue ) { + + object[ propertyName ] = this.serialize( propertyValue, false ); + + } + + serializeProperty( propertyName, propertyValue, object ) { + + if( this.isServerValue( propertyName, propertyValue ) ) { + + this.serializeServerProperty( object, propertyName, propertyValue ); + + } + + if( this.isUnifyObject(propertyName, propertyValue ) ) { + + this.serializedUnifyObject( object, propertyName, propertyValue ); + + } + + return object; + + } + + isArray( array ) { + + if( !array ) { + + return false; + + } + + return Array.isArray( array ); + + } + + validateNumber( value ) { + + if( typeof value == "number" ) { + + return value; + + } else { + + return false; + + } + + } + + validateString( value ) { + + if( typeof value == "string" ) { + + return value; + + } else { + + return false; + + } + + } + + validateValue( value ) { + + if( typeof value == "string" || typeof value == "number" || typeof value == "boolean" ) { + + return value; + + } else { + + return false; + + } + + } + + validateBoolean( value ) { + + if( typeof value == "boolean" ) { + + return value; + + } else { + + return false; + + } + + } + + validateArray( values ) { + + if( !this.isArray( values ) ) { + + return false; + + } + + for( var c = 0; c < values.length; c++ ) { + + values[ c ] = this.validateString( values[ c ] ); + + } + + return values; + + } + + + is_allowed_value( value ) { + + if( this.is_int( value ) ) { + + return true; + + } + + if( this.is_text( value ) ) { + + return true; + + } + + if( this.is_boolean( value ) ) { + + return true; + + } + + if( this.is_object( value ) ) { + + return true; + + } + + return false; + + } + + is_float( value ) { + + if( typeof value == "number" ) { + + return true; + + } else { + + return false; + + } + + } + + is_number( value ) { + + if( typeof value == "number" ) { + + return true; + + } else { + + return false; + + } + + } + + is_object( value ) { + + if( typeof value == "object" ) { + + return true; + + } else { + + return false; + + } + + } + + is_text( value ) { + + if( typeof value == "string" ) { + + return true; + + } else { + + return false; + + } + + } + + is_string( value ) { + + if( typeof value == "string" ) { + + return true; + + } else { + + return false; + + } + + } + + is_boolean() { + + if( typeof value == "boolean" ) { + + return true; + + } else { + + return false; + + } + + } + + is_int( value ) { + + if( typeof value == "number" ) { + + return true; + + } else { + + return false; + + } + + } + + createOuterObjectWithRoot() { + + var objectName = this.getClassName( object ); + + var output = new Object(); + + output[ objectName ] = serializedObject; + + return output; + + } + + createOuterObject( object, serializedObject, is_root ) { + + if( is_root ) { + + return this.createOuterObjectWithRoot( object, serializedObject ); + + } else { + + return serializedObject; + + } + + } + + consoleColors() { + + return consoleColors; + + } + + getFirstObjectFromEntries( entries ) { + + var firstChild = entries[0][1]; + + if( firstChild ) { + + return firstChild; + + } else { + + return object; + + } + + } + + getFirstChild( object ) { + + var entries = Object.entries( object ); + + if( entries[0] ) { + + return this.getFirstObjectFromEntries( entries ); + + } + + } + +} + +String.prototype.replaceAll = function replaceAll( search, replace ) { return this.split( search ).join( replace ); } + + +export default new tools(); + + diff --git a/storage/index.sqbpro b/storage/index.sqbpro new file mode 100644 index 0000000..f4371ee --- /dev/null +++ b/storage/index.sqbpro @@ -0,0 +1,12 @@ +CREATE TABLE "statistics" ( + "id" INTEGER, + "ip" TEXT, + "headers" REAL, + "browser" TEXT, + "Language" TEXT, + "Country" TEXT, + "region" TEXT, + "date" TEXT, + "day" TEXT, + PRIMARY KEY("id") +) diff --git a/storage/index.sqlite b/storage/index.sqlite new file mode 100644 index 0000000..355e8bb Binary files /dev/null and b/storage/index.sqlite differ