{"_id":"@allnulled/flysql","_rev":"6-f781d8c13efee95e83f90a6352844747","name":"@allnulled/flysql","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.0":{"name":"@allnulled/flysql","version":"1.0.0","keywords":[],"author":"","license":"ISC","_id":"@allnulled/flysql@1.0.0","maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"dist":{"shasum":"21f178efbc37e0f67ceffed9d7e573a22d98422e","tarball":"https://registry.npmjs.org/@allnulled/flysql/-/flysql-1.0.0.tgz","fileCount":23,"integrity":"sha512-DR+b1R0kWa2MSlSV45j9/pIczP+bjcLH1YGWPYBKvVnQ5MvdXlZuGXVDjq4+fUn2VMTDng+heB31MlNZYJo7kg==","signatures":[{"sig":"MEUCIHAxdClwIkfXBEeosPI0dXFNkfsJaP0Z6ZsVvHVvMk+mAiEAnfZTWrR/DKmDeK5jWEWDE0fhV/lEXoGl7QmCteCTuoY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":381237},"main":"flysql.js","gitHead":"2b7139fd66cbf399afa53e31752dc7acc816248b","scripts":{"dev":"npx nodemon -w 'flysql.js' -w 'test/*' -e 'js' -x 'npm test'","test":"node test.js"},"_npmUser":{"name":"allnulled","email":"todosanulados@gmail.com"},"_npmVersion":"9.6.7","description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","directories":{"test":"test"},"_nodeVersion":"18.17.1","dependencies":{"sqlstring":"^2.3.3","better-sqlite3":"^12.4.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/flysql_1.0.0_1761907165585_0.9467588240775633","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@allnulled/flysql","version":"1.0.1","keywords":[],"author":"","license":"ISC","_id":"@allnulled/flysql@1.0.1","maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"dist":{"shasum":"d61d826326b99482ffd14dfef8d235b5f04278b5","tarball":"https://registry.npmjs.org/@allnulled/flysql/-/flysql-1.0.1.tgz","fileCount":23,"integrity":"sha512-4LtMqyH4sTIBeIFqb/NDcNm3VEfImInHTBtfzuqzFHRRmXMC/hOzob5ogdtQkWnp+6ZAnI+XGGhv/lyJKjpLwQ==","signatures":[{"sig":"MEYCIQDsz4QtCD9G3DIF9kRnpxWGU9LasnB5QCTqHzyfFLXWYgIhAPsdZM1rAJwUJjppjxjqLivgvYek2/LVFQq3hnt2Fuit","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":381489},"main":"flysql.js","gitHead":"efdeabcb030444c851fb0e2a06555de80b34fc89","scripts":{"dev":"npx nodemon -w 'flysql.js' -w 'test/*' -e 'js' -x 'npm test'","test":"node test.js"},"_npmUser":{"name":"allnulled","email":"todosanulados@gmail.com"},"_npmVersion":"9.6.7","description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","directories":{"test":"test"},"_nodeVersion":"18.17.1","dependencies":{"sqlstring":"^2.3.3","better-sqlite3":"^12.4.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/flysql_1.0.1_1761907396587_0.09027050015694393","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@allnulled/flysql","version":"1.0.2","keywords":[],"author":"","license":"ISC","_id":"@allnulled/flysql@1.0.2","maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"dist":{"shasum":"5ef3cc3a9793e9473f55493b00243f6bcb06db79","tarball":"https://registry.npmjs.org/@allnulled/flysql/-/flysql-1.0.2.tgz","fileCount":25,"integrity":"sha512-YVlTn8ceVQ9Qon+JtxM86LslytpbsIcvJYLJBJzo5lixmF9aqBS1AoIGzntz1g1JfjcRrMR/Y2SPrSy7NDgexg==","signatures":[{"sig":"MEYCIQD0xLctcfmm1ojoyQvMJYAFExtTVxQElJQZfs+wtdoGGAIhAPB614cLRN576SJ8SngcLR2D8BqqJ8RKCnOU6U2St5ey","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":409978},"main":"flysql.js","gitHead":"2776a2dc012b77be47147ee74e6cfe5cd194be71","scripts":{"dev":"npx nodemon -w 'flysql.js' -w 'test/*' -e 'js' -x 'npm test'","test":"node test.js"},"_npmUser":{"name":"allnulled","email":"todosanulados@gmail.com"},"_npmVersion":"9.6.7","description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","directories":{"test":"test"},"_nodeVersion":"18.17.1","dependencies":{"better-sqlite3":"^12.4.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/flysql_1.0.2_1761935134894_0.14337337796721972","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@allnulled/flysql","version":"1.0.3","keywords":[],"author":"","license":"ISC","_id":"@allnulled/flysql@1.0.3","maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"dist":{"shasum":"4e0fc225e8603f345e9e17f959924aeefaf45f7b","tarball":"https://registry.npmjs.org/@allnulled/flysql/-/flysql-1.0.3.tgz","fileCount":27,"integrity":"sha512-6cottoJ8cEh9PHn5PY5erVr2dz4DSqZYL792HNcDg5p3LiqjaHfeNp460I8eq7RueygVt2pFYog18IgZG/nAqQ==","signatures":[{"sig":"MEYCIQD3H5XSQveonLfIYKKPBaNQECQryoteI0TTT6OQr8wSyQIhAMUWM0uvS9A1hgVh+cRxat2Bl2lK9pV5S3yG5vCFYJst","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":437311},"main":"flysql.js","gitHead":"643d5db3c52e92c137ba4cfe8dcf644b17102a54","scripts":{"dev":"npx nodemon -w 'flysql.js' -w 'test/*' -e 'js' -x 'npm test'","test":"node test.js"},"_npmUser":{"name":"allnulled","email":"todosanulados@gmail.com"},"_npmVersion":"9.6.7","description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","directories":{"test":"test"},"_nodeVersion":"18.17.1","dependencies":{"better-sqlite3":"^12.4.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/flysql_1.0.3_1761947488172_0.16376126471545183","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@allnulled/flysql","version":"1.0.4","keywords":[],"author":"","license":"ISC","_id":"@allnulled/flysql@1.0.4","maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"dist":{"shasum":"0e3e105d37a8a57d05e156ffe0ed81fd8f4f48c9","tarball":"https://registry.npmjs.org/@allnulled/flysql/-/flysql-1.0.4.tgz","fileCount":27,"integrity":"sha512-rrMXJWDTfzaHyb/2TwarKXgAmoshNhZndkZJg2sMoF8IU218mB8wGK9JYzXNxWgh0Q+JIzBmaLPtFyUg5g2gEA==","signatures":[{"sig":"MEUCIAjt2CsGJa0AcciU1hD9y9Zow4Wb4dwERtVhGUZXdfryAiEA6HpfoKloZ1KNSN0hqjjG1vT25RUJvk4qIGGjZSDddws=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":440534},"main":"flysql.js","gitHead":"b504a6a78405dbc0f365f221c23e3e8063b5371c","scripts":{"dev":"npx nodemon -w 'flysql.js' -w 'test/*' -e 'js' -x 'npm test'","test":"node test.js"},"_npmUser":{"name":"allnulled","email":"todosanulados@gmail.com"},"_npmVersion":"9.6.7","description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","directories":{"test":"test"},"_nodeVersion":"18.17.1","dependencies":{"better-sqlite3":"^12.4.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/flysql_1.0.4_1761948419761_0.6473072413705205","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@allnulled/flysql","version":"1.0.5","description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","main":"flysql.js","directories":{"test":"test"},"scripts":{"dev":"npx nodemon -w 'flysql.js' -w 'test/*' -e 'js' -x 'npm test'","test":"node test.js"},"keywords":[],"author":"","license":"ISC","dependencies":{"better-sqlite3":"^12.4.1"},"gitHead":"b14e111fbedc9d9121f08dbbfa974b4c0018c8f8","_id":"@allnulled/flysql@1.0.5","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-kWdUFYXT75hAvoFsR+fKObBFu+KOtIistbTAQGaMkMVLFgong+or+hkArRWzHcd9wdteISkGLycBX2A6oSvBpQ==","shasum":"9dd799869fcca4963c085bc779f70c9eded9b77d","tarball":"https://registry.npmjs.org/@allnulled/flysql/-/flysql-1.0.5.tgz","fileCount":27,"unpackedSize":440046,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDKgwZJBqUCKOGGIWErHNBzADFxnVD5N6YjK606LRXQNAIhALzfS0Pt0jbyz04XuASriC0rinX8w7++PJXjGMpcISDf"}]},"_npmUser":{"name":"allnulled","email":"todosanulados@gmail.com"},"maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/flysql_1.0.5_1761949129978_0.27521969938693847"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-31T10:39:25.498Z","modified":"2025-10-31T22:18:50.382Z","1.0.0":"2025-10-31T10:39:25.776Z","1.0.1":"2025-10-31T10:43:16.781Z","1.0.2":"2025-10-31T18:25:35.079Z","1.0.3":"2025-10-31T21:51:28.368Z","1.0.4":"2025-10-31T22:06:59.968Z","1.0.5":"2025-10-31T22:18:50.191Z"},"license":"ISC","keywords":[],"description":"Proxy para `better-sqlite3` con gestión nuclear de `schema`.","maintainers":[{"name":"allnulled","email":"todosanulados@gmail.com"}],"readme":"# flysql\n\nProxy para `better-sqlite3` con gestión nuclear de `schema`.\n\n# Índice\n\n- [flysql](#flysql)\n- [Índice](#índice)\n- [Instalación](#instalación)\n- [API](#api)\n  - [`Flysql.create(...args):Flysql`](#flysqlcreateargsflysql)\n  - [`Flysql.connect(...args):Flysql`](#flysqlconnectargsflysql)\n  - [`Flysql.AssertionError:Function`](#flysqlassertionerrorfunction)\n  - [`Flysql.assertion:Function`](#flysqlassertionfunction)\n  - [`Flysql.defaultOptions:Object`](#flysqldefaultoptionsobject)\n  - [`Flysql.defaultDatabaseOptions:Object`](#flysqldefaultdatabaseoptionsobject)\n  - [`Flysql.knownTypes:Array`](#flysqlknowntypesarray)\n  - [`Flysql.knownOperators`](#flysqlknownoperators)\n  - [`Flysql.checkSchemaColumnValidity(tableId:String, columnId:String, partialSchema:Object)`](#flysqlcheckschemacolumnvaliditytableidstring-columnidstring-partialschemaobject)\n  - [`Flysql.checkSchemaTableValidity(tableId:String, partialSchema:Object)`](#flysqlcheckschematablevaliditytableidstring-partialschemaobject)\n  - [`Flysql.checkSchemaValidity(schema:Object)`](#flysqlcheckschemavalidityschemaobject)\n  - [`Flysql.escapeId(id:String):String`](#flysqlescapeididstringstring)\n  - [`Flysql.escapeValue(value:String|Number):String`](#flysqlescapevaluevaluestringnumberstring)\n  - [`Flysql.padLeft(txt:String, len:Number, filler:String = \"0\"):String`](#flysqlpadlefttxtstring-lennumber-fillerstring--0string)\n  - [`Flysql.fromDateToDateSql(dateObject:Date):String`](#flysqlfromdatetodatesqldateobjectdatestring)\n  - [`Flysql.fromDateToDatetimeSql(dateObject:Date):String`](#flysqlfromdatetodatetimesqldateobjectdatestring)\n  - [`Flysql.constructor(options:Object = {}):Flysql`](#flysqlconstructoroptionsobject--flysql)\n  - [`flysql.trace(msg:String, argz:Array = [])`](#flysqltracemsgstring-argzarray--)\n  - [`flysql.checkInstanceValidity(table:String, item:Object)`](#flysqlcheckinstancevaliditytablestring-itemobject)\n  - [`flysql.copyObject(data)`](#flysqlcopyobjectdata)\n  - [`flysql.addSchema(schema:Object)`](#flysqladdschemaschemaobject)\n  - [`flysql.getSchema()`](#flysqlgetschema)\n  - [`flysql.connect()`](#flysqlconnect)\n  - [`flysql.disconnect()`](#flysqldisconnect)\n  - [`flysql.selectMany(table:String, filters:Array)`](#flysqlselectmanytablestring-filtersarray)\n  - [`flysql.selectOne(table:String, id:String|Number)`](#flysqlselectonetablestring-idstringnumber)\n  - [`flysql.insertMany(table:String, registers:Array)`](#flysqlinsertmanytablestring-registersarray)\n  - [`flysql.insertOne(table:String, register:Object)`](#flysqlinsertonetablestring-registerobject)\n  - [`flysql.updateMany(table:String, filters:Array, values:Object)`](#flysqlupdatemanytablestring-filtersarray-valuesobject)\n  - [`flysql.updateOne(table:String, id:String|Number, values:Object)`](#flysqlupdateonetablestring-idstringnumber-valuesobject)\n  - [`flysql.deleteMany(table:String, filters:Array)`](#flysqldeletemanytablestring-filtersarray)\n  - [`flysql.deleteOne(table:String, id:String|Number)`](#flysqldeleteonetablestring-idstringnumber)\n  - [`flysql.addTable(table:String, partialSchema:Object)`](#flysqladdtabletablestring-partialschemaobject)\n  - [`flysql.addColumn(table:String, column:String, partialSchema:Object)`](#flysqladdcolumntablestring-columnstring-partialschemaobject)\n  - [`flysql.renameTable(table:String, newName:String)`](#flysqlrenametabletablestring-newnamestring)\n  - [`flysql.renameColumn(table:String, column:String, newName:String)`](#flysqlrenamecolumntablestring-columnstring-newnamestring)\n  - [`flysql.dropTable(table:String)`](#flysqldroptabletablestring)\n  - [`flysql.dropColumn(table:String, column:String)`](#flysqldropcolumntablestring-columnstring)\n  - [`flysql.insertSql(sql:String)`](#flysqlinsertsqlsqlstring)\n  - [`flysql.runSql(sql:String)`](#flysqlrunsqlsqlstring)\n  - [`flysql.fetchSql(sql:String)`](#flysqlfetchsqlsqlstring)\n  - [`flysql.reloadSchema()`](#flysqlreloadschema)\n- [API no pública](#api-no-pública)\n  - [`flysql._addTable(table:String, partialSchema)`](#flysql_addtabletablestring-partialschema)\n  - [`flysql._addColumn(table:String, column, partialSchema)`](#flysql_addcolumntablestring-column-partialschema)\n  - [`flysql._renameTable(table:String, newName)`](#flysql_renametabletablestring-newname)\n  - [`flysql._renameColumn(table:String, column, newName)`](#flysql_renamecolumntablestring-column-newname)\n  - [`flysql._dropTable(table)`](#flysql_droptabletable)\n  - [`flysql._dropColumn(table:String, column)`](#flysql_dropcolumntablestring-column)\n  - [`flysql._ensureBasicMetadata()`](#flysql_ensurebasicmetadata)\n  - [`flysql._persistSchema()`](#flysql_persistschema)\n  - [`flysql._loadSchema()`](#flysql_loadschema)\n  - [`flysql._sqliteTypeFromColumnSchema(columnSchema)`](#flysql_sqlitetypefromcolumnschemacolumnschema)\n  - [`flysql._sqliteCreateTableFromTableSchema(table:String, partialSchema)`](#flysql_sqlitecreatetablefromtableschematablestring-partialschema)\n  - [`flysql._sqliteSelectFrom(table)`](#flysql_sqliteselectfromtable)\n  - [`flysql._sqliteInsertInto(table:String, columnIds)`](#flysql_sqliteinsertintotablestring-columnids)\n  - [`flysql._sqliteInsertValues(registers:Array, columnIds)`](#flysql_sqliteinsertvaluesregistersarray-columnids)\n  - [`flysql._sqliteUpdateSet(table:String, values)`](#flysql_sqliteupdatesettablestring-values)\n  - [`flysql._sqliteWhere(whereRules, includeWhereKeyword = true)`](#flysql_sqlitewherewhererules-includewherekeyword--true)\n  - [`flysql._sqliteDeleteFrom(table)`](#flysql_sqlitedeletefromtable)\n  - [`flysql._injectDefaultByJs(table:String, rows:Array<Object>)`](#flysql_injectdefaultbyjstablestring-rowsarrayobject)\n  - [`flysql._rehydrateResults(table:String, results:Array<Object>)`](#flysql_rehydrateresultstablestring-resultsarrayobject)\n- [Ejemplo](#ejemplo)\n\n# Instalación\n\n```sh\nnpm i -s @allnulled/flysql\n```\n\n# API\n\nLa API es totalmente síncrona debido a cómo funciona `better-sqlite3`.\n\n## `Flysql.create(...args):Flysql`\n\nLlama al `flysql.constructor` y devuelve la instancia.\n\n## `Flysql.connect(...args):Flysql`\n\nLlama al `flysql.constructor`, llama al `flysql.connect()` y devuelve la instancia.\n\n## `Flysql.AssertionError:Function`\n\nClase de `Error` para las aserciones en tiempo de ejecución.\n\n## `Flysql.assertion:Function`\n\nFunción para hacer aserciones.\n\n## `Flysql.defaultOptions:Object`\n\nOpciones por defecto pasadas al `constructor`. Las opciones son:\n\n```js\n{\n  trace: false,\n  traceSql: false,\n  filename: path.resolve(process.cwd(), \"db.sqlite\")\n}\n```\n\n## `Flysql.defaultDatabaseOptions:Object`\n\nOpciones por defecto pasadas al `better-sqlite3`. Las opciones son:\n\n```js\n{\n  readonly: false,\n  fileMustExist: false,\n  timeout: 5000,\n  verbose: (...args) => { },\n}\n```\n\n## `Flysql.knownTypes:Array`\n\nTipos válidos de columna.\n\n```js\n[\n   \"boolean\",\n   \"integer\",\n   \"real\",\n   \"string\",\n   \"blob\",\n   \"numeric\",\n   \"date\",\n   \"datetime\",\n   \"object\",\n   \"array\",\n   \"object-reference\"\n]\n```\n\nAl ser seleccionados con `selectOne` o `selectMany`:\n\n- los tipo `boolean` serán pasados a `true` o `false`.\n- los tipo `date` y `datetime` serán pasados a objetos `Date`.\n- los tipo `object` y `array` serán pasados a objetos JSON.\n\n## `Flysql.knownOperators`\n\nOperadores válidos para los filtros en las consultas.\n\n```js\n[\n  \"<\",\n  \"<=\",\n  \">\",\n  \">=\",\n  \"=\",\n  \"!=\",\n  \"is in\",\n  \"is not in\",\n  \"is null\",\n  \"is not null\",\n  \"is like\",\n  \"is not like\"\n]\n```\n\n## `Flysql.checkSchemaColumnValidity(tableId:String, columnId:String, partialSchema:Object)`\n\nMétodo que comprueba la validez de una columna del `schema`.\n\nAquí, `partialSchema:Object` tiene que ser una columna en el `schema`.\n\nLas propiedades válidas de columna son:\n\n- `nullable:Boolean` - debe ser `true` o `false`. Por defecto es `false` siempre.\n- `unique:Boolean` - debe ser `true` o `false`. Por defecto es `false` siempre.\n- `defaultBySql:String` - debe ser el código SQL que quieres poner detrás de la instrucción `DEFAULT`.\n   - se hace una inyección limpia en este campo.\n   - esto significa que si quieres poner un string, debes incluir las comillas.\n- `defaultByJs:String` - debe ser el código JS que quieres usar para inflar el valor de la columna cuando no aparece.\n   - tiene prioridad sobre el valor que se inyectaría desde `defaultBySql`.\n   - debe hacer un `return` con el valor final.\n   - se hace un `new Function(...)` para evaluar el código.\n   - se inyectan los parámetros:\n      - `row:Object`: la row en cuestión.\n      - `index:Number`: el índice de esta row.\n- `type:String` - debe ser uno de los tipos válidos, los `Flysql.knownTypes`, que son:\n   - `boolean`\n   - `integer`\n   - `real`\n   - `string`\n   - `blob`\n   - `numeric`\n   - `date`\n   - `datetime`\n   - `object`\n   - `array`\n   - `object-reference`\n\nEn el caso de `type: \"string\"` también:\n\n- `maxLength:Integer` - máximo de longitud de una columna tipo texto.\n\nEn el caso de `type: \"object-reference\"` también:\n\n- `referredTable:String` - **obligatorio**, la tabla referida mediante esta columna.\n\n## `Flysql.checkSchemaTableValidity(tableId:String, partialSchema:Object)`\n\nMétodo que comprueba la validez de una tabla del `schema`.\n\nEl objeto `partialSchema:Object` tiene que tener una propiedad `columns:Object` mínimo, aunque esté vacía.\n\n## `Flysql.checkSchemaValidity(schema:Object)`\n\nMétodo que comprueba la validez de un `schema`.\n\nEl objeto `schema` tiene que tener una propiedad `tables:Object` mínimo, aunque esté vacía.\n\n## `Flysql.escapeId(id:String):String`\n\nMétodo para escapar un identificador en `sql`.\n\n## `Flysql.escapeValue(value:String|Number):String`\n\nMétodo para escapar un valor en `sql`.\n\n## `Flysql.padLeft(txt:String, len:Number, filler:String = \"0\"):String`\n\nMétodo utilitario para llenar por la izquierda un texto hasta que llegue a cierta longitud.\n\n## `Flysql.fromDateToDateSql(dateObject:Date):String`\n\nMétodo utilitario para transformar objetos `Date` a un formato de fecha (hasta día) homogéneo.\n\n## `Flysql.fromDateToDatetimeSql(dateObject:Date):String`\n\nMétodo utilitario para transformar objetos `Date` a un formato de fecha (hasta milisegundos) homogéneo.\n\n## `Flysql.constructor(options:Object = {}):Flysql`\n\nConstructor de objetos `Flysql`.\n\nEl objeto `options:Object` se llena por defecto con estas propiedades:\n\n```js\n  static defaultOptions = {\n    trace: false,\n    traceSql: false,\n    filename: path.resolve(process.cwd(), \"db.sqlite\")\n    databaseOptions: {\n      readonly: false,\n      fileMustExist: false,\n      timeout: 5000,\n      verbose: (...args) => { },\n    },\n  };\n```\n\nPuedes sobreescribir cualquiera, incluso las de dentro de `databaseOptions`.\n\nAdemás, el método incorporará las siguientes propiedades propias:\n\n- `this.$database:Object = null`\n- `this.$schema:Object`\n- `this.$options:Object`\n\n## `flysql.trace(msg:String, argz:Array = [])`\n\nMétodo utilitario usado para los traceos.\n\n## `flysql.checkInstanceValidity(table:String, item:Object)`\n\nMétodo para comprobar si un objeto cumple con la interfaz esperada de una `table` del `schema`.\n\n## `flysql.copyObject(data)`\n\nMétodo utilitario que copia un objeto, usando `JSON.stringify + JSON.parse`.\n\n## `flysql.addSchema(schema:Object)`\n\nMétodo para añadir parte de un `schema` al `flysql.$schema`.\n\nEl objeto `schema:Object` debe contener mínimo una propiedad `tables:Object`.\n\n## `flysql.getSchema()`\n\nMétodo que devuelve el `flysql.$schema`.\n\n## `flysql.connect()`\n\nMétodo que abre la base de datos y sincroniza el `flysql.$schema`.\n\nDebes tener en cuenta que `flysql.$schema` está dentro de la base de datos:\n\n- En la tabla `Database_metadata`\n- Con el `name = 'db.schema'`\n- En formato JSON\n\nDe esta forma, se consigue tener acoplado a la base de datos, el `flysql.$schema` que va a validar las instancias y demás.\n\n## `flysql.disconnect()`\n\nMétodo que cierra la base de datos.\n\n## `flysql.selectMany(table:String, filters:Array)`\n\nMétodo para extraer filas de una tabla.\n\nEl objeto `filters:Object` acepta `Array<Array<String, String, Number|String|Array>>`. Concretamente son objetos así:\n\n```js\nflysql.selectMany(\"Nombre_de_tabla\", [\n  [\"columna\", \"<operador>\", \"<comparador>\"]\n]);\n```\n\nDonde:\n\n- `columna:String`: nombre de la columna de la tabla.\n- `operador:String`: acepta uno de los `Flysql.knownOperators` que son:\n   - `=`: es igual que\n   - `!=`: no es igual que\n   - `<`: es menor que\n   - `<=`: es menor o igual que\n   - `>`: es mayor que\n   - `>=`: es mayor o igual que\n   - `is null`: es nulo\n      - aquí no hay comparador\n   - `is not null`: no es nulo\n      - aquí no hay comparador\n   - `is in`: está entre\n      - aquí el comparador tiene que ser un `Array<String|Number>`\n   - `is not in`: no está entre\n      - aquí el comparador tiene que ser un `Array<String|Number>`\n   - `is like`: es como\n      - aquí el comparador es un `String` que permite el caracter `%` como *cualquier texto*.\n   - `is not like`: no es como\n      - aquí el comparador es un `String` que permite el caracter `%` como *cualquier texto*.\n- `comparador:String|Number|Array`: dependiendo del `operador` acepta unos u otros, y en el caso de `is null` e `is not null` no tiene relevancia este parámetro.\n\n## `flysql.selectOne(table:String, id:String|Number)`\n\nMétodo que permite extraer una fila concreta por su columna `id`.\n\n## `flysql.insertMany(table:String, registers:Array)`\n\nMétodo que permite insertar varias filas de una llamada.\n\nEl parámetro `registers:Array<Object>` acepta solamente un array de nuevas instancias.\n\nPermite insertar los tipos siguientes directamente:\n\n- Columnas `type:\"boolean\"` aceptan un booleano `true` o `false` directamente.\n- Columnas `type:\"date\"` aceptan un objeto `Date` directamente.\n- Columnas `type:\"datetime\"` aceptan un objeto `Date` directamente.\n- Columnas `type:\"object\"` aceptan un `Object` directamente.\n- Columnas `type:\"array\"` aceptan un `Array` directamente.\n\nLo mismo aplica para actualizar estos valores.\n\n## `flysql.insertOne(table:String, register:Object)`\n\nMétodo que permite insertar una fila.\n\nEl parámetro `register:Object` acepta solamente una nueva instancia.\n\n## `flysql.updateMany(table:String, filters:Array, values:Object)`\n\nMétodo que permite cambiar ciertas propiedades de varias filas de una llamada.\n\nEl parámetro `filters:Array` funciona igual que con `selectMany`.\n\nEl parámetro `values:Object` son las propiedades que se van a cambiar.\n\n## `flysql.updateOne(table:String, id:String|Number, values:Object)`\n\nMétodo que permite cambiar ciertas propiedades de una fila.\n\nEl parámetro `id:String|Number` es el `id` de la fila.\n\nEl parámetro `values:Object` son las propiedades que se van a cambiar.\n\n## `flysql.deleteMany(table:String, filters:Array)`\n\nMétodo que permite eliminar varias filas de una llamada.\n\nEl parámetro `filters:Array` funciona igual que con `selectMany`.\n\n## `flysql.deleteOne(table:String, id:String|Number)`\n\nMétodo que permite eliminar varias filas de una llamada.\n\nEl parámetro `id:String|Number` es el `id` de la fila.\n\n## `flysql.addTable(table:String, partialSchema:Object)`\n\nMétodo que añade una tabla en el `this.$schema` y sincroniza el `Database_metadata`.\n\nEl parámetro `partialSchema:Object` debe coincidir con la estructura que se espera de una tabla. Esto significa que, mínimo, tiene que tener la propiedad `column`.\n\n## `flysql.addColumn(table:String, column:String, partialSchema:Object)`\n\nMétodo que añade una columna en el `this.$schema` y sincroniza el `Database_metadata`.\n\nEl parámetro `partialSchema:Object` debe coincidir con la estructura que se espera de una columna.\n\n## `flysql.renameTable(table:String, newName:String)`\n\nMétodo que cambia el nombre de una tabla en el `this.$schema` y sincroniza el `Database_metadata`.\n\n## `flysql.renameColumn(table:String, column:String, newName:String)`\n\nMétodo que cambia el nombre de una columna en el `this.$schema` y sincroniza el `Database_metadata`.\n\n## `flysql.dropTable(table:String)`\n\nMétodo que elimina una tabla en el `this.$schema` y sincroniza el `Database_metadata`.\n\n## `flysql.dropColumn(table:String, column:String)`\n\nMétodo que elimina una columna en el `this.$schema` y sincroniza el `Database_metadata`.\n\n## `flysql.insertSql(sql:String)`\n\nMétodo que permite ejecutar `sql`, orientado a un *insert único o múltiple* y que devuelve el `lastInsertRowid` o identificador de la última fila insertada.\n\n## `flysql.runSql(sql:String)`\n\nMétodo que permite ejecutar `sql`, orientado a *múltiples instrucciones sql de una llamada*. No devuelve nada.\n\n## `flysql.fetchSql(sql:String)`\n\nMétodo que permite ejecutar `sql`, orientado a un *select* y que devuelve las filas seleccionadas.\n\n## `flysql.reloadSchema()`\n\nMétodo que sincroniza el `flysql.$schema` con el `db.schema` de la tabla `Database_metadata`.\n\n# API no pública\n\nAdemás de estos, hay una serie de métodos pensados para uso privado, pero que en esta documentación aparecen igualmente.\n\nEstos métodos tienen la peculiaridad de comenzar siempre con `_`.\n\n## `flysql._addTable(table:String, partialSchema)`\n\nMétodo que añade una tabla con `sql`.\n\n## `flysql._addColumn(table:String, column, partialSchema)`\n\nMétodo que añade una columna con `sql`.\n\n## `flysql._renameTable(table:String, newName)`\n\nMétodo que renombra una tabla con `sql`.\n\n## `flysql._renameColumn(table:String, column, newName)`\n\nMétodo que renombra una columna con `sql`.\n\n## `flysql._dropTable(table)`\n\nMétodo que elimina una tabla.\n\n## `flysql._dropColumn(table:String, column)`\n\nMétodo que elimina una columna.\n\n## `flysql._ensureBasicMetadata()`\n\nMétodo que crea las tablas básicas para que `Flysql` funcione correctamente.\n\nPor ahora, solo es `Database_metadata`.\n\n## `flysql._persistSchema()`\n\nMétodo que persiste el `this.$schema` en la tabla `Database_metadata`.\n\n## `flysql._loadSchema()`\n\nMétodo que carga el `this.$schema` de la tabla `Database_metadata`.\n\n## `flysql._sqliteTypeFromColumnSchema(columnSchema)`\n\nMétodo que devuelve el código `sql` correspondiente al tipo de una columna.\n\n## `flysql._sqliteCreateTableFromTableSchema(table:String, partialSchema)`\n\nMétodo que devuelve el código `sql` correspondiente a la creación de una tabla basándose en su definición del `flysql.$schema`.\n\n## `flysql._sqliteSelectFrom(table)`\n\nMétodo que devuelve el código `sql` correspondiente a `SELECT * FROM <tabla>`.\n\n## `flysql._sqliteInsertInto(table:String, columnIds)`\n\nMétodo que devuelve el código `sql` correspondiente a `INSERT INTO <tabla>`.\n\n## `flysql._sqliteInsertValues(registers:Array, columnIds)`\n\nMétodo que devuelve el código `sql` correspondiente a `VALUES (<fila>), (<fila>), ...`.\n\n## `flysql._sqliteUpdateSet(table:String, values)`\n\nMétodo que devuelve el código `sql` correspondiente a `UPDATE <tabla> SET <valores>`.\n\n## `flysql._sqliteWhere(whereRules, includeWhereKeyword = true)`\n\nMétodo que devuelve el código `sql` correspondiente a `WHERE <where rules>`.\n\n## `flysql._sqliteDeleteFrom(table)`\n\nMétodo que devuelve el código `sql` correspondiente a `DELETE FROM <tabla>`.\n\n## `flysql._injectDefaultByJs(table:String, rows:Array<Object>)`\n\nMétodo que inyecta el valor de la propiedad de columna `defaultByJs:String` a todos los rows del `insertOne` e `insertMany`.\n\n## `flysql._rehydrateResults(table:String, results:Array<Object>)`\n\nMétodo que cambia los valores tipados por su tipo en `javascript` indicado en el `this.$schema`.\n\n# Ejemplo\n\n```js\nmodule.exports = async function (Flysql) {\n\n  const fs = require(\"fs\");\n\n  fs.unlinkSync(__dirname + \"/test.sqlite\");\n\n  const { assertion } = Flysql;\n\n  const flysql = Flysql.create({\n    filename: \"test.sqlite\",\n    trace: true,\n    traceSql: true\n  });\n  flysql.connect();\n  flysql.addSchema({\n    tables: {\n      Usuario: {\n        columns: {\n          name: {type: \"string\", maxLength: 255, unique: true},\n          email: {type: \"string\", maxLength: 255, unique: true},\n          password: {type: \"string\", maxLength: 255}\n        }\n      },\n      Grupo: {\n        columns: {\n          name: {type: \"string\", maxLength: 255, unique: true},\n          description: {type: \"string\", maxLength: 255},\n        }\n      },\n      Permiso: {\n        columns: {\n          name: {type: \"string\", maxLength: 255, unique: true},\n          description: {type: \"string\", maxLength: 255},\n        }\n      },\n      Sesion: {\n        columns: {\n          token: {type: \"string\", maxLength: 100, unique: true},\n          id_usuario: {type: \"object-reference\", referredTable: \"Usuario\"},\n        }\n      }\n    }\n  });\n  flysql.insertOne(\"Usuario\", { name: \"u1\", password: \"u1\", email: \"u1@mail.com\" });\n  flysql.insertMany(\"Usuario\", [\n    { name: \"u2\", password: \"u1\", email: \"u2@mail.com\" },\n    { name: \"u3\", password: \"u1\", email: \"u3@mail.com\" },\n    { name: \"u4\", password: \"u4\", email: \"u4@mail.com\" },\n  ]);\n\n  const u1 = flysql.selectOne(\"Usuario\", 1);\n  const uN = flysql.selectMany(\"Usuario\", [\n    [\"name\", \"is in\", [\"u2\", \"u3\", \"u4\"]]\n  ]);\n\n  assertion(typeof u1 === \"object\", \"assertion\");\n  assertion(typeof u1.name === \"string\", \"assertion\");\n  assertion(u1.name === \"u1\", \"assertion\");\n\n  assertion(typeof uN === \"object\", \"assertion\");\n  assertion(Array.isArray(uN), \"assertion\");\n  assertion(uN.length === 3, \"assertion\");\n  assertion(uN[0].name === \"u2\", \"assertion\");\n  assertion(uN[1].name === \"u3\", \"assertion\");\n  assertion(uN[2].name === \"u4\", \"assertion\");\n\n  console.log(\"[*] Completado test: 009.readme\");\n\n};\n```\n\nOtro ejemplo de cómo los tipos pueden usarse sería este otro test:\n\n```js\nmodule.exports = async function (Flysql) {\n\n  const fs = require(\"fs\");\n\n  fs.unlinkSync(__dirname + \"/test.sqlite\");\n\n  const { assertion } = Flysql;\n\n  const flysql = Flysql.create({\n    filename: \"test.sqlite\",\n    trace: false,\n    traceSql: false\n  });\n  flysql.connect();\n  flysql.addSchema({\n    tables: {\n      Random_item: {\n        columns: {\n          booleanType: {type: \"boolean\"},\n          stringType: {type: \"string\", maxLength: 10},\n          textType: {type: \"string\"},\n          integerType: {type: \"integer\"},\n          realType: {type: \"real\"},\n          blobType: {type: \"blob\"},\n          dateType: {type: \"date\"},\n          datetimeType: {type: \"datetime\"},\n          objectType: {type: \"object\"},\n          arrayType: {type: \"array\"},\n        }\n      }\n    }\n  });\n  \n  const item1 = flysql.insertOne(\"Random_item\", {\n    booleanType: false,\n    stringType: \"texto\",\n    textType: \"texto\",\n    integerType: 1,\n    realType: 1.55,\n    blobType: \"texto binario\",\n    dateType: new Date(\"2025-01-01\"),\n    datetimeType: new Date(\"2025-01-01 00:00:00\"),\n    objectType: {ok:200,message:\"whatever intercaling ' quotes ' and ''two simple quotes''\"},\n    arrayType: [5,4,3,{message:\"whatever\"}],\n  });\n  \n  const item1data = flysql.selectOne(\"Random_item\", item1);\n\n  assertion(item1data.booleanType === false);\n  assertion(item1data.stringType === \"texto\");\n  assertion(item1data.integerType === 1);\n  assertion(item1data.realType === 1.55);\n  assertion(item1data.blobType === \"texto binario\");\n  assertion(item1data.dateType instanceof Date);\n  assertion(item1data.datetimeType instanceof Date);\n  assertion(Flysql.fromDateToDateSql(item1data.dateType) === \"2025-01-01\");\n  assertion(Flysql.fromDateToDatetimeSql(item1data.datetimeType) === \"2025-01-01 00:00:00\");\n  assertion(typeof item1data.objectType === \"object\");\n  assertion(item1data.objectType.ok === 200);\n  assertion(Array.isArray(item1data.arrayType));\n  assertion(item1data.arrayType[0] === 5);\n  assertion(item1data.arrayType[1] === 4);\n  assertion(item1data.arrayType[2] === 3);\n\n  console.log(\"[*] Completado test: 011.datatypes\");\n\n};\n```","readmeFilename":"README.md"}