diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2e8a84f63..8ac2c5e60 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,9 +39,9 @@ jobs: with: webroot: ${{ github.workspace }} execute: /build-all.cfm - luceeVersion: 6.2.0.164-RC - # redis, chart, lucene, form. ajax, chart - extensions: 60772C12-F179-D555-8E2CD2B4F7428718;version=3.0.0.54-SNAPSHOT,D46B46A9-A0E3-44E1-D972A04AC3A8DC10,EFDEB172-F52E-4D84-9CD1A1F561B3DFC8,FAD67145-E3AE-30F8-1C11A6CCF544F0B7,6E2CB28F-98FB-4B51-B6BE6C64ADF35473,DF28D0A4-6748-44B9-A2FDC12E4E2E4D38 + luceeVersion: 6.2.0.284-RC + # redis, chart, lucene, form. ajax, chart, argon2, websocket, ec2, json + extensions: 60772C12-F179-D555-8E2CD2B4F7428718;version=3.0.0.54-SNAPSHOT,D46B46A9-A0E3-44E1-D972A04AC3A8DC10,EFDEB172-F52E-4D84-9CD1A1F561B3DFC8,FAD67145-E3AE-30F8-1C11A6CCF544F0B7,6E2CB28F-98FB-4B51-B6BE6C64ADF35473,DF28D0A4-6748-44B9-A2FDC12E4E2E4D38,7891D723-8F78-45F5-B7E333A22F8467CA,07082C66-510A-4F0B-B5E63814E2FDF7BE,261114AC-7372-4CA8-BA7090895E01682D,A03F4335-BDEF-44DE-946FB16C47802F96 - name: Upload Artifact uses: actions/upload-artifact@v4 with: diff --git a/api/data/DocTree.cfc b/api/data/DocTree.cfc index bb724735c..e7d74a9ad 100644 --- a/api/data/DocTree.cfc +++ b/api/data/DocTree.cfc @@ -311,10 +311,17 @@ component accessors=true { variables.tree.append(guide); } break; - /* case "recipes": + var recipeTree = folder.getChildren(); + for (var recipe in recipeTree){ + if (recipe.getForceSortOrder() gt 0){ + recipe.setSortOrder(recipe.getForceSortOrder()); + } else { + recipe.setSortOrder(5 + NumberFormat(recipe.getSortOrder()/100,"0.00")); + } + variables.tree.append(recipe); + } break; - */ } } _sortChildren( variables.tree ); diff --git a/api/data/PageCache.cfc b/api/data/PageCache.cfc index 0bf3af363..5932d15ce 100644 --- a/api/data/PageCache.cfc +++ b/api/data/PageCache.cfc @@ -83,7 +83,7 @@ component accessors=true { var timestamp = CreateDate(2000,1,1);// for( var file in local.files){ file = _removeRootDirectoryFromFilePath(file); - if ( ListFirst( file, "/" ) eq "recipes") continue; + // if ( ListFirst( file, "/" ) eq "recipes") continue; var row = QueryAddRow(local.q_files); querySetCell(local.q_files, "name", ListLast(file, "/") , row); querySetCell(local.q_files, "fullpath", file , row); diff --git a/api/data/PageReader.cfc b/api/data/PageReader.cfc index 2a4e1a8c0..74d8d9c5d 100644 --- a/api/data/PageReader.cfc +++ b/api/data/PageReader.cfc @@ -50,11 +50,17 @@ component { if (page.getPageType() eq "README"){ page.setPath( page.getPath() ); page.setPageType( "listing" ); + page.setListingStyle( "flat" ); page.setVisible( true ); - page.setReference( false ); - page.setBody( "Recipes" ); + page.setReference( true ); + page.setBody( "Detailed Recipes showing you how to take advantage of the wide range of features in Lucee" ); + page.setMenuTitle( "Recipes" ); page.setTitle( "Lucee Recipes" ); - page.setDescription( "Lucee Recipes" ); + page.setDescription( "Detailed Recipes showing you how to take advantage of the wide range of features in Lucee" ); + page.setForceSortOrder( 5.5 ); + page.setSortOrder( 4.5 ); + page.setSlug("recipes"); + page.setId("recipes"); } else { page.setPath( page.getPath() & "/" & replace( page.getPageType(), ".md", "" ) ); page.setPageType( "page" ); @@ -149,7 +155,6 @@ component { } else if ( len( trim( arguments.pageContent ) ) ){ parsed = _splitCommentStructAndBody( arguments.pageContent, arguments.filePath ); } - return parsed; } @@ -189,15 +194,14 @@ component { var meta = mid( str, 5, endComment - 5 ); //systemOutput( "!!" & meta & "!!", true ); if ( !isJson( meta ) ){ - throw "metadata is not json [#arguments.filePath#]"; + throw (message="metadata is not json [#arguments.filePath#]", detail=meta); } var body = mid( str, endComment + 3 ); if ( len( trim( body ) ) eq 0 ) throw "empty content after metadata [#arguments.filePath#]"; - return { - yaml = deserializeJson( meta ) - , body = body - } + meta = deserializeJson( meta ); + meta.body = body; + return meta; } private string function _convertToUnixLineEnding( required string content ){ diff --git a/api/reference/ReferenceImporter.cfc b/api/reference/ReferenceImporter.cfc index 7bb8d6366..e73c5065c 100644 --- a/api/reference/ReferenceImporter.cfc +++ b/api/reference/ReferenceImporter.cfc @@ -300,7 +300,7 @@ categories: if ( size eq 0 ){ if ( len( trim( arguments.content ) ) gt 0 ){ request.logger( text="Updating existing zero length file: " & arguments.filePath ); - exists = true; + exists = false; break; } else if ( !arguments.docsOnly ){ request.logger(text="Missing content from Lucee: " & arguments.filePath, type="warn"); diff --git a/builders/html/Builder.cfc b/builders/html/Builder.cfc index 3fc77c739..46c8069da 100644 --- a/builders/html/Builder.cfc +++ b/builders/html/Builder.cfc @@ -225,7 +225,13 @@ component { FileWrite( arguments.buildDirectory & "/sitemap.xml", _renderSiteMap( arguments.docTree ) ); // google analytics for @zackster FileWrite( arguments.buildDirectory & "/google4973ccb67f78b874.html", "google-site-verification: google4973ccb67f78b874.html"); - FileWrite( arguments.buildDirectory & "/robots.txt", "User-agent: *#chr(10)#Disallow: /dictionaries/#chr(10)#Sitemap: https://docs.lucee.org/sitemap.xml"); + FileWrite( arguments.buildDirectory & "/robots.txt", [ + "User-agent: *", + "Disallow: /dictionaries/", + "Disallow: /editor.html", + "Sitemap: https://docs.lucee.org/sitemap.xml" + ].toList(chr(10)) + ); FileCopy( GetDirectoryFromPath( GetCurrentTemplatePath() ) & "/assets/trycf/index.html", arguments.buildDirectory & "/editor.html" ); } diff --git a/builders/html/templates/aToZIndex.cfm b/builders/html/templates/aToZIndex.cfm index 46383f4f3..93d1b92be 100644 --- a/builders/html/templates/aToZIndex.cfm +++ b/builders/html/templates/aToZIndex.cfm @@ -9,8 +9,7 @@ #getEditLink(path=local.pg.getSourceFile(), edit=args.edit)# #_markdownToHtml( local.pg.getBody() )# - - +
diff --git a/docs/00.home/homepage.md b/docs/00.home/homepage.md index f03f6160c..a0f1a38c4 100644 --- a/docs/00.home/homepage.md +++ b/docs/00.home/homepage.md @@ -16,9 +16,15 @@ Our documentation is an open source and community driven effort. It is also a co To find out more about getting involved as a developer with Lucee, checkout our [Git Repo](https://github.com/lucee/Lucee/blob/6.0/CONTRIBUTING.md) +## Recipes + +**New!** We have added a whole series of detailed [[Recipes]] showing you how to take advantage of the wide range of features in Lucee. + ## Lucee 6.2 -Lucee 6.2 is our upcoming next major release, including enhanced Java and Maven integration, with even better runtime performance. +Lucee 6.2 is our upcoming next major release, currently at the Release Candidate stage, including enhanced Java and Maven integration, Jakarta Servlet support and better runtime performance, up to 50% faster than Lucee 5.4. + +[[breaking-changes-6-1-to-6-2]] ## Lucee 6.1 @@ -27,6 +33,8 @@ Lucee 6.1 is current stable release of Lucee. Targeting better performance and reduced memory usage, Lucee 6.1 introduces full support for Java 17 and 21, as well as Java 11. Java 8 is no longer officially supported. +[[breaking-changes-6-0-to-6-1]] + ## Lucee 6.0 [Lucee 6](https://dev.lucee.org/tag/lucee-6) . diff --git a/docs/03.reference/01.functions/datetimeformat/_arguments/mask.md b/docs/03.reference/01.functions/datetimeformat/_arguments/mask.md index 66dda69ba..9d50d376e 100644 --- a/docs/03.reference/01.functions/datetimeformat/_arguments/mask.md +++ b/docs/03.reference/01.functions/datetimeformat/_arguments/mask.md @@ -1,53 +1,53 @@ Date time formatting mask (case sensitive): -- a,..,aaaa: AM/PM marker (see also "t" and "tt"; Example:AM) -- d: Day in month, no leading zero for single-digit days (Example:3) -- dd: Day in month, leading zero for single-digit days (Example:03) -- D: Day in year, no leading zero for single-digit days (Example:4) -- DD: Day in year, leading zero for single-digit days (Example:04) -- DDD: Day in year, 2 leading zero for single-digit days (Example:004) -- E,EE,EEE: Day of week as a three-letter abbreviation (Example:Tue) -- EEEE: Day of week as its full name (Example:Tuesday) -- F: Day of week in month, no leading zero for single-digit days (Example:4) -- FF: Day of week in month, leading zero for single-digit days (Example:04) -- G,GG: Era designator (Example:AD) -- h: Hour in am/pm (1-12), no leading zero for single-digit hours (Example:3) -- hh: Hour in am/pm (1-12), leading zero for single-digit hours (Example:03) -- H: Hour in day (0-23), no leading zero for single-digit hours (Example:14) -- HH: Hour in day (00-23), leading zero for single-digit hours (Example:14) -- k: Hour in day (1-24), no leading zero for single-digit hours (Example:15) -- kk: Hour in day (1-24), leading zero for single-digit hours (Example:15) -- K: Hour in am/pm (0-11), no leading zero for single-digit hours (Example:2) -- KK: Hour in am/pm (0-11), leading zero for single-digit hours (Example:02) -- l,L: milliseconds, with no leading zeros (Example:3) -- ll,LL: milliseconds, leading zero for single-digit days (Example:03) -- lll,LLL: milliseconds, 2 leading zero for single-digit days (Example:003) -- m,M: Month as digits, no leading zero for single-digit months (Example:6) -- mm,MM: Month as digits, leading zero for single-digit months (Example:06) -- mmm,MMM: Month as a three-letter abbreviation (Example:Jun) -- mmmm,MMMM: Month as its full name (Example:June) -- n,N: minutes in hour, no leading zero for single-digit minutes (Example:3) -- nn,NN: minutes in hour, leading zero for single-digit minutes (Example:03) -- s,S: seconds in minute, no leading zero for single-digit seconds (Example:3) -- ss,SS: seconds in minute, leading zero for single-digit seconds (Example:03) -- t,T: one-character time marker string (Example:P) -- tt,TT: multiple-character time marker string (Example:PM) -- w: Week in year, no leading zero for single-digit hours (Example:27) -- ww: Week in year, leading zero for single-digit hours (Example:27) -- W: Week in month, no leading zero for single-digit hours (Example:2) -- WW: Week in month, leading zero for single-digit hours (Example:02) -- y,yy,yyy: Year as last two digits, leading zero for single-digit (Example:09) -- yyyy: Year represented by four digits (Example:2009) -- z,zz,zzz: General time zone as a 3 to 4 letter abbreviation (Example:PST) -- zzzz: General time zone as its full name (Example:Pacific Standard Time) -- Z,..,ZZZZ: RFC 822 time zone (Example:-0800) +- `a,..,aaaa`: AM/PM marker (see also "t" and "tt"; Example:AM) +- `d`: Day in month, no leading zero for single-digit days (Example:3) +- `dd`: Day in month, leading zero for single-digit days (Example:03) +- `D`: Day in year, no leading zero for single-digit days (Example:4) +- `DD`: Day in year, leading zero for single-digit days (Example:04) +- `DDD`: Day in year, 2 leading zero for single-digit days (Example:004) +- `E,EE,EEE`: Day of week as a three-letter abbreviation (Example:Tue) +- `EEEE`: Day of week as its full name (Example:Tuesday) +- `F`: Day of week in month, no leading zero for single-digit days (Example:4) +- `FF`: Day of week in month, leading zero for single-digit days (Example:04) +- `G,GG`: Era designator (Example:AD) +- `h`: Hour in am/pm (1-12), no leading zero for single-digit hours (Example:3) +- `hh`: Hour in am/pm (1-12), leading zero for single-digit hours (Example:03) +- `H`: Hour in day (0-23), no leading zero for single-digit hours (Example:14) +- `HH`: Hour in day (00-23), leading zero for single-digit hours (Example:14) +- `k`: Hour in day (1-24), no leading zero for single-digit hours (Example:15) +- `kk`: Hour in day (1-24), leading zero for single-digit hours (Example:15) +- `K`: Hour in am/pm (0-11), no leading zero for single-digit hours (Example:2) +- `KK`: Hour in am/pm (0-11), leading zero for single-digit hours (Example:02) +- `l,L`: milliseconds, with no leading zeros (Example:3) +- `ll,LL`: milliseconds, leading zero for single-digit days (Example:03) +- `lll,LLL`: milliseconds, 2 leading zero for single-digit days (Example:003) +- `m,M`: Month as digits, no leading zero for single-digit months (Example:6) +- `mm,MM`: Month as digits, leading zero for single-digit months (Example:06) +- `mmm,MMM`: Month as a three-letter abbreviation (Example:Jun) +- `mmmm,MMMM`: Month as its full name (Example:June) +- `n,N`: minutes in hour, no leading zero for single-digit minutes (Example:3) +- `nn,NN`: minutes in hour, leading zero for single-digit minutes (Example:03) +- `s,S`: seconds in minute, no leading zero for single-digit seconds (Example:3) +- `ss,SS`: seconds in minute, leading zero for single-digit seconds (Example:03) +- `t,T`: one-character time marker string (Example:P) +- `tt,TT`: multiple-character time marker string (Example:PM) +- `w`: Week in year, no leading zero for single-digit hours (Example:27) +- `ww`: Week in year, leading zero for single-digit hours (Example:27) +- `W`: Week in month, no leading zero for single-digit hours (Example:2) +- `WW`: Week in month, leading zero for single-digit hours (Example:02) +- `y,yy,yyy`: Year as last two digits, leading zero for single-digit (Example:09) +- `yyyy`: Year represented by four digits (Example:2009) +- `z,zz,zzz`: General time zone as a 3 to 4 letter abbreviation (Example:PST) +- `zzzz`: General time zone as its full name (Example:Pacific Standard Time) +- `Z,..,ZZZZ`: RFC 822 time zone (Example:-0800) The following masks can be used to format the full date and time and may not be combined with other masks: -- short: equivalent to "m/d/y h:nn tt" -- medium: equivalent to "mmm d, yyyy h:nn:ss tt" -- long: medium followed by three-letter time zone; i.e. "mmmm d, yyyy h:nn:ss tt zzz" -- full: equivalent to "dddd, mmmm d, yyyy h:nn:ss tt zz" -- ISO8601/ISO: equivalent to "yyyy-mm-dd'T'HH:nn:ssXXX" -- epoch: Total seconds of a given date (Example:1567517664) (added in Lucee 6.0.0.83) -- epochms: Total milliseconds of a given date (Example:1567517664000) (added in Lucee 6.0.0.83) +- `short`: equivalent to "m/d/y h:nn tt" +- `medium`: equivalent to "mmm d, yyyy h:nn:ss tt" +- `long`: medium followed by three-letter time zone; i.e. "mmmm d, yyyy h:nn:ss tt zzz" +- `full`: equivalent to "dddd, mmmm d, yyyy h:nn:ss tt zz" +- `ISO8601/ISO`: equivalent to "yyyy-mm-dd'T'HH:nn:ssXXX" +- `epoch`: Total seconds of a given date (Example:1567517664) (added in Lucee 6.0.0.83) +- `epochms`: Total milliseconds of a given date (Example:1567517664000) (added in Lucee 6.0.0.83) diff --git a/docs/03.reference/01.functions/directorylist/_arguments/filter.md b/docs/03.reference/01.functions/directorylist/_arguments/filter.md index 4f88ae33f..98ea23876 100644 --- a/docs/03.reference/01.functions/directorylist/_arguments/filter.md +++ b/docs/03.reference/01.functions/directorylist/_arguments/filter.md @@ -1,4 +1,6 @@ -Filter to be used to filter the results: +Specifies a filter to be used to filter the results: -* A string that uses "*" as a wildcard, for example, "*.cfm" -* a UDF (User defined Function) with signature `Boolean function(String path)`. The function is run for each file in turn; if the function returns `true`, then the file is will be added to the result; otherwise it will be omitted. +- A string that uses `*` as a wildcard, for example, `*.cfm` +- UDF (User Defined Function) using the following pattern: `boolean function(String path, String type, String ext)`. The function is run for every single file; if the function returns `true`, the file is included in the list; otherwise, it is omitted. `Type` is either `File` or `Directory` + +`Type` and `Ext` arguments were added in Lucee 6.0 diff --git a/docs/03.reference/01.functions/directorylist/_arguments/listInfo.md b/docs/03.reference/01.functions/directorylist/_arguments/listInfo.md index f09b24832..0aac86b50 100644 --- a/docs/03.reference/01.functions/directorylist/_arguments/listInfo.md +++ b/docs/03.reference/01.functions/directorylist/_arguments/listInfo.md @@ -1,3 +1,5 @@ -- name: returns an array of names of files and directories. -- path: returns an array of paths of files and directories. This is the default. -- query: returns a query. +Defines the return type of this function: + +- `name`: returns an array of names of files and directories. +- `path`: returns an array of paths of files and directories. This is the default. +- `query`: returns a query object. \ No newline at end of file diff --git a/docs/03.reference/01.functions/directorylist/_arguments/path.md b/docs/03.reference/01.functions/directorylist/_arguments/path.md index e4cf9882c..59f886825 100644 --- a/docs/03.reference/01.functions/directorylist/_arguments/path.md +++ b/docs/03.reference/01.functions/directorylist/_arguments/path.md @@ -1,3 +1,3 @@ The absolute path of the directory to list the content from. -Alternatively, you can specify IP address as in the following example: DirectoryList(\"//12.3.123.123/c_drive/test\");. \ No newline at end of file +This can be any type of supported [[virtual-file-system]] \ No newline at end of file diff --git a/docs/03.reference/01.functions/directorylist/_arguments/recurse.md b/docs/03.reference/01.functions/directorylist/_arguments/recurse.md index 236736f06..ff11471c0 100644 --- a/docs/03.reference/01.functions/directorylist/_arguments/recurse.md +++ b/docs/03.reference/01.functions/directorylist/_arguments/recurse.md @@ -1,3 +1,3 @@ -Whether Lucee performs the action on sub-directories: +Specifies whether to include subdirectories in the listing. -If true, the contents of all sub-directories are also included. \ No newline at end of file +If `true`, the content of all sub-directories is also included. \ No newline at end of file diff --git a/docs/03.reference/01.functions/directorylist/_arguments/sort.md b/docs/03.reference/01.functions/directorylist/_arguments/sort.md index 293ed9259..0541fde6b 100644 --- a/docs/03.reference/01.functions/directorylist/_arguments/sort.md +++ b/docs/03.reference/01.functions/directorylist/_arguments/sort.md @@ -6,5 +6,5 @@ Sorting is case sensitive. To qualify a column, use one of the following values: -- asc: ascending (a to z) sort order. -- desc: descending (z to a) sort order. +- `asc`: ascending (a to z) sort order. Default +- `desc`: descending (z to a) sort order. diff --git a/docs/03.reference/01.functions/directorylist/_arguments/type.md b/docs/03.reference/01.functions/directorylist/_arguments/type.md index 8942fcd0f..ad10c7014 100644 --- a/docs/03.reference/01.functions/directorylist/_arguments/type.md +++ b/docs/03.reference/01.functions/directorylist/_arguments/type.md @@ -1,5 +1,5 @@ type of the result returned: -- file: includes only filenames -- dir: includes only directory names -- all: includes both filenames and directory names \ No newline at end of file +- `file`: includes only filenames +- `dir`: includes only directory names +- `all`: includes both filenames and directory names \ No newline at end of file diff --git a/docs/03.reference/01.functions/directorylist/_usageNotes.md b/docs/03.reference/01.functions/directorylist/_usageNotes.md index 6eefc3cf4..6e8a592e3 100644 --- a/docs/03.reference/01.functions/directorylist/_usageNotes.md +++ b/docs/03.reference/01.functions/directorylist/_usageNotes.md @@ -1,3 +1 @@ -For ACF compatibility, on Unix systems, the `mode` column is currently not populated - - \ No newline at end of file +The Unix `mode` column was not populated prior to Lucee 6.1 diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/accessKeyId.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/accessKeyId.md new file mode 100644 index 000000000..ac9a6a930 --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/accessKeyId.md @@ -0,0 +1 @@ +Your AWS access key ID. Used for authentication with AWS services. This key must have appropriate permissions for EC2 describe instance operations. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/filters.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/filters.md new file mode 100644 index 000000000..82706c709 --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/filters.md @@ -0,0 +1 @@ +A struct of filters to apply to the instance description request. Each key in the struct is a filter name, and its value is an array of filter values. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/host.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/host.md new file mode 100644 index 000000000..a00bb2ac3 --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/host.md @@ -0,0 +1 @@ +The endpoint or the provider to connect to. If not set, Amazon AWS is used. This can be used to specify a different AWS region or a custom EC2-compatible endpoint. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/instanceIds.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/instanceIds.md new file mode 100644 index 000000000..6042f08ba --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/instanceIds.md @@ -0,0 +1 @@ +An array of instance IDs specifying the EC2 instances to describe. If not provided, information for all instances will be returned. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/location.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/location.md new file mode 100644 index 000000000..2ecd5e10a --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/location.md @@ -0,0 +1 @@ +The AWS region hosting the EC2 endpoint. If not specified, the default region associated with the provided credentials is used. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/secretAccessKey.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/secretAccessKey.md new file mode 100644 index 000000000..9f2078770 --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/secretAccessKey.md @@ -0,0 +1 @@ +Your AWS secret access key associated with the access key ID. This key is used in conjunction with the accessKeyId for authentication. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_arguments/timeout.md b/docs/03.reference/01.functions/ec2describeinstances/_arguments/timeout.md new file mode 100644 index 000000000..0e0bd05f9 --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/_arguments/timeout.md @@ -0,0 +1 @@ +The timeout in milliseconds for the EC2 describe instances request. Defaults to 10000 milliseconds (10 seconds). \ No newline at end of file diff --git a/docs/03.reference/01.functions/ec2describeinstances/_returnTypeDesc.md b/docs/03.reference/01.functions/ec2describeinstances/_returnTypeDesc.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/ec2describeinstances/_usageNotes.md b/docs/03.reference/01.functions/ec2describeinstances/_usageNotes.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/ec2describeinstances/function.md b/docs/03.reference/01.functions/ec2describeinstances/function.md new file mode 100644 index 000000000..5b7c12ad0 --- /dev/null +++ b/docs/03.reference/01.functions/ec2describeinstances/function.md @@ -0,0 +1,11 @@ +--- +title: EC2describeInstances +id: function-ec2describeinstances +categories: +- s3 +- server +--- + +This function interfaces with the EC2 service to retrieve detailed information about specified EC2 instances. + +It supports custom filtering, specific instance IDs, regional targeting, and legacy mode handling. diff --git a/docs/03.reference/01.functions/empty/_arguments/variable.md b/docs/03.reference/01.functions/empty/_arguments/variable.md index e69de29bb..15bbec18a 100644 --- a/docs/03.reference/01.functions/empty/_arguments/variable.md +++ b/docs/03.reference/01.functions/empty/_arguments/variable.md @@ -0,0 +1 @@ +Variable to check \ No newline at end of file diff --git a/docs/03.reference/01.functions/gethttprequestdata/function.md b/docs/03.reference/01.functions/gethttprequestdata/function.md index ba0a482b1..7ba16d8eb 100644 --- a/docs/03.reference/01.functions/gethttprequestdata/function.md +++ b/docs/03.reference/01.functions/gethttprequestdata/function.md @@ -2,9 +2,10 @@ title: GetHTTPRequestData id: function-gethttprequestdata related: -categories: +- function-gethttprequestheaders +- function-getpagecontext --- Makes HTTP request headers and body available to CFML pages. Useful for capturing SOAP request data, which can be delivered -in an HTTP header. \ No newline at end of file +in an HTTP header. diff --git a/docs/03.reference/01.functions/htmlparse/_arguments/html.md b/docs/03.reference/01.functions/htmlparse/_arguments/html.md index e69de29bb..2de40ed0b 100644 --- a/docs/03.reference/01.functions/htmlparse/_arguments/html.md +++ b/docs/03.reference/01.functions/htmlparse/_arguments/html.md @@ -0,0 +1 @@ +A string or a variable that contains one, with HTML to be parsed \ No newline at end of file diff --git a/docs/03.reference/01.functions/logallthreads/_arguments/duration.md b/docs/03.reference/01.functions/logallthreads/_arguments/duration.md new file mode 100644 index 000000000..504e91b64 --- /dev/null +++ b/docs/03.reference/01.functions/logallthreads/_arguments/duration.md @@ -0,0 +1,9 @@ +Total duration (in milliseconds) for which the function will collect thread data. + +After this period, logging automatically stops. + +Common durations: + +- 1000-5000ms: Quick snapshots +- 10000ms: Standard analysis period +- 30000ms+: Extended analysis for complex operations \ No newline at end of file diff --git a/docs/03.reference/01.functions/logallthreads/_arguments/interval.md b/docs/03.reference/01.functions/logallthreads/_arguments/interval.md new file mode 100644 index 000000000..544b746db --- /dev/null +++ b/docs/03.reference/01.functions/logallthreads/_arguments/interval.md @@ -0,0 +1,8 @@ +The time interval (in milliseconds) between stack trace captures. Lower values provide +more detailed analysis but generate larger log files and may impact performance. + +Recommended ranges: + +- 1-10ms: Very detailed analysis, higher overhead +- 10-100ms: Balanced detail and performance +- 100ms+: Lower detail, minimal performance impact \ No newline at end of file diff --git a/docs/03.reference/01.functions/logallthreads/_arguments/path.md b/docs/03.reference/01.functions/logallthreads/_arguments/path.md new file mode 100644 index 000000000..c95578518 --- /dev/null +++ b/docs/03.reference/01.functions/logallthreads/_arguments/path.md @@ -0,0 +1,5 @@ +Full file path where the log will be written. The file should have a `.jsonl` extension +for proper identification as a JSON Lines format file. The function will create the file +if it doesn't exist, or append to it if it does. + +Example: `/var/log/lucee/thread_analysis.jsonl` \ No newline at end of file diff --git a/docs/03.reference/01.functions/logallthreads/_returnTypeDesc.md b/docs/03.reference/01.functions/logallthreads/_returnTypeDesc.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/logallthreads/_usageNotes.md b/docs/03.reference/01.functions/logallthreads/_usageNotes.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/logallthreads/function.md b/docs/03.reference/01.functions/logallthreads/function.md new file mode 100644 index 000000000..93e3fecb5 --- /dev/null +++ b/docs/03.reference/01.functions/logallthreads/function.md @@ -0,0 +1,28 @@ +--- +title: LogAllThreads +id: function-logallthreads +categories: +- debugging +- server +- system +- thread +--- + +Creates detailed thread stack trace logs in JSONL format for performance analysis and debugging. + +This function captures stack traces from all running threads at specified intervals for a given duration. + +It executes asynchronously, returning immediately after starting the logging process, making it ideal +for analyzing specific code segments by initiating logging just before the target code execution. + +The output format is JSONL (JSON Lines), where each line represents a separate JSON object containing: + +- Timestamp offset in milliseconds from 1/1/1970 00:00:00 UTC (Unix 0) +- Complete stack trace of each thread's current location + +This data can be used for: + +- Performance bottleneck identification +- Thread behavior analysis +- Deadlock detection +- Resource usage patterns diff --git a/docs/03.reference/01.functions/lsdateformat/_arguments/mask.md b/docs/03.reference/01.functions/lsdateformat/_arguments/mask.md index e69de29bb..390a66754 100644 --- a/docs/03.reference/01.functions/lsdateformat/_arguments/mask.md +++ b/docs/03.reference/01.functions/lsdateformat/_arguments/mask.md @@ -0,0 +1,23 @@ +Characters that show how Lucee displays a date: + +- `d`: Day of the month as digits; no leading zero for single-digit days. +- `dd`: Day of the month as digits; leading zero for single-digit days. +- `ddd`: Day of the week as a three-letter abbreviation. +- `dddd`: Day of the week as its full name. +- `m`: Month as digits; no leading zero for single-digit months. +- `mm`: Month as digits; leading zero for single-digit months. +- `mmm`: Month as a three-letter abbreviation. +- `mmmm`: Month as its full name. +- `yy`: Year as last two digits; leading zero for years less than 10. +- `yyyy`: Year represented by four digits. +- `gg`: Period/era string. Ignored. Reserved. The following masks tell how to format the full date and cannot be combined with other masks: +- `z`: Time zone in literal format, for example, IST +- `Z`: Time zone in hours of offset (RFC 822 TimeZone), for example, +0530 +- `X`: Time zone in hours of offset in ISO 8601 format. The following are the three ways of using 'X': + - `X`: +05 + - `XX`: +0530 + - `XXX`: +5:30 +- `short`: equivalent to m/d/y +- `medium`: equivalent to mmm d, yyyy +- `long`: equivalent to mmmm d, yyyy +- `full`: equivalent to dddd, mmmm d, yyyy \ No newline at end of file diff --git a/docs/03.reference/01.functions/lsdatetimeformat/_arguments/mask.md b/docs/03.reference/01.functions/lsdatetimeformat/_arguments/mask.md index 19a5a4f87..e20e1ed74 100644 --- a/docs/03.reference/01.functions/lsdatetimeformat/_arguments/mask.md +++ b/docs/03.reference/01.functions/lsdatetimeformat/_arguments/mask.md @@ -1,52 +1,55 @@ Mask that has to be used for formatting. Date time formatting mask (case sensitive): -- a,..,aaaa: AM/PM marker (see also "t" and "tt"; Example:AM) -- d: Day in month, no leading zero for single-digit days (Example:3) -- dd: Day in month, leading zero for single-digit days (Example:03) -- D: Day in year, no leading zero for single-digit days (Example:4) -- DD: Day in year, leading zero for single-digit days (Example:04) -- DDD: Day in year, 2 leading zero for single-digit days (Example:004) -- E,EE,EEE: Day of week as a three-letter abbreviation (Example:Tue) -- EEEE: Day of week as its full name (Example:Tuesday) -- F: Day of week in month, no leading zero for single-digit days (Example:4) -- FF: Day of week in month, leading zero for single-digit days (Example:04) -- G,GG: Era designator (Example:AD) -- h: Hour in am/pm (1-12), no leading zero for single-digit hours (Example:3) -- hh: Hour in am/pm (1-12), leading zero for single-digit hours (Example:03) -- H: Hour in day (0-23), no leading zero for single-digit hours (Example:14) -- HH: Hour in day (00-23), leading zero for single-digit hours (Example:14) -- k: Hour in day (1-24), no leading zero for single-digit hours (Example:15) -- kk: Hour in day (1-24), leading zero for single-digit hours (Example:15) -- K: Hour in am/pm (0-11), no leading zero for single-digit hours (Example:2) -- KK: Hour in am/pm (0-11), leading zero for single-digit hours (Example:02) -- l,L: milliseconds, with no leading zeros (Example:3) -- ll,LL: milliseconds, leading zero for single-digit days (Example:03) -- lll,LLL: milliseconds, 2 leading zero for single-digit days (Example:003) -- m,M: Month as digits, no leading zero for single-digit months (Example:6) -- mm,MM: Month as digits, leading zero for single-digit months (Example:06) -- mmm,MMM: Month as a three-letter abbreviation (Example:Jun) -- mmmm,MMMM: Month as its full name (Example:June) -- n,N: minutes in hour, no leading zero for single-digit minutes (Example:3) -- nn,NN: minutes in hour, leading zero for single-digit minutes (Example:03) -- s,S: seconds in minute, no leading zero for single-digit seconds (Example:3) -- ss,SS: seconds in minute, leading zero for single-digit seconds (Example:03) -- t,T: one-character time marker string (Example:P) -- tt,TT: multiple-character time marker string (Example:PM) -- w: Week in year, no leading zero for single-digit hours (Example:27) -- ww: Week in year, leading zero for single-digit hours (Example:27) -- W: Week in month, no leading zero for single-digit hours (Example:2) -- WW: Week in month, leading zero for single-digit hours (Example:02) -- y,yy,yyy: Year as last two digits, leading zero for single-digit (Example:09) -- yyyy: Year represented by four digits (Example:2009) -- z,zz,zzz: General time zone as a 3 to 4 letter abbreviation (Example:PST) -- zzzz: General time zone as its full name (Example:Pacific Standard Time) -- Z,..,ZZZZ: RFC 822 time zone (Example:-0800) +- `a,..,aaaa`: AM/PM marker (see also "t" and "tt"; Example:AM) +- `d`: Day in month, no leading zero for single-digit days (Example:3) +- `dd`: Day in month, leading zero for single-digit days (Example:03) +- `D`: Day in year, no leading zero for single-digit days (Example:4) +- `DD`: Day in year, leading zero for single-digit days (Example:04) +- `DDD`: Day in year, 2 leading zero for single-digit days (Example:004) +- `E,EE,EEE`: Day of week as a three-letter abbreviation (Example:Tue) +- `EEEE`: Day of week as its full name (Example:Tuesday) +- `F`: Day of week in month, no leading zero for single-digit days (Example:4) +- `FF`: Day of week in month, leading zero for single-digit days (Example:04) +- `G,GG`: Era designator (Example:AD) +- `h`: Hour in am/pm (1-12), no leading zero for single-digit hours (Example:3) +- `hh`: Hour in am/pm (1-12), leading zero for single-digit hours (Example:03) +- `H`: Hour in day (0-23), no leading zero for single-digit hours (Example:14) +- `HH`: Hour in day (00-23), leading zero for single-digit hours (Example:14) +- `k`: Hour in day (1-24), no leading zero for single-digit hours (Example:15) +- `kk`: Hour in day (1-24), leading zero for single-digit hours (Example:15) +- `K`: Hour in am/pm (0-11), no leading zero for single-digit hours (Example:2) +- `KK`: Hour in am/pm (0-11), leading zero for single-digit hours (Example:02) +- `l,L`: milliseconds, with no leading zeros (Example:3) +- `ll,LL`: milliseconds, leading zero for single-digit days (Example:03) +- `lll,LLL`: milliseconds, 2 leading zero for single-digit days (Example:003) +- `m,M`: Month as digits, no leading zero for single-digit months (Example:6) +- `mm,MM`: Month as digits, leading zero for single-digit months (Example:06) +- `mmm,MMM`: Month as a three-letter abbreviation (Example:Jun) +- `mmmm,MMMM`: Month as its full name (Example:June) +- `n,N`: minutes in hour, no leading zero for single-digit minutes (Example:3) +- `nn,NN`: minutes in hour, leading zero for single-digit minutes (Example:03) +- `s,S`: seconds in minute, no leading zero for single-digit seconds (Example:3) +- `ss,SS`: seconds in minute, leading zero for single-digit seconds (Example:03) +- `t,T`: one-character time marker string (Example:P) +- `tt,TT`: multiple-character time marker string (Example:PM) +- `w`: Week in year, no leading zero for single-digit hours (Example:27) +- `ww`: Week in year, leading zero for single-digit hours (Example:27) +- `W`: Week in month, no leading zero for single-digit hours (Example:2) +- `WW`: Week in month, leading zero for single-digit hours (Example:02) +- `y,yy,yyy`: Year as last two digits, leading zero for single-digit (Example:09) +- `yyyy`: Year represented by four digits (Example:2009) +- `z,zz,zzz`: General time zone as a 3 to 4 letter abbreviation (Example:PST) +- `zzzz`: General time zone as its full name (Example:Pacific Standard Time) +- `Z,..,ZZZZ`: RFC 822 time zone (Example:-0800) The following masks can be used to format the full date and time and may not be combined with other masks: -- short: equivalent to "m/d/y h:nn tt" -- medium: equivalent to "mmm d, yyyy h:nn:ss tt" -- long: medium followed by three-letter time zone; i.e. "mmmm d, yyyy h:nn:ss tt zzz" -- full: equivalent to "dddd, mmmm d, yyyy h:nn:ss tt zz" -- ISO8601/ISO: equivalent to "yyyy-mm-dd'T'HH:nn:ssXXX" \ No newline at end of file +- `short`: equivalent to "m/d/y h:nn tt" +- `medium`: equivalent to "mmm d, yyyy h:nn:ss tt" +- `long`: medium followed by three-letter time zone; i.e. "mmmm d, yyyy h:nn:ss tt zzz" +- `full`: equivalent to "dddd, mmmm d, yyyy h:nn:ss tt zz" +- `ISO8601/ISO`: equivalent to "yyyy-mm-dd'T'HH:nn:ssXXX" +- `ISOMillis/ISOMs/javascript`: Javascript style ISO date, equivalent to "yyyy-mm-dd'T'HH:nn:ss.SSSXXX" +- `epoch`: Total seconds of a given date (Example:1567517664) +- `epochms`: Total millseconds of a given date (Example:1567517664000) \ No newline at end of file diff --git a/docs/03.reference/01.functions/lsnumberformat/_arguments/mask.md b/docs/03.reference/01.functions/lsnumberformat/_arguments/mask.md index e69de29bb..f380b1873 100644 --- a/docs/03.reference/01.functions/lsnumberformat/_arguments/mask.md +++ b/docs/03.reference/01.functions/lsnumberformat/_arguments/mask.md @@ -0,0 +1,12 @@ +Mask that has to be used for formatting number: dollar sign, comma, and dot are mapped to their locale-specific equivalents. + +- `_,9` Digit placeholder; +- `.` decimal point; +- `0` Pads with zeros; +- `( )` less than zero, puts parentheses around the mask +- `+` plus sign before positive number minus before negative +- `-` a space before positive minus sign before negative +- `,` Separates every third decimal place with a comma. +- `L,C` Left-justifies or center-justifies number +- `$` dollar sign before formatted number. +- `^` Separates left and right formatting. \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormevictcollection/_arguments/collectionName.md b/docs/03.reference/01.functions/ormevictcollection/_arguments/collectionName.md index e69de29bb..8440b27a7 100644 --- a/docs/03.reference/01.functions/ormevictcollection/_arguments/collectionName.md +++ b/docs/03.reference/01.functions/ormevictcollection/_arguments/collectionName.md @@ -0,0 +1 @@ +Name of the collection in the component \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormevictcollection/_arguments/entityName.md b/docs/03.reference/01.functions/ormevictcollection/_arguments/entityName.md index e69de29bb..325fb411d 100644 --- a/docs/03.reference/01.functions/ormevictcollection/_arguments/entityName.md +++ b/docs/03.reference/01.functions/ormevictcollection/_arguments/entityName.md @@ -0,0 +1 @@ +Entity name \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormevictcollection/_arguments/primaryKey.md b/docs/03.reference/01.functions/ormevictcollection/_arguments/primaryKey.md index e69de29bb..86c43cfa8 100644 --- a/docs/03.reference/01.functions/ormevictcollection/_arguments/primaryKey.md +++ b/docs/03.reference/01.functions/ormevictcollection/_arguments/primaryKey.md @@ -0,0 +1 @@ +Primary key of the collection or association data of the entity \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormevictentity/_arguments/entityName.md b/docs/03.reference/01.functions/ormevictentity/_arguments/entityName.md index e69de29bb..325fb411d 100644 --- a/docs/03.reference/01.functions/ormevictentity/_arguments/entityName.md +++ b/docs/03.reference/01.functions/ormevictentity/_arguments/entityName.md @@ -0,0 +1 @@ +Entity name \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormevictentity/_arguments/primaryKey.md b/docs/03.reference/01.functions/ormevictentity/_arguments/primaryKey.md index e69de29bb..5fd6b08bd 100644 --- a/docs/03.reference/01.functions/ormevictentity/_arguments/primaryKey.md +++ b/docs/03.reference/01.functions/ormevictentity/_arguments/primaryKey.md @@ -0,0 +1 @@ +Primary key value of the component \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormevictqueries/_arguments/cacheName.md b/docs/03.reference/01.functions/ormevictqueries/_arguments/cacheName.md index e69de29bb..cdc488027 100644 --- a/docs/03.reference/01.functions/ormevictqueries/_arguments/cacheName.md +++ b/docs/03.reference/01.functions/ormevictqueries/_arguments/cacheName.md @@ -0,0 +1 @@ +Name of the cache region that you want to evict \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormexecutequery/_arguments/paramsOrUnique.md b/docs/03.reference/01.functions/ormexecutequery/_arguments/paramsOrUnique.md index e69de29bb..a3ca22993 100644 --- a/docs/03.reference/01.functions/ormexecutequery/_arguments/paramsOrUnique.md +++ b/docs/03.reference/01.functions/ormexecutequery/_arguments/paramsOrUnique.md @@ -0,0 +1 @@ +Object parameter for the entity \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormexecutequery/_arguments/queryOptions.md b/docs/03.reference/01.functions/ormexecutequery/_arguments/queryOptions.md index e69de29bb..56f29640e 100644 --- a/docs/03.reference/01.functions/ormexecutequery/_arguments/queryOptions.md +++ b/docs/03.reference/01.functions/ormexecutequery/_arguments/queryOptions.md @@ -0,0 +1 @@ +Options for the query \ No newline at end of file diff --git a/docs/03.reference/01.functions/ormexecutequery/_arguments/uniqueOrQueryOptions.md b/docs/03.reference/01.functions/ormexecutequery/_arguments/uniqueOrQueryOptions.md index e69de29bb..fbd057c82 100644 --- a/docs/03.reference/01.functions/ormexecutequery/_arguments/uniqueOrQueryOptions.md +++ b/docs/03.reference/01.functions/ormexecutequery/_arguments/uniqueOrQueryOptions.md @@ -0,0 +1 @@ +Specifies if the object parameter is unique \ No newline at end of file diff --git a/docs/03.reference/01.functions/parsedatetime/_arguments/format.md b/docs/03.reference/01.functions/parsedatetime/_arguments/format.md index d5f36e686..3d7401bb8 100644 --- a/docs/03.reference/01.functions/parsedatetime/_arguments/format.md +++ b/docs/03.reference/01.functions/parsedatetime/_arguments/format.md @@ -2,52 +2,53 @@ Mask that has to be used for formatting. the following characters are pattern letters (case sensitive) representing the components of a datetime string. All other characters are not interpreted -- a,..,aaaa: AM/PM marker (see also "t" and "tt"; Example:AM) -- d: Day in month, no leading zero for single-digit days (Example:3) -- dd: Day in month, leading zero for single-digit days (Example:03) -- D: Day in year, no leading zero for single-digit days (Example:4) -- DD: Day in month, leading zero for single-digit days (Example:04) -- DDD: Day in month, 2 leading zero for single-digit days (Example:004) -- E,EE,EEE: Day of week as a three-letter abbreviation (Example:Tue) -- EEEE: Day of week as its full name (Example:Tuesday) -- F: Day of week in month, no leading zero for single-digit days (Example:4) -- FF: Day of week in month, leading zero for single-digit days (Example:04) -- G,GG: Era designator (Example:AD) -- h: Hour in am/pm (1-12), no leading zero for single-digit hours (Example:3) -- hh: Hour in am/pm (1-12), leading zero for single-digit hours (Example:03) -- H: Hour in day (0-23), no leading zero for single-digit hours (Example:14) -- HH: Hour in day (00-23), leading zero for single-digit hours (Example:14) -- k: Hour in day (1-24), no leading zero for single-digit hours (Example:15) -- kk: Hour in day (1-24), leading zero for single-digit hours (Example:15) -- K: Hour in am/pm (0-11), no leading zero for single-digit hours (Example:2) -- KK: Hour in am/pm (0-11), leading zero for single-digit hours (Example:02) -- l,L: milliseconds, with no leading zeros (Example:3) -- ll,LL: milliseconds, leading zero for single-digit days (Example:03) -- lll,LLL: milliseconds, 2 leading zero for single-digit days (Example:003) -- m,M: Month as digits, no leading zero for single-digit months (Example:6) -- mm,MM: Month as digits, leading zero for single-digit months (Example:06) -- mmm,MMM: Month as a three-letter abbreviation (Example:Jun) -- mmmm,MMMM: Month as its full name (Example:June) -- n,N: minutes in hour, no leading zero for single-digit minutes (Example:3) -- nn,NN: minutes in hour, leading zero for single-digit minutes (Example:03) -- s,S: seconds in minute, no leading zero for single-digit seconds (Example:3) -- ss,SS: seconds in minute, leading zero for single-digit seconds (Example:03) -- t,T: one-character time marker string (Example:P) -- tt,TT: multiple-character time marker string (Example:PM) -- w: Week in year, no leading zero for single-digit hours (Example:27) -- ww: Week in year, leading zero for single-digit hours (Example:27) -- W: Week in month, no leading zero for single-digit hours (Example:2) -- WW: Week in month, leading zero for single-digit hours (Example:02) -- y,yy,yyy: Year as last two digits, leading zero for single-digit (Example:09) -- yyyy: Year represented by four digits (Example:2009) -- z,zz,zzz: General time zone as a 3 to 4 letter abbreviation (Example:PST) -- zzzz: General time zone as its full name (Example:Pacific Standard Time) -- Z,..,ZZZZ: RFC 822 time zone (Example:-0800) +- `a,..,aaaa`: AM/PM marker (see also "t" and "tt"; Example:AM) +- `d`: Day in month, no leading zero for single-digit days (Example:3) +- `dd`: Day in month, leading zero for single-digit days (Example:03) +- `D`: Day in year, no leading zero for single-digit days (Example:4) +- `DD`: Day in month, leading zero for single-digit days (Example:04) +- `DDD`: Day in month, 2 leading zero for single-digit days (Example:004) +- `E,EE,EEE`: Day of week as a three-letter abbreviation (Example:Tue) +- `EEEE`: Day of week as its full name (Example:Tuesday) +- `F`: Day of week in month, no leading zero for single-digit days (Example:4) +- `FF`: Day of week in month, leading zero for single-digit days (Example:04) +- `G,GG`: Era designator (Example:AD) +- `h`: Hour in am/pm (1-12), no leading zero for single-digit hours (Example:3) +- `hh`: Hour in am/pm (1-12), leading zero for single-digit hours (Example:03) +- `H`: Hour in day (0-23), no leading zero for single-digit hours (Example:14) +- `HH`: Hour in day (00-23), leading zero for single-digit hours (Example:14) +- `k`: Hour in day (1-24), no leading zero for single-digit hours (Example:15) +- `kk`: Hour in day (1-24), leading zero for single-digit hours (Example:15) +- `K`: Hour in am/pm (0-11), no leading zero for single-digit hours (Example:2) +- `KK`: Hour in am/pm (0-11), leading zero for single-digit hours (Example:02) +- `l,L`: milliseconds, with no leading zeros (Example:3) +- `ll,LL`: milliseconds, leading zero for single-digit days (Example:03) +- `lll,LLL`: milliseconds, 2 leading zero for single-digit days (Example:003) +- `m,M`: Month as digits, no leading zero for single-digit months (Example:6) +- `mm,MM`: Month as digits, leading zero for single-digit months (Example:06) +- `mmm,MMM`: Month as a three-letter abbreviation (Example:Jun) +- `mmmm,MMMM`: Month as its full name (Example:June) +- `n,N`: minutes in hour, no leading zero for single-digit minutes (Example:3) +- `nn,NN`: minutes in hour, leading zero for single-digit minutes (Example:03) +- `s,S`: seconds in minute, no leading zero for single-digit seconds (Example:3) +- `ss,SS`: seconds in minute, leading zero for single-digit seconds (Example:03) +- `t,T`: one-character time marker string (Example:P) +- `tt,TT`: multiple-character time marker string (Example:PM) +- `w`: Week in year, no leading zero for single-digit hours (Example:27) +- `ww`: Week in year, leading zero for single-digit hours (Example:27) +- `W`: Week in month, no leading zero for single-digit hours (Example:2) +- `WW`: Week in month, leading zero for single-digit hours (Example:02) +- `y,yy,yyy`: Year as last two digits, leading zero for single-digit (Example:09) +- `yyyy`: Year represented by four digits (Example:2009) +- `z,zz,zzz`: General time zone as a 3 to 4 letter abbreviation (Example:PST) +- `zzzz`: General time zone as its full name (Example:Pacific Standard Time) +- `Z,..,ZZZZ`: RFC 822 time zone (Example:-0800) The following masks can be used to format the full date and time and may not be combined with other masks: -- short: equivalent to "m/d/y h:mm tt" -- medium: equivalent to "mmm d, yyyy h:mm:ss tt" -- long: medium followed by three-letter time zone; i.e. "mmmm d, yyyy h:mm:ss tt zzz" -- full: equivalent to "dddd, mmmm d, yyyy h:mm:ss tt zz" -- ISO8601: equivalent to "yyyy-mm-dd'T'HH:nn:ss'Z'Z" +- `short`: equivalent to "m/d/y h:mm tt" +- `medium`: equivalent to "mmm d, yyyy h:mm:ss tt" +- `long`: medium followed by three-letter time zone; i.e. "mmmm d, yyyy h:mm:ss tt zzz" +- `full`: equivalent to "dddd, mmmm d, yyyy h:mm:ss tt zz" +- `ISO8601`: equivalent to "yyyy-mm-dd'T'HH:nn:ss'Z'Z" +- `ISOMillis/ISOMs/javascript`: Javascript style ISO date, equivalent to "yyyy-mm-dd'T'HH:nn:ss.SSS'Z'Z" diff --git a/docs/03.reference/01.functions/queryaddcolumn/_arguments/array.md b/docs/03.reference/01.functions/queryaddcolumn/_arguments/array.md index e69de29bb..3b5d18665 100644 --- a/docs/03.reference/01.functions/queryaddcolumn/_arguments/array.md +++ b/docs/03.reference/01.functions/queryaddcolumn/_arguments/array.md @@ -0,0 +1 @@ +Name of an array whose elements populate the new column. \ No newline at end of file diff --git a/docs/03.reference/01.functions/queryaddcolumn/_arguments/column.md b/docs/03.reference/01.functions/queryaddcolumn/_arguments/column.md index e69de29bb..d8990686b 100644 --- a/docs/03.reference/01.functions/queryaddcolumn/_arguments/column.md +++ b/docs/03.reference/01.functions/queryaddcolumn/_arguments/column.md @@ -0,0 +1 @@ +Name of the new column. \ No newline at end of file diff --git a/docs/03.reference/01.functions/queryaddcolumn/_arguments/datatype_or_array.md b/docs/03.reference/01.functions/queryaddcolumn/_arguments/datatype_or_array.md index e69de29bb..6699d36c2 100644 --- a/docs/03.reference/01.functions/queryaddcolumn/_arguments/datatype_or_array.md +++ b/docs/03.reference/01.functions/queryaddcolumn/_arguments/datatype_or_array.md @@ -0,0 +1 @@ +Column data type. \ No newline at end of file diff --git a/docs/03.reference/01.functions/queryclose/_arguments/query.md b/docs/03.reference/01.functions/queryclose/_arguments/query.md index e69de29bb..c57d05e66 100644 --- a/docs/03.reference/01.functions/queryclose/_arguments/query.md +++ b/docs/03.reference/01.functions/queryclose/_arguments/query.md @@ -0,0 +1 @@ +Query object to close. \ No newline at end of file diff --git a/docs/03.reference/01.functions/querycolumnexists/_arguments/query.md b/docs/03.reference/01.functions/querycolumnexists/_arguments/query.md index e69de29bb..cc62ea781 100644 --- a/docs/03.reference/01.functions/querycolumnexists/_arguments/query.md +++ b/docs/03.reference/01.functions/querycolumnexists/_arguments/query.md @@ -0,0 +1 @@ +Query object to check. \ No newline at end of file diff --git a/docs/03.reference/01.functions/querycolumnlist/_arguments/query.md b/docs/03.reference/01.functions/querycolumnlist/_arguments/query.md index e69de29bb..28465ba01 100644 --- a/docs/03.reference/01.functions/querycolumnlist/_arguments/query.md +++ b/docs/03.reference/01.functions/querycolumnlist/_arguments/query.md @@ -0,0 +1 @@ +Query object to get data from. \ No newline at end of file diff --git a/docs/03.reference/01.functions/queryconvertforgrid/_arguments/page.md b/docs/03.reference/01.functions/queryconvertforgrid/_arguments/page.md index e69de29bb..440a5ad9c 100644 --- a/docs/03.reference/01.functions/queryconvertforgrid/_arguments/page.md +++ b/docs/03.reference/01.functions/queryconvertforgrid/_arguments/page.md @@ -0,0 +1 @@ +The specific page of query data to be returned. \ No newline at end of file diff --git a/docs/03.reference/01.functions/queryconvertforgrid/_arguments/pageSize.md b/docs/03.reference/01.functions/queryconvertforgrid/_arguments/pageSize.md index e69de29bb..eaf18006b 100644 --- a/docs/03.reference/01.functions/queryconvertforgrid/_arguments/pageSize.md +++ b/docs/03.reference/01.functions/queryconvertforgrid/_arguments/pageSize.md @@ -0,0 +1 @@ +Number of rows of query data on a page. \ No newline at end of file diff --git a/docs/03.reference/01.functions/querymap/_arguments/resQuery.md b/docs/03.reference/01.functions/querymap/_arguments/resQuery.md index e69de29bb..2cf5fe074 100644 --- a/docs/03.reference/01.functions/querymap/_arguments/resQuery.md +++ b/docs/03.reference/01.functions/querymap/_arguments/resQuery.md @@ -0,0 +1 @@ +Resulted query. \ No newline at end of file diff --git a/docs/03.reference/01.functions/queryrowbyindex/_arguments/index.md b/docs/03.reference/01.functions/queryrowbyindex/_arguments/index.md index e69de29bb..b80c17f2c 100644 --- a/docs/03.reference/01.functions/queryrowbyindex/_arguments/index.md +++ b/docs/03.reference/01.functions/queryrowbyindex/_arguments/index.md @@ -0,0 +1 @@ +Name of the index. \ No newline at end of file diff --git a/docs/03.reference/01.functions/quotedvaluelist/_arguments/delimiter.md b/docs/03.reference/01.functions/quotedvaluelist/_arguments/delimiter.md index e69de29bb..e7d73d008 100644 --- a/docs/03.reference/01.functions/quotedvaluelist/_arguments/delimiter.md +++ b/docs/03.reference/01.functions/quotedvaluelist/_arguments/delimiter.md @@ -0,0 +1 @@ +Characters that separate list elements. The default value is comma. \ No newline at end of file diff --git a/docs/03.reference/01.functions/serialize/_arguments/object.md b/docs/03.reference/01.functions/serialize/_arguments/object.md index e69de29bb..019996557 100644 --- a/docs/03.reference/01.functions/serialize/_arguments/object.md +++ b/docs/03.reference/01.functions/serialize/_arguments/object.md @@ -0,0 +1 @@ +An object to be serialized. \ No newline at end of file diff --git a/docs/03.reference/01.functions/soundex/_arguments/str.md b/docs/03.reference/01.functions/soundex/_arguments/str.md index e69de29bb..4c07f96ef 100644 --- a/docs/03.reference/01.functions/soundex/_arguments/str.md +++ b/docs/03.reference/01.functions/soundex/_arguments/str.md @@ -0,0 +1 @@ +A string or a variable that contains one \ No newline at end of file diff --git a/docs/03.reference/01.functions/unserializejava/_arguments/string.md b/docs/03.reference/01.functions/unserializejava/_arguments/string.md index e69de29bb..4c07f96ef 100644 --- a/docs/03.reference/01.functions/unserializejava/_arguments/string.md +++ b/docs/03.reference/01.functions/unserializejava/_arguments/string.md @@ -0,0 +1 @@ +A string or a variable that contains one \ No newline at end of file diff --git a/docs/03.reference/01.functions/validatejson/_arguments/json.md b/docs/03.reference/01.functions/validatejson/_arguments/json.md new file mode 100644 index 000000000..2c62e8a07 --- /dev/null +++ b/docs/03.reference/01.functions/validatejson/_arguments/json.md @@ -0,0 +1 @@ +String to validate \ No newline at end of file diff --git a/docs/03.reference/01.functions/validatejson/_arguments/schema.md b/docs/03.reference/01.functions/validatejson/_arguments/schema.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/validatejson/_arguments/throwonError.md b/docs/03.reference/01.functions/validatejson/_arguments/throwonError.md new file mode 100644 index 000000000..135043958 --- /dev/null +++ b/docs/03.reference/01.functions/validatejson/_arguments/throwonError.md @@ -0,0 +1 @@ +throw an exception in case of an error, when false no exception is thrown, instead the errors are returned in an array of structs. \ No newline at end of file diff --git a/docs/03.reference/01.functions/validatejson/_returnTypeDesc.md b/docs/03.reference/01.functions/validatejson/_returnTypeDesc.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/validatejson/_usageNotes.md b/docs/03.reference/01.functions/validatejson/_usageNotes.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/validatejson/function.md b/docs/03.reference/01.functions/validatejson/function.md new file mode 100644 index 000000000..da91520b7 --- /dev/null +++ b/docs/03.reference/01.functions/validatejson/function.md @@ -0,0 +1,8 @@ +--- +title: ValidateJson +id: function-validatejson +categories: +- json +--- + +validate a json string diff --git a/docs/03.reference/01.functions/valuearray/_arguments/query_column.md b/docs/03.reference/01.functions/valuearray/_arguments/query_column.md index e69de29bb..c024283d7 100644 --- a/docs/03.reference/01.functions/valuearray/_arguments/query_column.md +++ b/docs/03.reference/01.functions/valuearray/_arguments/query_column.md @@ -0,0 +1 @@ +Name of an executed query and column. Separate query name and column name with a period. \ No newline at end of file diff --git a/docs/03.reference/01.functions/websocketinfo/_arguments/addRaw.md b/docs/03.reference/01.functions/websocketinfo/_arguments/addRaw.md new file mode 100644 index 000000000..7e832e3ea --- /dev/null +++ b/docs/03.reference/01.functions/websocketinfo/_arguments/addRaw.md @@ -0,0 +1 @@ +in the session array add the raw Session object. \ No newline at end of file diff --git a/docs/03.reference/01.functions/websocketinfo/_returnTypeDesc.md b/docs/03.reference/01.functions/websocketinfo/_returnTypeDesc.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/websocketinfo/_usageNotes.md b/docs/03.reference/01.functions/websocketinfo/_usageNotes.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/03.reference/01.functions/websocketinfo/function.md b/docs/03.reference/01.functions/websocketinfo/function.md new file mode 100644 index 000000000..00f314a08 --- /dev/null +++ b/docs/03.reference/01.functions/websocketinfo/function.md @@ -0,0 +1,8 @@ +--- +title: WebSocketInfo +id: function-websocketinfo +categories: +- protocols +--- + +This functions provides information about the current websocket server instance. diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingdatabase.md b/docs/03.reference/02.tags/application/_attributes/debuggingdatabase.md index e69de29bb..a4bea2afc 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingdatabase.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingdatabase.md @@ -0,0 +1 @@ +Log debugging information from the queries in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingdump.md b/docs/03.reference/02.tags/application/_attributes/debuggingdump.md index e69de29bb..f90a60e57 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingdump.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingdump.md @@ -0,0 +1 @@ +Log debugging information from the dump tag in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingexception.md b/docs/03.reference/02.tags/application/_attributes/debuggingexception.md index e69de29bb..1aa13ab2c 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingexception.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingexception.md @@ -0,0 +1 @@ +Log debugging information from the exceptions in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingimplicitaccess.md b/docs/03.reference/02.tags/application/_attributes/debuggingimplicitaccess.md index e69de29bb..88e321bd6 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingimplicitaccess.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingimplicitaccess.md @@ -0,0 +1 @@ +Log debugging information about unscoped variables accessed in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingqueryusage.md b/docs/03.reference/02.tags/application/_attributes/debuggingqueryusage.md index e69de29bb..f87d0a24d 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingqueryusage.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingqueryusage.md @@ -0,0 +1 @@ +Log debugging information about which columns in queries are used the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingtemplate.md b/docs/03.reference/02.tags/application/_attributes/debuggingtemplate.md index e69de29bb..782d5e66d 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingtemplate.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingtemplate.md @@ -0,0 +1 @@ +Log debugging information about templates used in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingthread.md b/docs/03.reference/02.tags/application/_attributes/debuggingthread.md index e69de29bb..54b28806f 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingthread.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingthread.md @@ -0,0 +1 @@ +Log debugging information about threads used in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingtimer.md b/docs/03.reference/02.tags/application/_attributes/debuggingtimer.md index e69de29bb..bdd7c5647 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingtimer.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingtimer.md @@ -0,0 +1 @@ +Log debugging information from the timer tag in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/application/_attributes/debuggingtracing.md b/docs/03.reference/02.tags/application/_attributes/debuggingtracing.md index e69de29bb..00d24c54b 100644 --- a/docs/03.reference/02.tags/application/_attributes/debuggingtracing.md +++ b/docs/03.reference/02.tags/application/_attributes/debuggingtracing.md @@ -0,0 +1 @@ +Log debugging information from the trace tag in the request \ No newline at end of file diff --git a/docs/03.reference/02.tags/component/_attributes/alias.md b/docs/03.reference/02.tags/component/_attributes/alias.md index e69de29bb..09f121a08 100644 --- a/docs/03.reference/02.tags/component/_attributes/alias.md +++ b/docs/03.reference/02.tags/component/_attributes/alias.md @@ -0,0 +1 @@ +Defines an alternative name or alias for the component, providing flexibility in referencing the component in different contexts. \ No newline at end of file diff --git a/docs/03.reference/02.tags/component/_attributes/mappedSuperClass.md b/docs/03.reference/02.tags/component/_attributes/mappedSuperClass.md index e69de29bb..a4ed1bbae 100644 --- a/docs/03.reference/02.tags/component/_attributes/mappedSuperClass.md +++ b/docs/03.reference/02.tags/component/_attributes/mappedSuperClass.md @@ -0,0 +1 @@ +Indicates whether the component acts as a mapped superclass. A mapped superclass serves as a base class for other components to extend but does not itself represent a database entity. \ No newline at end of file diff --git a/docs/03.reference/02.tags/mail/_attributes/listener.md b/docs/03.reference/02.tags/mail/_attributes/listener.md index e69de29bb..f2ddf5c34 100644 --- a/docs/03.reference/02.tags/mail/_attributes/listener.md +++ b/docs/03.reference/02.tags/mail/_attributes/listener.md @@ -0,0 +1,26 @@ +Listener for the mail. the listener can have 2 (optional) functions, "before" and "after" that get triggered before and after sending the mail. + +The functions get all data about the mail. + +Listener is only used when `async` (spoolEnable) is set to true. + +This attribute overwrites any mail listener defined in the `application.cfc/cfapplication`. + +The "before" function can also modify some data, by returning a struct containing the following keys: + +`[ from, to, bcc, cc, replyTo, failTo, subject, charset]` + +the listener can be a component looking like this: + +``` +component { + function before( lastExecution, nextExecution, created, id, type, detail, + tries, remainingTries, closed, caller, advanced ){} + function after( lastExecution, nextExecution, created, id, type, detail, tries, + remainingTries, closed, caller, advanced, passed, exception ){} +} +``` + +a struct looking like this: + +`component {before:function(...){}, after:function(...){}}` \ No newline at end of file diff --git a/docs/03.reference/02.tags/query/_attributes/async.md b/docs/03.reference/02.tags/query/_attributes/async.md index e69de29bb..cde7253c4 100644 --- a/docs/03.reference/02.tags/query/_attributes/async.md +++ b/docs/03.reference/02.tags/query/_attributes/async.md @@ -0,0 +1,3 @@ +If set to `true`, the query is executed asynchronously by the Lucee Task manager, + +If set to `false` (default) the query is executed in the same thread that executes the request. \ No newline at end of file diff --git a/docs/03.reference/02.tags/query/_attributes/listener.md b/docs/03.reference/02.tags/query/_attributes/listener.md index e69de29bb..8664cfbc2 100644 --- a/docs/03.reference/02.tags/query/_attributes/listener.md +++ b/docs/03.reference/02.tags/query/_attributes/listener.md @@ -0,0 +1,33 @@ +Listener for the query. + +The listener can have 3 (optional) functions, `before`, `after` and `error` that get triggered before and after executing the query and in case of an exception. + +The functions get all data about the query. + +This attributes overwrites any query listener defined in the `application.cfc/cfapplication`. + +All the functions can also modify all data, by returning a struct containing the keys to overwrite following the same structure as the input coming in the argument scope. + +The listener can be a component looking like this: + +``` +component { + function before( cachedAfter, cachedWithin, columnName, datasource, dbType, debug, + maxRows, name, ormOptions, username, password, result, + returnType, timeout, timezone, unique, sql, args, params, caller){} + function after( result, meta, cachedAfter, cachedWithin, columnName, datasource, + dbType, debug, maxRows, name, ormOptions, username, password, result, + returnType, timeout, timezone, unique, sql, args, params, caller){} + function error(exception, lastExecution, nextExecution, created, id, type, detail, + tries, remainingTries, closed, caller, advanced, passed, exception){} +} +``` + +or a struct looking like this: + +``` +component { + before:function(...){}, + after:function(...){}, + error:function(...){}} +``` \ No newline at end of file diff --git a/docs/03.reference/02.tags/query/_attributes/returntype.md b/docs/03.reference/02.tags/query/_attributes/returntype.md index ac8442b50..7f68c5c36 100644 --- a/docs/03.reference/02.tags/query/_attributes/returntype.md +++ b/docs/03.reference/02.tags/query/_attributes/returntype.md @@ -1,6 +1,6 @@ -one of the following values: +One of the following values: -- query: default for all dbtype expect "hql", returns a query object -- array_of_entity: works only with dbtype "hql" and is also the default value for dbtype "hql" -- array: converts the query object into an array of structs -- struct: converts the query object into a struct using the columnKey attribute as a primary key +- `query`: default for all dbtype expect "hql", returns a query object +- `array_of_entity`: works only with dbtype "hql" and is also the default value for dbtype "hql" +- `array`: converts the query object into an array of structs +- `struct`: returns either a struct of structs where the key is specified by the keyColumn attribute and each value is a struct with a query record, or a single record if keyColumn is not set, where each key is a column name and each value has its corresponding value diff --git a/docs/03.reference/05.objects/datetime/lsdateformat/_arguments/mask.md b/docs/03.reference/05.objects/datetime/lsdateformat/_arguments/mask.md index e69de29bb..e4e68bc72 100644 --- a/docs/03.reference/05.objects/datetime/lsdateformat/_arguments/mask.md +++ b/docs/03.reference/05.objects/datetime/lsdateformat/_arguments/mask.md @@ -0,0 +1,23 @@ +Characters that show how Lucee displays a date: + +- `d`: Day of the month as digits; no leading zero for single-digit days. +- `dd`: Day of the month as digits; leading zero for single-digit days. +- `ddd`: Day of the week as a three-letter abbreviation. +- `dddd`: Day of the week as its full name. +- `m`: Month as digits; no leading zero for single-digit months. +- `mm`: Month as digits; leading zero for single-digit months. +- `mmm`: Month as a three-letter abbreviation. +- `mmmm`: Month as its full name. +- `yy`: Year as last two digits; leading zero for years less than 10. +- `yyyy`: Year represented by four digits. +- `gg`: Period/era string. Ignored. Reserved. The following masks tell how to format the full date and cannot be combined with other masks: +- `z`: Time zone in literal format, for example, IST +- `Z`: Time zone in hours of offset (RFC 822 TimeZone), for example, +0530 +- `X`: Time zone in hours of offset in ISO 8601 format. The following are the three ways of using 'X': + - `X`: +05 + - `XX`: +0530 + - `XXX`: +5:30 +- `short`: equivalent to m/d/y +- `medium`: equivalent to mmm d, yyyy +- `long`: equivalent to mmmm d, yyyy +- `full`: equivalent to dddd, mmmm d, yyyy \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/addcolumn/_arguments/array.md b/docs/03.reference/05.objects/query/addcolumn/_arguments/array.md index e69de29bb..3b5d18665 100644 --- a/docs/03.reference/05.objects/query/addcolumn/_arguments/array.md +++ b/docs/03.reference/05.objects/query/addcolumn/_arguments/array.md @@ -0,0 +1 @@ +Name of an array whose elements populate the new column. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/addcolumn/_arguments/column.md b/docs/03.reference/05.objects/query/addcolumn/_arguments/column.md index e69de29bb..d8990686b 100644 --- a/docs/03.reference/05.objects/query/addcolumn/_arguments/column.md +++ b/docs/03.reference/05.objects/query/addcolumn/_arguments/column.md @@ -0,0 +1 @@ +Name of the new column. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/addcolumn/_arguments/datatype_or_array.md b/docs/03.reference/05.objects/query/addcolumn/_arguments/datatype_or_array.md index e69de29bb..6699d36c2 100644 --- a/docs/03.reference/05.objects/query/addcolumn/_arguments/datatype_or_array.md +++ b/docs/03.reference/05.objects/query/addcolumn/_arguments/datatype_or_array.md @@ -0,0 +1 @@ +Column data type. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/columnarray/_arguments/query.md b/docs/03.reference/05.objects/query/columnarray/_arguments/query.md index e69de29bb..28465ba01 100644 --- a/docs/03.reference/05.objects/query/columnarray/_arguments/query.md +++ b/docs/03.reference/05.objects/query/columnarray/_arguments/query.md @@ -0,0 +1 @@ +Query object to get data from. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/columncount/_arguments/query.md b/docs/03.reference/05.objects/query/columncount/_arguments/query.md index e69de29bb..28465ba01 100644 --- a/docs/03.reference/05.objects/query/columncount/_arguments/query.md +++ b/docs/03.reference/05.objects/query/columncount/_arguments/query.md @@ -0,0 +1 @@ +Query object to get data from. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/columnexists/_arguments/column.md b/docs/03.reference/05.objects/query/columnexists/_arguments/column.md index e69de29bb..df02f5cfa 100644 --- a/docs/03.reference/05.objects/query/columnexists/_arguments/column.md +++ b/docs/03.reference/05.objects/query/columnexists/_arguments/column.md @@ -0,0 +1 @@ +Name of the column. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/columnexists/_arguments/query.md b/docs/03.reference/05.objects/query/columnexists/_arguments/query.md index e69de29bb..cc62ea781 100644 --- a/docs/03.reference/05.objects/query/columnexists/_arguments/query.md +++ b/docs/03.reference/05.objects/query/columnexists/_arguments/query.md @@ -0,0 +1 @@ +Query object to check. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/columnlist/_arguments/query.md b/docs/03.reference/05.objects/query/columnlist/_arguments/query.md index e69de29bb..28465ba01 100644 --- a/docs/03.reference/05.objects/query/columnlist/_arguments/query.md +++ b/docs/03.reference/05.objects/query/columnlist/_arguments/query.md @@ -0,0 +1 @@ +Query object to get data from. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/map/_arguments/resQuery.md b/docs/03.reference/05.objects/query/map/_arguments/resQuery.md index e69de29bb..2cf5fe074 100644 --- a/docs/03.reference/05.objects/query/map/_arguments/resQuery.md +++ b/docs/03.reference/05.objects/query/map/_arguments/resQuery.md @@ -0,0 +1 @@ +Resulted query. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/recordcount/_arguments/query.md b/docs/03.reference/05.objects/query/recordcount/_arguments/query.md index e69de29bb..28465ba01 100644 --- a/docs/03.reference/05.objects/query/recordcount/_arguments/query.md +++ b/docs/03.reference/05.objects/query/recordcount/_arguments/query.md @@ -0,0 +1 @@ +Query object to get data from. \ No newline at end of file diff --git a/docs/03.reference/05.objects/query/rowdatabyindex/_arguments/index.md b/docs/03.reference/05.objects/query/rowdatabyindex/_arguments/index.md index e69de29bb..27f677b0f 100644 --- a/docs/03.reference/05.objects/query/rowdatabyindex/_arguments/index.md +++ b/docs/03.reference/05.objects/query/rowdatabyindex/_arguments/index.md @@ -0,0 +1 @@ +Name of the index \ No newline at end of file diff --git a/docs/03.reference/05.objects/string/len/_arguments/string.md b/docs/03.reference/05.objects/string/len/_arguments/string.md index e69de29bb..4c07f96ef 100644 --- a/docs/03.reference/05.objects/string/len/_arguments/string.md +++ b/docs/03.reference/05.objects/string/len/_arguments/string.md @@ -0,0 +1 @@ +A string or a variable that contains one \ No newline at end of file diff --git a/docs/03.reference/05.objects/string/removechars/_arguments/count.md b/docs/03.reference/05.objects/string/removechars/_arguments/count.md index e69de29bb..5383f0a0b 100644 --- a/docs/03.reference/05.objects/string/removechars/_arguments/count.md +++ b/docs/03.reference/05.objects/string/removechars/_arguments/count.md @@ -0,0 +1 @@ +Count of characters to be removed. \ No newline at end of file diff --git a/docs/03.reference/05.objects/string/removechars/_arguments/start.md b/docs/03.reference/05.objects/string/removechars/_arguments/start.md index e69de29bb..6bdba8c28 100644 --- a/docs/03.reference/05.objects/string/removechars/_arguments/start.md +++ b/docs/03.reference/05.objects/string/removechars/_arguments/start.md @@ -0,0 +1 @@ +Start position of search from the left. \ No newline at end of file diff --git a/docs/03.reference/05.objects/struct/keytranslate/_arguments/struct.md b/docs/03.reference/05.objects/struct/keytranslate/_arguments/struct.md index e69de29bb..da03d843b 100644 --- a/docs/03.reference/05.objects/struct/keytranslate/_arguments/struct.md +++ b/docs/03.reference/05.objects/struct/keytranslate/_arguments/struct.md @@ -0,0 +1 @@ +Structure to translate \ No newline at end of file diff --git a/docs/03.reference/05.objects/xml/transform/_arguments/xsl.md b/docs/03.reference/05.objects/xml/transform/_arguments/xsl.md index e69de29bb..742b0feca 100644 --- a/docs/03.reference/05.objects/xml/transform/_arguments/xsl.md +++ b/docs/03.reference/05.objects/xml/transform/_arguments/xsl.md @@ -0,0 +1 @@ +A string containing XSL text \ No newline at end of file diff --git a/docs/04.guides/04.cookbooks/04.basic-date/page.md b/docs/04.guides/04.cookbooks/04.basic-date/page.md deleted file mode 100644 index 8f4943e1d..000000000 --- a/docs/04.guides/04.cookbooks/04.basic-date/page.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Basic Date -id: cookbook-basic-date ---- - -## Output the current date ## - -The following examples shows you how to output the current date. - -```coldfusion - - - Current date - - - -

The time is #lsdateTimeFormat(now())#

-
- - -``` - -Executing this code you will see something like the following: - -> The time is 31-Jan-2038 11:12:08 - -The tag [[tag-output]] defines for the compiler that everything within a `##` is a code expression and needs to be parsed accordingly. [[function-now]] is a function call that is returning a date object containing the current time, [[function-lsDateTimeFormat]] then converts that date to a string using "locale" specific formatting rules (default en_US). - -You can configure a different locale globally in the Lucee admin under "Settings/Regional". - -You can then configure a different locale for the current request in the Application.cfc file (for example: `this.locale="de_CH"`) or with help of the function [[function-setLocale]] or as argument of the function call itself as follows: - -```coldfusion - - - Current date - - - -

The time is #lsDateTimeFormat(date:now(),locale:'de_CH')#

-
- - -``` diff --git a/docs/04.guides/04.cookbooks/05.cache-list/page.md b/docs/04.guides/04.cookbooks/05.cache-list/page.md deleted file mode 100644 index b7b1139c6..000000000 --- a/docs/04.guides/04.cookbooks/05.cache-list/page.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: List existing Cache Connections -id: cookbook-cache-list -categories: -- cache -menuTitle: Cache Connections -description: List existing Cache Connections ---- - -# List existing Cache Connections available # - -There is now a built in function in Lucee to list existing cache connections but you can also easily do this using the following - -```cfs -/** -* returns all available cache names as an array -*/ -array function cacheNames(){ - return getPageContext().getConfig().getCacheConnections().keySet().toArray(); -} -``` - -This function returns an array containing all cache connections available. - -```cfs -/** -* checks if a cache with the given name is defined -* @cacheName name of the cache to look for -*/ -boolean function hasCache(required string cacheName){ - var it=getPageContext().getConfig().getCacheConnections().keySet().iterator(); - loop collection="#it#" item="local.name" { - if(cacheName.trim()==name) return true; - } - return false; -} -``` - -This is a variation of this function that checks if a cache with the given name exists. diff --git a/docs/04.guides/04.cookbooks/06.cached-within-request/page.md b/docs/04.guides/04.cookbooks/06.cached-within-request/page.md deleted file mode 100644 index dff60d7a1..000000000 --- a/docs/04.guides/04.cookbooks/06.cached-within-request/page.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Cache a query for the current request -id: cookbook-cached-within-request -related: -- tag-query -categories: -- cache -- query -description: Cache a Query for the current request -menuTitle: Query Caching ---- - -## Cache a Query for the current request ## - -Perhaps you're familiar with the "cachedwithin" attribute of the tag [[tag-query]], which is normally used as follows: - -```coldfusion - - select * from whatever where whatsoever='#whatsoever#' - -``` - -This caches the query result for ALL users for one second. This is sometimes used to cache a query for the current request, because usually most requests are completed in less than a second. - -The problem is that this cache applies to all requests and that's more complicated for Lucee, meaning unnecessary overhead on the system. - -Request query caching is a simple solution to this problem, replace the timespan defined in the "cachedWithin" attribute with the value "request": - -```coldfusion - - select * from whatever where whatsoever='#whatsoever#' - -``` - -Then the query is cached for only for the current request, independent of how long the request takes! diff --git a/docs/04.guides/04.cookbooks/11.configuration-administrator-cfc/page.md b/docs/04.guides/04.cookbooks/11.configuration-administrator-cfc/page.md deleted file mode 100644 index c23ff961f..000000000 --- a/docs/04.guides/04.cookbooks/11.configuration-administrator-cfc/page.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Configure Lucee within your Application -id: cookbook-configuration-administrator-cfc ---- - -# Configure Lucee within your application # - -Lucee provides a web frontend to configure the server and each web context, but you can also do this configuration from within your application -(For per request settings, please check out the" Application.cfc" section in the [Cookbook](/guides/cookbooks.html)). - -## Administrator.cfc ## - -Lucee is providing the component "Administrator.cfc" in the package "org.lucee.cfml" a package auto imported in any template, so you can simply use that component as follows - -```cfs -admin=new Administrator("web","myPassword"); // first argument is the admin type you wanna load (web|server), second the password for the Administrator -dump(admin); // show me the doc for the component -admin.updateCharset(resourceCharset:"UTF-8"); // set the resource charset - -``` - -## cfadmin Tag ## - -The component "Administrator" is far from being feature complete, so if you miss a functionality, best consult the unofficial tag "cfadmin" (undocumented) and check out how this tag is used inside the [Lucee Administrator](https://github.com/lucee/Lucee/blob/5.2/core/src/main/java/resource/component/org/lucee/cfml/Administrator.cfc). -Of course, it would be great if you could contribute your addition to the "Administrator" component. diff --git a/docs/04.guides/04.cookbooks/12.filesystem-mapping/01.filesystem-mapping-define-mapping/page.md b/docs/04.guides/04.cookbooks/12.filesystem-mapping/01.filesystem-mapping-define-mapping/page.md deleted file mode 100644 index dde0f457b..000000000 --- a/docs/04.guides/04.cookbooks/12.filesystem-mapping/01.filesystem-mapping-define-mapping/page.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: Define a mapping -id: cookbook-filesystem-mapping-define-mapping -related: -- tag-application -- function-expandpath -- cookbook-application-context-set-mapping -categories: -- application -- files -description: All about the different mappings in Lucee and how to use them ---- - -# How to define a regular Mapping # - -Lucee allows you to define a mappings to a specific location in a filesystem, so you don't always have to use the full path, in most cases the full path is not working anyway, for example with [[tag-include] does not work with a full path. - -This is supported with all the various [[lucee-resources]] supported (local, ftp, http, ram, zip ,s3 etc ). - -## Create a regular Mapping in the Administrator ## - -The most common way is to define a regular Mapping is in the Lucee Server or Web Administrator. - -The only difference between the Web and Server Administrator is, that a mapping defined in the Server Administrator is visible to all web contexts and a mapping defined in the Web Administrator only to the current web context. - -In your Administrator go to the Page "Archives & Resources/Mappings", in the section "create new Mapping" that looks like this. - -![create-mapping.png](https://bitbucket.org/repo/rX87Rq/images/4035761629-create-mapping.png) - -With "Virtual" choose the virtual path for the mapping, this is the path you will later use to address this mapping. - -"Resource" is the physical location where the mapping is pointing to, for example `C:\Projects\whatever\test`. - -With "Archive" you can map a Lucee archive (more below) to the mapping. - -"Primary" defines where a template is searched first, let's say you have set primary to "archive" and you execute the following code - -```coldfusion - -``` - -In that case Lucee is first checking the archive associated with the "/myMapping" mapping for "test.cfm", if the template is not found it there, Lucee also checks the physical location. - -"Inspect templates" defines the rule for Lucee when and if to check changes in source templates and if necessary recompile them. - -* never - once the template is compiled and loaded Lucee never check for changes as long the template is not unloaded (restart server) -* once - Lucee only checks with the first access within a request if the template has changed -* always - Lucee checks with every access to the file if the file has changed -* inherit - The mapping has no setting at all, it inherits the "inspect templates" setting made in "Settings - Performance/Caching" - -"Web accessible" defines if you can call the mapping directly from the browser or not, "/lucee" for example is a web accessible mapping, because of that you can call it in the browser as follows "/lucee/admin.cfm". - -### Compile the CFML Code inside a mapping ### - -In the detail view of a single mapping you can compile all cfm and cfc files in that mapping to test if they are syntactically correct. - -With the flag "stop on error" you can define if the process should stop if the compiler fails. - -![compile.png](https://bitbucket.org/repo/rX87Rq/images/362153996-compile.png) - -### Create an archive from a mapping ### - -In the detail view of a single mapping you can create an archive that contains all templates of the mapping in compiled form. - -With the flag "Add CFML Templates" you can define if Lucee should add the source version of the templates as well, this make sense when you need a proper error output in case of an exception (source code output) or you need to read the content of this files for example with [[tag-file]]. - -With the flag "Add Non CFML Templates" you can define if Lucee should add all non CFML files (PNG,JS,GIF,CSS ...) as well, this make sense when you need to read the content of this files for example with [[tag-file]]. - -![create-archive.png](https://bitbucket.org/repo/rX87Rq/images/2720116188-create-archive.png) - -By clicking the button "download archive" you create the archive and then you can download it directly, with the button "assign archive to mapping" you can create the mapping and directly add to the current mapping. - -## Create a Mapping in the Application.cfc ## - -Lucee allows to create mappings in your [[tag-application]], these mappings are only valid for the current request. - -```cfs -// Application.cfc -component { - this.mappings['/shop']=getDirectoryFromPath(getCurrentTemplatePath())&"shop"; -} -``` - -We define the mappings as a struct, where the key of the struct is the virtual path. - -Now you can simply use that mapping in your code - -```coldfusion - - -``` - -## Advanced ## - -In the previous example we have simply set a path, like you can see in the Administrator, a mapping can contain more data than only a physical path, of course you can use this settings also with a mapping done in the [[tag-application]]. - -```cfs -// Application.cfc -component { - this.mappings['/shop']={ - physical:getDirectoryFromPath(getCurrentTemplatePath())&"shop", - archive:getDirectoryFromPath(getCurrentTemplatePath())&"shop.lar", - primary:"archive" - }; -} -``` - -In that case we not only define a physical path, we cam also define a Lucee archive (.lar). - -"primary" defines where Lucee is checking first for a resource, let's say you have the following code - -```coldfusion - -``` - -In that case Lucee first checks in the archive for`"whatever.cfm`, if not found there, it looks inside the physical path. - -### Site Note ### - -Of course this can be done for all mapping types - -```cfs -// Application.cfc -component { - this.componentpaths=[{archive:getDirectoryFromPath(getCurrentTemplatePath())&"testbox.lar"}];// loading testbox from an archive - this.customtagpaths=[{archive:getDirectoryFromPath(getCurrentTemplatePath())&"helper.lar"}];// a collection of helper custom tags - - }; -} -``` - -### See Also ### - -- [Forcing Lucee to re-check the physical paths of application defined mappings without a restart](https://blog.simplicityweb.co.uk/123/forcing-lucee-to-re-check-the-physical-paths-of-application-defined-mappings-without-a-restart) -- [Confusion Over this.mappings And expandPath() Not Working In Lucee](https://www.bennadel.com/blog/3718-confusion-over-this-mappings-and-expandpath-not-working-in-lucee-cfml-5-3-3-62.htm) diff --git a/docs/04.guides/04.cookbooks/12.filesystem-mapping/page.md b/docs/04.guides/04.cookbooks/12.filesystem-mapping/page.md deleted file mode 100644 index 58a722220..000000000 --- a/docs/04.guides/04.cookbooks/12.filesystem-mapping/page.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: File system - Mappings -id: cookbook-filesystem-mapping -categories: -- files ---- - -## Mapping ## - -We distinguish 3 different mapping types: - -- "component" mappings used to map components (similar to a classpath in Java), -- "custom tag" mappings used to map custom tags -- "regular mappings" for the rest ([[tag-include]], [[tag-file]] ...). - -* [[cookbook-filesystem-mapping-define-mapping]] -* [[cookbook-application-context-set-mapping]] -* Define a component Mapping (TODO) -* Define a custom tag Mapping (TODO) diff --git a/docs/04.guides/04.cookbooks/14.check-for-changes/page.md b/docs/04.guides/04.cookbooks/14.check-for-changes/page.md deleted file mode 100644 index fa563975a..000000000 --- a/docs/04.guides/04.cookbooks/14.check-for-changes/page.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Check for changes -id: cookbook-check-for-changes ---- - -# Check for changes in your configuration file automatically # - -Lucee can automatically check for changes in your configuration files from the complete server or a single web context. - -This is useful if you are doing scripted deploys and/or synchronization from, for example, a master instance to many slave instances of Lucee. - -### Check for Changes in ALL the contexts - -To enable this for a whole Lucee server find lucee server XML file in: - - /lib/ext/lucee-server/context/lucee-server.xml - -At the top of this file, you should see something along the lines of: - - - -Now it's simple to add the following: - - - -Now that you have made the change you can either restart Lucee server from the administrator in: - - http://localhost:8888/lucee/admin/server.cfm?action=services.restart - -Or actually make any change in the Server Admin for the configuration to be picked up. This should now allow it to pick up any changes you have written to the lucee-server.xml file. - -### Check for changes in an individual context - -If you only want an individual context to check for changes, you can do the same configuration but you would have to go to: - - /WEB-INF/lucee/lucee-web.xml.cfm - -And and the same changes from above: - - - -Lucee will now check for any changes in the lucee configuration files every minute and if there is a change, reload it and enable those changes. - -A very handy little feature for those automated deployments! diff --git a/docs/04.guides/04.cookbooks/15.event-gateway/01.create-event-gateway/page.md b/docs/04.guides/04.cookbooks/15.event-gateway/01.create-event-gateway/page.md deleted file mode 100644 index 450b4b358..000000000 --- a/docs/04.guides/04.cookbooks/15.event-gateway/01.create-event-gateway/page.md +++ /dev/null @@ -1,325 +0,0 @@ ---- -title: Custom Event Gateways -id: create-event-gateway -categories: -- gateways -description: Here you will find a short introduction into writing your own Event Gateway type. ---- - -### Preface ### - -Here you will find a short introduction into writing your own Event Gateway type. - -Since you can write these in pure cfml (and Java when you want it), it is really simple to do. - -There are 2 to 3 files you need to create: - -* the Gateway cfc -* the Gateway Driver cfc -* A listener cfc - -### The Gateway CFC ### - -This is the file which contains the action you want your gateway to do. - -Also, it is the file which is instantiated by Lucee when the gateway starts. - -You can take the following files as an example: - -* {Lucee-install}/lib/lucee-server/context/gateway/lucee/extension/gateway/DirectoryWatcher.cfc -* {Lucee-install}/lib/lucee-server/context/gateway/lucee/extension/gateway/MailWatcher.cfc - -The example code shown underneath is a modified version of the DirectoryWatcher.cfc, which, at time of writing, is in line for reviewing at the Lucee team. - -By default, you need to have the following functions: - -* An init function, which receives the necessary config data. -* A start function, which continues to run while variables.state="running". -* A stop and restart function -* A getState function, which returns the current state of the gateway instance (running,stopping,stopped) -* A sendMessage function, which will be called when the CFML sendGatewayMessage function is used. - -The following is all the code you need: - -```lucee - - - - - - - - - - - - - - - - - - - - - - - - - <--- when restart() is called, we enter this loop until the previous execution has ended. ---> - - - - - - - - - - <--- YOUR GATEWAY ACTIONS HERE ---> - - - - - <--- sleep until the next run, but cut it into half seconds, so we can stop the gateway easily ---> - - - - - - - <--- some extra sleeping if the requested timeout is not yet completely done ---> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -I guess you noticed the comment "YOUR GATEWAY ACTIONS HERE"? That's where you add the real functionality. - -## The Gateway Driver ## - -The driver is used to configure and define your Gateway. - -With it, you define the form fields in the Lucee admin settings page for your gateway, and it makes sure that your gateway is listed as an available Gateway. - -The Gateway Driver is a CFC file, which must be added into the directory {Lucee-install}/lib/lucee-server/context/admin/gdriver/ - -## Gateway driver Functions ## - -* **getClass():string.** Returns the Java class name. If the gateway is Java based, then the Java class has to implement the interface "org.opencfml.eventgateway.Gateway". If it is not Java based, then this method must return an empty string or void. - -* **getCFCPath():string.** Returns the cfc path, when the gateway is cfc based, If it is not cfc based, then this method must return an empty string or void. - -* **getLabel():string.** The label (friendly name) of the gateway. - -* **getDescription():string** The description of the gateway - -* **onBeforeUpdate(string cfcPath, string startupMode, struct custom):void.** This method is invoked before the settings entered in the form are saved. This method can be used to validate the entered data. - -* **onBeforeError(cfcatch):void.** Invoked before an error is thrown. Can be used to throw your own error, and/or do logging. - -* **getListenerCfcMode():string.** Can be one of the following: - * "none": no listener gets defined - * "required": defining a listener is required - -* **getListenerPath():string** The default location of a listener cfc. (only used when the listenerCfcMode is not "none") - -## Example Gateway driver ## - -```lucee - - <--- The form fields which will be shown when adding a gateway instance via the Lucee admin ---> - <--- argument names (see file Gateway.cfc): displayName, name, defaultValue, required, description, type, values ---> - - - - - - - - - - - - - - - - - - - - - - - - - <--- does gven file exist? ---> - - - - - <--- interval ---> - - - - - <--- minimalsize ---> - - - - - - - - - - - - - - - - - -``` - -Also see the file Gateway.cfc, which extends the functionality of this example () - -## The Listener CFC ## - -Most gateways need a Listener CFC to respond to events occurring in the Gateway instance. For example, if the Mail watcher finds new email in the mailbox, then it needs to do something with that event; it calls a method (function) of the Listener CFC. The path to your listener CFC must be given as an argument when you create or update a gateway instance. The contents of the CFC is completely up to you, as long as it has a public function that can be called by the Gateway. - -### Example ### - -Let's say our Gateway type to create is a "filesize checker", which checks a file for a minimum filesize. If the file's size has the minimum filesize, then we will call the listener CFC. First, we'll create the listener CFC: - - - - -```lucee - - - - - - <--- create a non-existing zipfile path---> - - - - - - - - - <--- zip the file ---> - - - <--- log the zip action ---> - - - <--- now delete the file ---> - - - - - - - - - - - - - - -``` - -We will save the file as {Lucee-install}/lib/lucee-server/context/gateway/filesizechecker/FileBackuper.cfc - -Now we will add the "file size check" functionality into our gateway cfc. We'll replace "YOUR GATEWAY ACTIONS HERE" with the following: - -```lucee - -<--- get the file's size by using cfdirectory ---> - - -<--- call the listener CFC if the file size meets the minimum requirement ---> - - - -``` - -We will save the file as {Lucee-install}/lib/lucee-server/context/gateway/filesizechecker/FileSizeWatcher.cfc - -Btw: the variables.listener and variables.config variables did not just come falling from the sky; instead, it was saved to the variables scope in the init() function. - -Lastly, we need to create the Gateway driver. We can use the Gateway driver code which was shown before, and then save it as {Lucee-install}/lib/lucee-server/context/admin/gdriver/FileSizeWatcher.cfc - -Now we are almost good to go! We do need to restart Lucee to have it pick up the new Gateway driver. So just go to the server admin, click on the menu-item "Restart", and then hit the "Restart Lucee" button. - -We can add an instance of our new Gateway type now! You can do it by using cfadmin like this: - -```lucee - -``` - -Interval: time in milliseconds to wait between each check Minimalsize: the minimum filesize in bytes - -After executing the cfadmin code, or going through the admin screens, you should now have an instance of your own Event Gateway type running! - -When creating a Socket gateway or an Instant messaging gateway, you will need to do a bit more coding, but hopefully this instruction helped you out! diff --git a/docs/04.guides/04.cookbooks/15.event-gateway/02.event-gateways-lucee/page.md b/docs/04.guides/04.cookbooks/15.event-gateway/02.event-gateways-lucee/page.md deleted file mode 100644 index b4b62038f..000000000 --- a/docs/04.guides/04.cookbooks/15.event-gateway/02.event-gateways-lucee/page.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -title: Event Gateways in Lucee -id: event-gateways-lucee -related: -- function-sendgatewaymessage -categories: -- gateways -description: EG's are another way how to communicate with your Lucee server are kind of a service running on Lucee, reacting on certain events ---- - -## Lucee Event Gateways - -First of all it is necessary to explain how Event Gateways (EG) are working in the first place. -EG's are another way how to communicate with your Lucee server are kind of a service running on Lucee, reacting on certain events. These kind of events could be something along the lines of: - -* SMS sent to a certain receiver -* File change happening in a directory -* Mail received on a mail server -* Slack notification received - -What then can be done with these events is to trigger some actions that react on these events. For instance if an SMS is sent to the server asking for the current heap memory space, the server could respond with an SMS returning the details. So you basically have an event producer and an event consumer. - -Event Gateways have for a long time lived a quiet life in CFML for several reasons. The main reasons were the lack of diversity and implementations which were due to the fact that EG's had to be written in Java and not every CFML developer is very familiar with Java. Given this downside, it is understandable, that there are such few available event gateways available. - -## Lucee's approach - -In Lucee EG's can be written in CFML and this is what this description is all about, which now makes it way more attractive to write the decisive parts with your favorite language. Some parts sometimes still need perhaps a Java library, but coding around that normally is not really a problem. Just use the according JAR solution available for the specific event (like SMS or others). - -### What are the involved components in Lucee? - -There are 2 components that are important for writing an event gateway: - -* Gateway driver -* Event Gateway - -The gateway driver is a CFC that is allowing you to configure your EG. The basic Gateway driver is defining the edit fields for the configuration in the administrator. - -So for instance if you want to define the above configuration with the Event Gateway Driver CFC the CFC might look like this: - -**CustomLoggerDriver.cfc** - -``` -component extends="Gateway" { - fields = [ - field("Interval (ms)","interval","5000",true,"The interval used for checking on log events","text"), - field("Log level","logLevel","Debug",true,"Log level for the log file. Possible values are:
    -
  • Info - Starting, stopping and errors will be logged.
  • -
  • Warning - Nothing will be logged.
  • -
  • Error - Only errors will be logged.
  • -
  • Debug - Detailed messages will be logged.
", - "select","Info,Warning,Error,Debug" - ), - field("Log Filename","logFileName","susi.log",true,"The file name to be used for logging.","text") - ]; - -public string function getClass() { return ""; } - public string function getCFCPath() { return "lucee.extension.gateway.CustomLogger"; } - public string function getLabel() { return "Custom Logger"; } - public string function getDescription() { return "Catches log calls and stores them in log files"; } - - public string function onBeforeUpdate(required string cfcPath, required string startupMode, required struct custom) { - // interval - if (!isNumeric(custom.interval)) { - throw "interval [#custom.interval#] is not a numeric value"; - } else if (custom.interval LT 1) { - throw "interval [#custom.interval#] must be a positive number greater than 0"; - } - } - -} -``` - -In the above CustomLoggerDriver.cfc in the body of the component an array is defined containing the fields of the event gateway. Each element is defined by a function called field. The field function is mapped to the component Field.cfc (internal convention based Lucee calls implement this function mapping) and takes the following arguments: - -* displayName string -* name string -* defaultValue string -* required boolean -* description any -* type string -* values string - -The values above are quite self-describing. So with the function field() and the above parameters, you can define the form for the configuration of your EG. The variable names are important, since they will be passed along as in struct as an argument of the init function of the EG itself. - -### Driver Component Methods - -The following functions are available in the driver CFC and can be used in order to influence the display and setup of the EG driver. The driver is of the same kind as the datasource drivers, so some of the functions are not necessary: - -* getClass() -required only with Datasource Drivers -* getCFCPath() -contains the path to the event gateway itself. In our example the component points to lucee.extension.gateway.CustomLogger which is in the directory of the auto included components (eg. /WEB-INF/lucee/components) -* getLabel() -contains the label of the driver for selection of the Gateway -* getDescription() -The description appears at the top of the form displayed for defining the configuration values - - * onBeforeUpdate -This method allows you to do sanity checks with the values entered, like checking whether the interval is numeric or not. It is called on submission of the form. If you throw an error, the error will be displayed at the top of the form. - -After we have created the driver CFC, we need to copy it to the directory WEB-INF/lucee/context/admin/gdrivers. If the file has no syntax errors, the new driver should be available in the drop down list for new event gateways. - -When the values displayed by the EG-driver are saved, the EG might be starting up right away (depending on the mode). EG startupmode: - -* Automatic; In automatic mode, the EG will be started as soon as the context will be started. If you are using dynamic hosts, the EG will only start as soon as the particular host is called for the first time. Disabled obviously disables the EG. Consider it similar to Windows Services or Linux Daemons. -* Manual; You have to call the start/stop methods (hit the button) in order to start/stop the EG. The EG will not start at engine startup -* Disabled - -Basically when an EG is started up (according to its startup mode) is an endless loop that waits for events to happen. In our current example we will create a custom logger, that logs events to a file system with the help of the CFML function eventGatewayMessage(). The CFC looks like the one further above. In our case, the CustomLoggerDriver.cfc already allows us to define the following keys in the configuration struct for the EG: - -* interval -* logLevel -* logFileName - -These values are important for our EG which we will look at in a bit. The EG itself has been defined in the EG Driver with the help of the method getCFCPath(). So next, lets have a look at the CFC we defined above: lucee.extension.gateway.CustomLogger - -You can use any component path you like here. In the above example we are actually pointing to a directory inside the Lucee configuration directory. It is easier to store all components in that place, so that they are tied to the context you are in. Of course you can use any other mapping you desire. Here is the CustomLogger.cfc: - -``` -component { - variables.state = "stopped"; - variables.aLogs = []; - variables.stTypes = {'debug':1,'info':2,'error':3,'quiet':4}; - - public void function init(string id, struct config) { … } - public void function start() { … } - public void function stop() { … } - public void function restart() { … } - public string function getState() { return state; } - public any function sendMessage(struct data) { … } - private void function _handleError(struct catchData = {}, string functionName) { … } - private void function _log(required string sText, string sType = "quiet") { … } -} -``` - -We will have a look at the individual functions in more detail below. - -When a Lucee context is started and there are EG's defined for the context, they will be started and after the init function has been called, the start method will be called (if the startup mode is set to automatic) by Lucee. So let's have a closer look at the details. - -The init method will be called when the EG is first called either at startup or when initiated the start procedure is initiated when the start button is pressed in the Lucee Web Administrator. -In the above CFC, we are initializing the status variable and an array of log messages that we will process later on. - -``` -variables.state = "stopped"; -variables.aLogs = []; -variables.stTypes = {'debug':1,'info':2,'error':3,'quiet':4}; -``` - -The state is the label displayed when the EG is stopped or started or when it is about to start. When Lucee is determining in which state an EG is, it will call the getState() method of the EG CFC. You can actually use any state you like. We tend to use the state labels stopped, stopping, running and starting. - -When first initialized (startup of the context), the init() method is called. In our case, the init() method is just storing the passed arguments in the variables scope of the component and log a message to an EG logfile. - -``` -public void function init(string id, struct config) { - local.cfcatch = ""; - try { - variables.id = arguments.id; - variables.config = arguments.config; - _log("init"); - } catch (e) { - _handleError(cfcatch, "init"); - } -} -``` - -The arguments of the init() method are: - -* id -The ID is the name of the EG. You will need this name (which has to be unique per context) to address any message you are sending to the EG. -* config -The config argument is a struct which contains the variables that you have defined and the user has set in the instantiation of the EG. The EG driver allows you, as mentioned above, to define additional values which you now receive. Storing them in the variables scope helps us reference them for later. - -One interesting thing can be deducted from the above lines. The component that has been initiated will exist for the entire time the EG has been started. This is the case because the start method actually intentionally ends up in an endless loop, so the component never is destroyed. - -Next to that, even if a component is stopped, the get getState() method returns the correct value. So actually the EG is a singleton in the context that you are in. - -The start() method is either called in case the startup method is set to automatic at context startup time, or whenever the start method is initialized by the pressing of the start button in the Lucee Web Administrator. So let's have a look at the current start() method: - -``` -public void function start() { - local.sleepStep = variables.config.interval gt 2000 ? variables.config.interval : 2000; -try { - state="starting"; - state="running"; - while(variables.state EQ "running") { - loop array="#variables.aLogs#" index="local.iMsg" item="local.stLog" { - _log(stLog.message, stLog.type); - }; - variables.aLogs = []; - sleep(sleepStep); - } - } catch (e) { - state="failed : #cfcatch.message#"; - _handleError(cfcatch, "init"); - rethrow; -} -} -``` - -What the start method actually does is looping and eventually executing stuff that comes in through the sendMessage() method described later. - -First of all the start() method makes sure, that the value of the field interval defined in the custom configuration is not exceeding 2000 (ms). - -Then, the state is changed from stopped to starting and then to running. After this the code goes into an endless loop, which depends on the content of the state variable. So you can easily understand that when the administrator button "stop" is pressed, the status would change to stopped and the endless loop will be terminated. - -Inside the loop the EG is checking on the existence or rather the length of a message variable and calls the _log() function for every single entry. After this, the loop is paused by the sleep() function which takes the configured wait time as an argument. - -Now during the sleep time, there might be messages pouring in and stored in the aLogs variable. The _log() function is actually not necessary in any EG. It is only a custom one that we have written in order to write stuff out to a file. - -So core to the EG are the functions init(), start(), stop(), restart(), getState() and sendMessage(). All together help you define an EG. - -In our example we will have a closer look at the sendMessage() method and how it is used. The sendMessage() method looks like follows: - -``` -public any function sendMessage(struct data) { - // data receives some data to log - /* - - Check whether necessary data exists: data.keyExists("") - - when type is missing, cfthrow with available types - - types are available in variables.stTypes. - */ - local.sMessage = ""; - local.sDetail = ""; - - if (!arguments.data.keyExists("message")) { - sMessage &= "#chr(10)#Key message is required in the data struct for sendMessage(customLogger)."; - } - - if (!arguments.data.keyExists("type")) { - sMessage &= "#chr(10)#Key type is required in the data struct for sendMessage(customLogger)."; - local.availTypes = ""; - loop collection="#variables.stTypes#" item="local.sTypes" { - availTypes &= "#chr(10)#- #sTypes#"; - } - sDetail &= "#chr(10)#Available types are: #availTypes#"; - } else if (!stTypes.keyExists(arguments.data.type)) { - local.availTypes = ""; - loop collection="#variables.stTypes#" item="local.sTypes" { - availTypes &= "#chr(10)#- #sTypes#"; - } - sMessage &= "#chr(10)#Type #arguments.data.type# is not available."; - sDetail &= "#chr(10)#Available types are: #availTypes#"; - } - - if (!isEmpty(local.sMessage)) { - throw(message:sMessage, detail:sDetail); - } - - variables.aLogs.append(arguments.data); - -} -``` - -The EG method is called, when you use the function sendGatewayMessage() in any of your applications. The arguments for the function are the ID of the gateway (defined in the web administrator, when you create the gateway) and any additional argument you define in the method above. - -In this case we are passing in a struct that contains the level and the message to log. The most of the lines are just sanity checks, so that the line - -``` -variables.aLogs.append(arguments.data); -``` - -is executed with useful data. So let's see this event gateway in action. After we have defined the custom Logger EG in the administrator and stored the customLogger.cfc in the corresponding directory, let's use some code to check the functionality of the EG. - -The two methods errorHandling() and _log() are helper functions which actually either write the data or catch exceptions. - -## Testing the Event Gateway - -I have created a template called testGateway.cfm and use the following code to test the result. - -``` - - -``` - - - -Now the sanity checks kick in and prevent faulty data from being sent to the Gateway. So once we change the code to this: - -``` - - -``` - -We receive the expected blank page. In the background the message has been passed to the Gateway through the sendGateway() method and the data will be written by the start() endless loop into the logfile with the help of the method _log(). - -How you actually write your EG is totally up to you. But now, do it in CFML! - -## Further examples for Event Gateway implementations - -Above we have introduced the possibility to asynchronously log some data to a log file. There are additional other Event Gateways you can think of or use: - -* ICQ watcher -* Slack Channel inspector -* Listen to a socket -* On incoming email - -The possibilities are huge and we expect several new event gateways to emerge in the next few months. Have fun with Lucee. diff --git a/docs/04.guides/04.cookbooks/15.event-gateway/page.md b/docs/04.guides/04.cookbooks/15.event-gateway/page.md deleted file mode 100644 index 524eb19cf..000000000 --- a/docs/04.guides/04.cookbooks/15.event-gateway/page.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -title: Event Gateways -id: event-gateways-overview -categories: -- gateways ---- - -## How does an Event Gateway work? ## - -An event gateway is a background process which is continuously running. - -While running, it is doing the following: for a specific time (the "interval"), then doing what it is designed for (checking changes in a directory, polling a mailserver, etcetera). And after that, it goes to again. - -This looping and sleeping does not count for all types of event gateways btw. A socket gateway for example just instantiates a Java socket server. - -This "doing what it is designed for", will be explained in more detail underneath. - -## Which gateways are available ## - -Lucee come with 2 gateways: a Directory watcher, and a Mail watcher. - -### Directory watcher ### - -This event gateway checks a given directory for file changes. These changes (events) can be: - -* new files -* changed files -* removed files - -When this gateway starts, it first takes a snapshot of the current state of the directory. This is the starting point, from where changes are calculated. - -Please note that the files in this first snapshot are NOT seen as changes! - -So if you already have some files in the directory you want to watch, then these files are not seen as "new file" when the gateway starts. Also, when Lucee (or your whole server) restarts, then any changes which happened within this time are not seen, and will not be picked up when the Directory watcher starts up again. - -### Filters ### - -You can apply filters for what you exactly want to watch changes for: - -* **Watch subdirectories**: same as the "Recurse" option in and directoryList() -* **Extensions**: an optional list of comma delimited file extensions. The default is "*", which obviously means "all files". - -Note: the Extensions setting might be changed in the near future, due to an enhancement request. - -### Mail watcher ### - -This gateway checks a given POP mailbox for new mail. Since it only checks for new mail, all emails in the POP box with a date lesser then the startup time will be ignored. - -## Location of the gateway files ## - -The event gateways are written in CFML! This means you can easily see how they work, and you can also create your own, for example by rewriting the existing ones. - -The 2 gateways are located in: - -* {Lucee-web}/lucee/gateway/lucee/extension/gateway/DirectoryWatcher.cfc -* {Lucee-web}/lucee/gateway/lucee/extension/gateway/MailWatcher.cfc -* {Lucee-install}/lib/lucee-server/context/gateway/lucee/extension/gateway/DirectoryWatcher.cfc -* {Lucee-install}/lib/lucee-server/context/gateway/lucee/extension/gateway/MailWatcher.cfc - -Where {Lucee-web} is the "WEB-INF" directory in your webroot directory (by default), and {Lucee-install} is the Lucee installation directory. - -### How to use the Event gateway ### - -To use an event gateway, you need to create a "listener cfc". This is a cfc file with some functions, which are called when an event occurs. - -You can take the following cfcs as a starting point: - -* {Lucee-web}/lucee/gateway/lucee/extension/gateway/DirectoryWatcherListener.cfc -* {Lucee-web}/lucee/gateway/lucee/extension/gateway/MailWatcherListener.cfc - -For the Directory watcher, the cfc must have 3 functions: one for each event (new, modified, deleted). The Mail watcher only has one action, and you therefore only need to have one function in your cfc. - -You can name these functions anything you like. Just be sure to use the same names when you create the Event gateway. - -At the moment, your Listener cfc must be somewhere inside the directory {Lucee-web}/lucee/gateway/ for a gateway created in the web context (via the web admin, or ), and {Lucee-install}/lib/lucee-server/context/gateway/ for a gateway in the server context (created via the server admin, or ). - -You might want to check this enhancement request for updates regarding this location requirement. - -### Some considerations on creating a listener cfc ### - -The CGI scope does not contain useful data. For example, there is no "CGI.http_host". - -Debugging can be a bit harder, because there is no Application.cfc/cfm loaded. - -In fact, since the Event gateway is just one continuously running thread, every iteration of the Event gateway uses the same already loaded listener cfc. - -If you make any changes to your code, then you will need to stop the gateway, and then restart it. This can be done via the web or server admin. - -## Installation ## - -After you created your Listener cfc, add it somewhere in the required directory mentioned before. - -Then, you can add your gateway instance by using the server/web admin. - -Don't forget to change the "Listener CFC Path" to the cfc file you just copied. The path has a dot notation, starting inside the "gateway" directory as mentioned before. - -### Example ### - -As an example, we will create a Directory listener Event gateway instance. The function of the listener is to copy new incoming files from a directory to a backup directory. - -The listener cfc is called "BackupFilesListener.cfc". - -We will add this Event gateway into the server admin, because it's functionality is not specifically bound to a website. - -First, we create a new directory "{Lucee-install}/lib/lucee-server/context/gateway/backupFilesGateway/", and then copy the CFC inside that directory. - -Next, we go to the Lucee server admin, click on "Event gateways (beta)", and add a Directory listener gateway instance - -Most of the settings should be self-explanatory. Some comments though... - -You can see there is no function name given for the "Delete" action. That's because this example "file backup gateway" does not need to handle file deletions. - -The **Listener CFC** Path must be entered using dot notation, starting from within the directory {Lucee-install}/lib/lucee-server/context/gateway/. - -The **Interval** and **Watch subdirectory** values should always get your full attention. - -Remember that the Directory watcher actually does a complete crawl on every Interval. - -So if the directory to check contains a lot of files (and subdirectories, if you checked Watch subdirectory), then the execution of the gateway instance might take some time. - -The current Interval setting of 10 seconds in this example could also be 100 or 600 seconds, if the files in the directory do not change often, or do not get deleted. - -The **function name** of the Change and Add action is the same; they are both called onAdd. It means there is a function onAdd available in BackupFilesListener.cfc. - -This function will be called on both occasions, which is okay for a functionality that only needs to copy a given file to a certain directory. - -## Debugging your gateway implementation ## - -First thing to do, is check the Lucee logs. You can find these logs in the following directories: - -* {Lucee-install}/lib/lucee-server/context/logs/ -* {Lucee-web}/lucee/logs/ - -You can also view the logs in your web/server admin, by installing the Log Analyzer plugin. - -Also, make sure that you wrap your Listener function code inside try-catch blocks, and do something within the catch block. For example: - -```lucee - - - - <--- do your file handling here, for example copy it: ---> - - - - - - -``` - -If you do not add these try-catch blocks, and anything goes wrong, it will be much harder to find out if anything went wrong! - -For example, the above code would crash if a file with the same name already exists in the directory "C:\backupfiles\". - -It might be even wiser to just email the complete error dump, so you will be semi-instantly notified of any errors. - -### Using cfadmin with Event gateways ### - -Instead of using the server/web admin, you can also use Lucee's tag. - -Add or update a gateway instance: - -```lucee - -``` - -### Remove a gateway instance: ### - -```lucee - -``` \ No newline at end of file diff --git a/docs/04.guides/04.cookbooks/16.caches-in-application-cfc/page.md b/docs/04.guides/04.cookbooks/16.caches-in-application-cfc/page.md deleted file mode 100644 index 2ea9d5267..000000000 --- a/docs/04.guides/04.cookbooks/16.caches-in-application-cfc/page.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Adding Caches via Application.cfc -id: cookbook-caches-in-application-cfc -related: -- tag-application -categories: -- application -- cache -menuTitle: Adding Caches -description: How to add per Application caches via Application.cfc ---- - -# Adding Caches via Application.cfc - -It is possible to add cache connections in Lucee 5.1+ on a per-application basis by adding configuration to your `Application.cfc`. You can also select the default object cache, query cache, function cache, etc as well. Note if these caches use an extension that provides the cache driver, the extension must be installed already. - -To declare cache connections, create a struct called `this.cache.connections` in the pseudo constructor of your `Application.cfc`. Each key in the struct will be the name of the cache connection to create, and the value of the item will be another struct defining the properties of that cache connection. - -```javascript -this.cache.connections["myCache"] = { - class: 'org.lucee.extension.cache.eh.EHCache' - , bundleName: 'ehcache.extension' - , bundleVersion: '2.10.0.25' - , storage: false - , custom: { - "bootstrapAsynchronously":"true", - "replicatePuts":"true", - etc... - } - , default: 'object' -}; -``` - -Note, there is a shortcut for `this.cache.connections["myCache"] = {}` and that is `this.cache["myCache"] = {}`. We support both since the latter is closer to how datasources are defined. - -## Generating Cache Connection code - -The easiest way to generate the code block above is the follow these steps: - -1. Start up a Lucee server -2. Create the cache you want via the web admin -3. Edit the cache and scroll to the bottom -4. Copy the code snippet that appears directly into your `Application.cfc` - -## Cache metadata - -Let's take a look at some of the keys used to define a cache connection. - -* **class** - This is the Java class of the driver for the cache engine. -* **bundleName** - Optional. The name of the OSGI bundle to load the `class` from -* **bundleVersion** - Optional. The version of the OSGI bundle to load the `class` from. -* **storage** - A boolean that flags whether this cache can be used for client or session storage -* **custom** - A struct of key/value pairs for configuration the cache. This struct is entirely dependent on the cache driver in use, so refer to the docs for that cache driver to see the possible values. Note, some of these custom values might be required for some cache drivers to work. -* **default** - Optional. If you want this cache to be used as a default cache, then give this one of these values: `function`, `object`, `template`, `query`, `resource`, `include`, `http`, `file`, `webservice` - -## Default Caches - -When declaring a cache, you can make it the default cache for creation operations, but it is also possible to configure the default caches for each operation all at once in your `Application.cfc` like so: - -```javascript -this.cache.object = "myCache"; -this.cache.template = "AnotherCache"; -this.cache.query = "yetAnother"; -this.cache.resource = ""; -this.cache.function = ""; -this.cache.include = ""; -this.cache.http = ""; -this.cache.file = ""; -this.cache.webservice = ""; -``` - -A single cache can only be the default storage location for a single operation at a time. For example, a cache named "myCache" cannot both be the default cache for objects as well as queries. diff --git a/docs/04.guides/04.cookbooks/20.query-of-queries/page.md b/docs/04.guides/04.cookbooks/20.query-of-queries/page.md deleted file mode 100644 index 1ab4f15df..000000000 --- a/docs/04.guides/04.cookbooks/20.query-of-queries/page.md +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Query of Queries (QoQ) -id: query-of-queries -related: -- tag-query -categories: -- query -description: 'Query of queries (QoQ) is a technique for re-querying an existing (in - memory) query without another trip to the database.' ---- - -### Introduction ### - -Query of queries (QoQ) is a technique for re-querying an existing (in memory) query without another trip to the database. This allows you to dynamically combine queries from different databases. - -```lucee - - - SELECT * - FROM my_db_table - - - - - SELECT * - FROM sourceQry - -``` - -The above example isn't very useful, because ```newQry``` is a straight copy of the source query, but it demonstrates the two requirements of ```QoQ```: - -* The dbtype="query" attribute -* A source query object name (e.g., sourceQry) instead of table name in the FROM clause. - -### Example: Filtering ### - -Let's say you have the following database query, ```myQuery```: - -```lucee - - SELECT Name, Age, Location - FROM People - -``` - -You would now have a list of names, ages and locations for all the people in a query called ```myQuery```. - -Say you want to filter out people under 90 and over 18, but you don't want to hit the database again: - -```lucee - - SELECT Name, Age, Location - FROM myQuery - WHERE Age >= 18 - AND Age <= 90 - -``` - -```filteredQry``` contains the desired records. - -### Internals ### - -Lucee uses its own SQL implementation for QoQ; when that fails, HSQLDB is tried. - -Lucee's SQL implementation is a basic subset of ANSI92, but it is relatively fast. [HSQLDB is a more complete SQL implementation](http://hsqldb.org/doc/2.0/guide/sqlgeneral-chapt.html), but it is slow, as compared to Lucee's implementation. - -### Supported Constructs ### - -Even though under the hood, Lucee handles the fallback to HSQLDB automatically, it still can be useful to know what's possible with the fast Lucee SQL implementation versus the slower, fallback HSQLDB SQL implementation. - -### Lucee's SQL Implementation ### - -**Keywords and Operators** - -* <= -* <> -* = -* => -* = -* != -* ALL -* AND -* AS -* BETWEEN x AND y -* DESC/ASC -* DISTINCT -* FROM -* GROUP BY -* HAVING -* IN () -* IS -* IS NOT NULL -* IS NULL -* LIKE -* NOT -* NOT IN () -* NOT LIKE -* OR -* ORDER BY -* SELECT -* TOP -* UNION -* WHERE -* XOR - -Functions - -TODO: Flesh this out. - -### HSQLDB SQL Implementation ### - -This is the fallback for when Lucee's SQL implementation can't handle the QoQ syntax. See the [HSQLDB documentation](http://hsqldb.org/doc/2.0/guide/sqlgeneral-chapt.html) for details. - -### Footnotes ### - -Lucee Google Groups Post: SQL syntax supported by query-of-queries? diff --git a/docs/04.guides/04.cookbooks/21.Exeception-Output/page.md b/docs/04.guides/04.cookbooks/21.Exeception-Output/page.md deleted file mode 100644 index 265c5de21..000000000 --- a/docs/04.guides/04.cookbooks/21.Exeception-Output/page.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Exception Output -id: exception-output -related: -- tag-catch -- tag-rethrow -- tag-throw -- tag-try -categories: -- debugging -description: How to catch and display exceptions ---- - -## Output Exceptions ## - -How to catch and display exceptions - -#### Example #### - -```lucee - -try { - throw "an error happened"; -} -catch ( any e ){ - dump(e); -} - -Go on with your code -``` - -Result - -[[tag-Dump]] shows the full exception structure without blocking your code. Dump include all stack trace with it. - -#### Example 2 #### - -```lucee - -try { - throw "an error happened"; -} -catch ( any e ){ - echo(e); -} - -Go on with your code -``` - -Here we simply echo the exception, It shows the normal exception without blocking your code. - - diff --git a/docs/04.guides/04.cookbooks/22.Extension-Installation/page.md b/docs/04.guides/04.cookbooks/22.Extension-Installation/page.md deleted file mode 100644 index f1e4ab56b..000000000 --- a/docs/04.guides/04.cookbooks/22.Extension-Installation/page.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Extension Installation -id: extension-installation -categories: -- extensions -description: How to install Lucee extensions, manually, via a environment variable or via the admin ---- - -## Extensions ## - -In this section, you'll find information about Lucee extension installation, which can be used to add Functions, Tags, JDBC/Cache drivers and Admin Plugins to Lucee Server. - -There are several different ways to install extensions in Lucee. - -### Extension installation via Admin ### - -Extensions can be installed via the web or server admin. - -If you want to use an Extension for the whole server, you should install it under the Server Admin. If you want the extension for just for only a single web context, install it via the Web admin. - -All available Extensions are listed under **Extension -> Applications** - -![Extension](/assets/images/screenImages/Extension.png) - -Here you can see which extensions are installed and not installed. - -Installed extensions, with an update available have a red overlay. - -![Extension Details](/assets/images/screenImages/Extension_Detail.png) - -On the Extension detail page, you can upgrade or downgrade the version or uninstall it. - -With JDBC drivers, choose the version you require, the version numbers are based on the underlying JDBC Library. - -By default Lucee allows installing extensions from the following sites - -- (Official LAS Extensions) -- and (third party, community) - -### Extension installation via lex file ### - -To install an extension using the file system, first download the `.lex` file for the extension. - -You can download it from the url [https://download.lucee.org/](https://download.lucee.org/) - -Copy the `.lex` file into your ```lucee-server/deploy/``` folder. Wait for a minute, it deploy the extension automatically. You can see the installation message on `deploy.log` files. - -Another way you can upload the `.lex` file in admin, You can see "Upload new extension (experimental)" at bottom of **Extension -> Applications** page. - -* Click the browse button, -* Choose the `.lex` file, -* Click the upload button, and the Extension will be automatically installed - -### Extension installation via an Environment Variable ### - -Lucee will automatically install extensions on startup, if an environment variable is set. - -`LUCEE_EXTENSIONS=D46B46A9-A0E3-44E1-D972A04AC3A8DC10;version=1.0.19.19` - -See [[running-lucee-system-properties]] - -### Footnotes ### - -Here you can see this details on video also - -[Extension Installation](https://www.youtube.com/watch?time_continue=184&v=Vcu0OENm_ks) diff --git a/docs/04.guides/04.cookbooks/24.Query-Handling/page.md b/docs/04.guides/04.cookbooks/24.Query-Handling/page.md deleted file mode 100644 index c2f21a7bf..000000000 --- a/docs/04.guides/04.cookbooks/24.Query-Handling/page.md +++ /dev/null @@ -1,247 +0,0 @@ ---- -title: Query Handling In Lucee -id: query-handling-lucee -related: -- tag-query -- tag-queryparam -- function-queryexecute -categories: -- query -description: How to do SQL Queries with Lucee ---- - -This document explains how SQL queries are supported in Lucee. - -## Query tags ## - -[[tag-query]] different ways to use the tags in Lucee and how we can the pass the value into the query - -```lucee - - select * from Foo1890 - - -``` - -The above example just shows how to retrieve the data from the database. - -### Using QueryParam ### - -The [[tag-QueryParam]] is used inside the [[tag-query]] tag. It is used to bind the value with the SQL statement. - -```lucee - - select * from Foo1890 - where title= - - -``` - -Passing values with [[tag-QueryParam]] has two advantages: - -* The value you pass in QueryParam is very secure, -* Lucee is able to cache the query statement and reuse it as long as the value is unchanged. - -### Params ### - -Here we use params as part of [[tag-query]] tag, used to pass the value with SQL statement. - -Pass the params value with struct - -```lucee - - select * from Foo1890 - where title=:title - - -``` - -referenced as ```:key``` in sql. - -The below example shows how to pass more information using a struct. - -```lucee - - select * from Foo1890 - where title=:title - - -``` - -You can pass the params value using an array. It is referenced as '?' in SQL. - -```lucee - - select * from Foo1890 - where title=? - - -``` - -The below example shows how to pass more information using an array. - -```lucee - - select * from Foo1890 - where title=? - -``` - -## Query with script tag ## - -Lucee supports two types of script statements as shown below: - -```lucee - -query name="qry" datasource="test" params={title:{type:'varchar',value:'Susi'}} { - echo(" - select * from Foo1890 - where title=:title - "); -} -dump(qry); - -``` - -```lucee - -cfquery(name="qry",datasource="test",params={title:{type:'varchar',value:'Susi'}}) { - echo(" - select * from Foo1890 - where title=:title - "); -} -dump(qry); - -``` - -## QueryExecute ## - -Lucee includes support for [[function-QueryExecute]] via script or tag. You can pass all the arguments to the function. - -```lucee - -qry=queryExecute( - sql:"select * from Foo1890 where title=:title" - ,options:{datasource="test"} - ,params={title:{type:'varchar',value:'Susi'}} -); -dump(qry); - -``` - -Pass the values in params same as we saw in cfquerytag, In options we can pass other arguments like datasource,cachename,dbtype - -### Query Component ### - -You can do a query with component like "Query()". - -```lucee - - query=new Query(sql:"select * from Foo1890 where title=?"); - query.setParams([{type:'varchar',value:'Susi'}]); - query.setDatasource('test'); - dump(query.execute().getResult()); - -``` - -In the above example we pass the sql as part of the constructor. - -* Use setDatasource() function to set the datasource. -* Use setParams() function to set the param values. The value used is the same as we used in the tag. - -```query.execute()``` function returns detail of the component, ```query.execute().getResult()``` returns query result. - -### Query Future ### - -We are always in discussion how to improve the functions in lucee. - -This output technique ```$("Hi there")``` can be used anywhere in the file (not just inside a query). - -```lucee - -query name="qry" datasource="test" params={title:{type:'varchar',value:'Susi'}} { - $(" - select * from Foo1890 - where title=:title - "); -} -dump(qry); - -``` - -We can use not only for query, you can use any where in the file ```$("Hi there")``` make our output. This idea to make a code better - -Lucee also supports static functions as shown in the example code below: - -```lucee - -// Component gets more static functions -q=Query::new("a,b,c"); // equal to queryNew("a,b,c"), already exists -Query::execute(...); // equal to queryExecute(), coming soon - -``` - -### Query Builder ### - -Query Builder use as extension, it will not come up with core. - -It is much easier to do a simple query. - -You can - -```lucee - -// Query Builder (creates SQL in dialect based on the datasource defined) - qb=new QueryBuilder("test") - .select("lastName") - .from("person") - .where(QB::eq("firstname","Susi")); - qb.execute(); - dump(res); - -``` - -Use ```QueryBuilder("test")``` as constructor - -* define a datasource with constructor or 'setDatasource('test')' function, -* Use ```select("lastName")``` to select the column -* Use ```from("person")``` from which table you want to retrieve data, -* where statement like ```where(QB::eq("firstname","Susi"))```, - -Use ```qb.execute()``` to obtain the result. - -You can change selected column like below example - -```lucee - -// change select -qb.select(["age","firstname"]); -qb.execute(); -dump(res); - -``` - -You can also change the where condition also like below example - -```lucee - -// change where -qb.clear("where"); -qb.where( - QB::and( - QB::eq("firstname","Susi"), - QB::neq("lastname","Moser"), - QB::lt("age",18) - ) -); -qb.execute(); -dump(res); - -``` - -### Footnotes ### - -Here you can see above details in video - - diff --git a/docs/04.guides/04.cookbooks/25.Deploy-Archives/page.md b/docs/04.guides/04.cookbooks/25.Deploy-Archives/page.md deleted file mode 100644 index 5e78d4fba..000000000 --- a/docs/04.guides/04.cookbooks/25.Deploy-Archives/page.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Creating and deploying Lucee Archives (.lar files) -id: deploy-archives ---- -## Deploy Archive ## - -This document explains how to deploy an Application on a live server without using single CFML file. - -Simple example: - -### Using CFC file ### - -```lucee -//placed under outside root/component/org/lucee/examples/deploy/Test.cfc - -component test { - function salve() { - return "Hi There" - } -} - -``` - -You will need to add a mapping for the above cfc, because it's not inside the Root folder - -Create component mapping in **Archives & Resources -> Component** - -create a mapping test.cfc as like below - -``` -name: mycfc -resource: **Full folder path**/component/ -``` - -After creating the mapping, you need to create an archive file for the cfc. - -* Go to the detail view of mycfc mapping page, -* Click the button **assign archive to mapping**. - -Archive(lar file) created automatically and saved in WEB-INF\lucee\context\archives - -Now you can see the archive path on mycfc mapping - -### Using CFM file ### - -Create a mapping for below CFM file, - -```lucee -//placed under /ROOT/test/deploy/index.cfm - -test = new org.lucee.examples.deploy.Test(); -dump(test.slave()); - -``` - -``` -name: /deploy -resource: ROOT/test/deploy/index.cfm -``` - -After creating mapping in the Administrator, you can create an Archive file by clicking **assign archive to mapping** - -Now you can see the both lar files were in WEB-INF\lucee\context\archives folder. - -* One is lucee\context\archives\xxx-deploy.lar file, -* another one is lucee\context\archives\xxx-mycfc.lar - -Now you can place the archive files in your target server. - -Copy the archive files (deploy.lar, mycfc.lar) and placed in target server /WEB-INF/lucee/deploy folder wait for a minute. It successfully deploy your archives into the server. - -You can now view mappings in admin. - -### Footnotes ### - -Here you can see above details in video - -[Lucee Deploy Archive file](https://www.youtube.com/watch?time_continue=473&v=E9Z0KvspBAY) diff --git a/docs/04.guides/04.cookbooks/26.Vitural-FileSystem/page.md b/docs/04.guides/04.cookbooks/26.Vitural-FileSystem/page.md deleted file mode 100644 index 8a02ac13a..000000000 --- a/docs/04.guides/04.cookbooks/26.Vitural-FileSystem/page.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: Virtual File Systems -id: virtual-file-system -related: -- function-getvfsmetadata -categories: -- s3 -- system -description: 'Lucee support the following virtual file systems: ram, file, s3, http, - https, zip and tar' ---- - -## Virtual File Systems ## - -Lucee supports the following virtual file systems: - -- ram -- file -- s3 -- http / https -- zip -- tar - -### Local File System ### - -You may already be familiar with local file systems, the local file system is the default file system in Lucee. -That means if there is no other definition, Lucee will always use the local file system. - -A simple example - -```lucee - - sct.file=getCurrenttemplatepath(); - sct.directory=getDirectoryFromPath(sct.file); - dump(sct); - - dump(fileRead(sct.file)); - dump(directoryList(sct.directory)); - -``` - -* [[function-getcurrenttemplatepath]] returns current template path, -* [[function-getDirectoryFromPath]] returns directory, -* pass the file path to the [[function-fileRead]], to read the content of the file, -* pass the directory to [[function-directoryList]] to list all the directories in the given folder path. - -However, you can explicitly define the file system you want to use. To use a local file system, use the "//file" prefix. - -As seen in the example code above, the local file system is the default, so it is not necessary to explicitly define it. The example below shows how you can explicitly define a local file system. The result is the same as the code above. - -```lucee - -sct.file=getCurrenttemplatepath(); -sct.directory=getDirectoryFromPath(sct.file); -dump(sct); - -sct.file="file://"&sct.file; -sct.directory="file://"&sct.directory; - -dump(fileRead(sct.file)); -dump(directoryList(sct.directory)); - -``` - -### ZIP File System ### - -Another file system you can use in Lucee is the ZIP file system. -To tell Lucee to use the ZIP file system, use the prefix "zip://" and end with ! -Now the file path will look like zip://xxx/xxx/xxx/xxx/testbox-2.2.0.zip! - -A detailed example is provided below: - -```lucee - -sct.file=getCurrenttemplatepath(); -sct.directory=getDirectoryFromPath(sct.file); -dump(sct); - -sct.zipFile=sct.directory&"testbox-2.2.0.zip"; -sct.zip="Zip://"&sct.zipFile&"!" - -dump(directoryList(sct.zip)); -dump(directoryList(sct.zip&"/testbox")); -echo("
");echo(fileRead(sct.zip&"/testbox/readme.md"));echo("
") -
-``` - -### http/https File System ### - -Lucee also support the HTTP file system. Simply use the HTTP URL like you would use a file system definition. - -The below example shows how to read the file content from the Lucee docs: - -```lucee - - uri="https://docs.lucee.org/reference/functions/abs.html"; - dump(fileRead(uri)); - dump(directoryList("https://lucee.org/index.cfm")); - -``` - -### RAM File System ### - -RAM is an in Memory Filesystem that stores Files in the Memory of the Java Virtual Machine (JVM) simply by using "ram://", -unless you define a Cache in the Lucee Administrator for this Resource. - -The RAM file system has much faster access than a local file system. - -Each Web Context has it's own independent RAM Cache, it cannot be shared between multiple contexts. - -**When the available memory is low, files maybe (somewhat randomly) garbage collected (CG-ed) by the JVM from the RAM file system, increasing the memory assigned to the JVM will help avoid this** - -```lucee - -sct.ram = "ram://"; -dump(sct); -dump(directoryCreate(sct.ram&"/heidi/")); -fileWrite(sct.ram&"susi.txt", "sorglos"); -dump(directoryList(sct.ram)); - -``` - -### S3 File System ### - -S3 is a remote file system you can use from Amazon S3 storage. You will need access credentials for accessing the S3 bucket. - -Set up the S3 file system using the prefix "s3://" - -In Lucee, we can define an S3 file system in two ways: - -* Define credentials in the Application.cfc file -* Pass the credentials with the S3 URL - -```lucee - -//In Application.cfc -this.s3.accesskeyid= "xxxxxxx" -this.s3.awssecretkey= "xxxxxxx" - -sct.s3 = s3://#request.s3.accesskeyid#:#request.s3.awssecretkey#; // simply as file path -sct.s3 = "s3:///"; //If you define in cfc use like this - -dir = directoryList(sct.s3); -dump(dir); - -dir = directoryList(sct.s3&"testcasesS3/"); -dump(dir); - -dir = directoryList(sct.s3&"testcasesS3/a"); -dump(dir); - -c = fileRead(sct.s3&"testcasesS3/a/foo.txt"); -dump(c); - -``` - -### FTP File System ### - -Lucee allows you to treat a remote FTP server as a virtual filesystem. - -You will need access credentials for accessing FTP. Set up an FTP file system using the prefix "ftp://" - -```lucee - -/* How to configure default FTP settings via Application.cfc */ -this.ftp.username="..."; -this.ftp.password="..."; -this.ftp.host="ftp.lucee.org"; -this.ftp.port=21; - -/* index.cfm */ -ftp = ftp://#request.ftp.user#:#request.ftp.pass#@ftp53.world4you.com:21/; -//ftp="ftp:///"; // take credentials and host/port from Application.cfc -//ftp="ftp://ftp53.world4you.com:21/"; // take credentials from Application.cfc -//ftp="ftp://#request.ftp.user#:#request.ftp.pass#@/"; // take host/port from Application.cfc - -dir = directoryList(ftp); -dump(dir); - - -``` - -### Footnotes ### - -Here you can see above details in video - -[Lucee virtual File System](https://www.youtube.com/watch?time_continue=693&v=AzUNVYrbWiQ) diff --git a/docs/04.guides/04.cookbooks/27.PreCompiled-Code/page.md b/docs/04.guides/04.cookbooks/27.PreCompiled-Code/page.md deleted file mode 100644 index 810c7b491..000000000 --- a/docs/04.guides/04.cookbooks/27.PreCompiled-Code/page.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Precompiled -id: precompiled-code ---- -## Precompiled Code ## - -This document explains how to pre-compile code for a production server while the source code is deployed. This method avoids compilation on the production server for security reasons. We explain this method with a simple example below: - -Example: - -```lucee -//index.cfm page in current instance location like \webapps\ROOT\sample\index.cfm - -Time is -writeoutput(now()); - -``` - -Run this index.cfm page in the browser. - -* When a cfm or cfc file is executed for the first time (or after the file has been edited), a class file holding the java byte-code representing that CFML file is automatically created within the cfclasses folder, webroot --> WEB-INF --> lucee --> cfclasses folder, in a sub-folder representing your application's context, for example `CFC__lucee_tomcat_webapps_ROOT4900`. (Differently from Adobe ColdFusion, a separate class file is not created for each method/function within a cfc/cfm file.) - -* After executing a request to our `/sample/index.cfm` example above, a class file named `index_cfm$cf.class` will be created within a `sample` folder of the cfclasses folder for our application's context. - -* To demonstrate how you can deploy that compiled byte-code for a cfm as if it was the cfm itself, you can copy that class file and paste it into your original application folder (\webapps\ROOT\sample). Since you already have the original index.cfm there, rename this class file to `test.cfm`. - -* Finally, run the `/sample/test.cfm` file in your browser. It should show the same results as the index.cfm file would. - -### Footnotes ### - -Here you can see above details in video - -[Lucee Precompiled Code](https://www.youtube.com/watch?v=Yjy3bQJgphA) diff --git a/docs/04.guides/04.cookbooks/28.StaticScope/page.md b/docs/04.guides/04.cookbooks/28.StaticScope/page.md deleted file mode 100644 index a5943874b..000000000 --- a/docs/04.guides/04.cookbooks/28.StaticScope/page.md +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Static scope in components -id: static_scope -categories: -- component -- scopes -- static -description: Static scope in components is needed to create an instance of cfc and call its method ---- - -## Static scope in components ## - -Static scope in components is needed to create an instance of cfc and call its method. It is used to avoid creating an instance each time you use the cfc. - -You can create an object in the Application init() function, and make it at application scope, so you can directly call the methods. - -We explain this methodology with a simple example below: - -### Example: ### - -```luceescript -// index.cfm -directory sort="name" action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example*.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -1) Create a constructor of the component. It is the instance of the current path and also create new function hey(). - -```luceescript -// Example0.cfc - Component { - public function init() { - dump("create an instance of "&listLast(getCurrentTemplatePath(),'\/')); - } - public function hey() { - dump("Salve!"); - } - } -``` - -2) Next, we instantiate the component four times, and then call the hey() function. Run this example00.cfm page in the browser. It shows five dumps. Four dumps coming from inside of the constructor and the fifth dump is from hey(). Note that the init() function is private, so you cannot load it from outside the component. Therefore, you have no access to the message within init() from the cfscript in the example below. - -```luceescript -// example0.cfm - new Example0(); - new Example0(); - new Example0(); - cfc=new Example0(); - cfc.hey(); -``` - -### Example 1: ### - -As our code gets more complicated, we need to make some additions to it. - -* One option is to create the Component in the application scope or server scope, or to use the function GetComponentMetaData to store components in a more persistent way. -* However, using the static scope is a much better option which offers more control in how you load and how you share the data between components of the specific type. This is explained in Example1 below. - -1) This code has a new static function getInstance(). This function is not a part of the instance in Component. It is static of the specific component, but not created in any instance. - -```luceescript -// Example1.cfc -Component { - public static function getInstance() { - if(isNull(static.instance)) { - static.instance=new Example1(); - } - return static.instance; - } - private function init() { - dump("create an instance of "&listLast(getCurrentTemplatePath(),'\/')); - } - public function hey() { - dump("Salve!"); - } -} -``` - -2) This example calls the getInstance() static function four times, and calls the hey() function once. - -* Next, we run this in the browser to see that the constructor calls only one instance, and function hey() is called once. It always gets the same instance because only one exists at this time. -* We give an additional request to the same page again. No constructor is displayed. Only the hey() function contents are shown. Therefore, we know that the constructor is only showing the first request of the page. - -```luceescript -// example01.cfm - Example1::getInstance(); - Example1::getInstance(); - Example1::getInstance(); - cfc=Example1::getInstance(); - cfc.hey(); -``` - -### Example 2: ### - -1) Example2 shows the same concepts that were shown in the previous Example1, but here we pass two instances for arguments. One instance for every combination of arguments passed in firstname, lastname. Then we also call the hey() function. - -```luceescript -// Example2.cfc -Component { - public static function getInstance(required string lastname, required string firstname) { - var id=hash(lastname&":"&firstname,"quick"); - if(isNull(static.instance[id])) { - static.instance[id]=new Example2(lastname,firstname); - } - return static.instance[id]; - } - private function init(required string lastname, required string firstname) { - dump("create an instance of "&listLast(getCurrentTemplatePath(),'\/')&" for "&lastname&" "&firstname); - variables.lastname=arguments.lastname; - variables.firstname=arguments.firstname; - } - public function hey() { - dump("Salve #variables.firstname#!"); - } -} -``` - -2) Next we call the getInstance() static function five times. Here we pass three different arguments into the getInstance() function. So three instances are displayed when we run this in the browser. This indicates that the same arguments are executed only once. - -```luceescript -// example02.cfm - Example2::getInstance("Quintana","Jesus"); - Example2::getInstance("Sobchak","Walter"); - Example2::getInstance("Sobchak","Walter"); - Example2::getInstance("Sobchak","Walter"); - Example2::getInstance("Sobchak","Walter").hey(); -``` - -### Example 3: ### - -1)This example is to show the difference between the body of the instance constructor and the static constructor. - -* The static constructor constructs the whole execution when the component is loaded in the memory for first time only. It does not create the same (duplicate) instance again for the execution. -* A new instance is created for every execution of an instance constructor. - -```luceescript -// Example3.cfc -Component { - //instance constructor body - dump("this is executed every time a new instance is created"); - - //static constructor body - static { - dump("this is executed only if the component is loaded for the first time"); - } -} -``` - -2) Here we call the Example3() function twice. The first request will display three instances when run in the browser. The static constructor body will execute one time, and the instance constructor body will execute two times. - -```luceescript -// example03.cfm - new Example3(); - new Example3(); -``` - -### Example 4: ### - -1) This example shows the count of how many instances of the component get loaded. In this example we define the body of the static constructor as zero, then increase the count. The instance of the component can always access the static scope because that allows you to share data between multiple instances of the component. - -```luceescript -// Example4.cfc -Component { - static { - static.counter = 0 ; - } - static.counter++; - - dump(static.counter&" instances used so far"); -} -``` - -2) Here we call the Example4() function five times. Each time the function is called, the count of counter in the static scope increases. - -```luceescript -// example04.cfm - new Example4(); - new Example4(); - new Example4(); - new Example4(); - new Example4(); -``` - -### Example 5: ### - -1) We can also use the static scope to store constant data like HOST,PORT. - -* If we store the instance in the variable scope, you will run into problems when you have a thousand components or it gets loaded a thousand times. This is a waste of time and memory storage. -* The Static scope means that a variable example only exist once and is independent of how many instances you have. So it is more memory efficient to do it that way. You can also do the same for functions. - -```luceescript -// Example5.cfc -Component { - static{ - static.HOST="lucee.org"; - static.PORT=8080; - } - public static function splitFullName(required string fullName) { - var arr=listToArray(fullName," "); - return {'lastname':arr[1],'firstname':arr[2]}; - } - public function init(required string fullname) { - variables.fullname=static.splitFullName(fullName); - } - public string function getLastName() { - return variables.fullname.lastname; - } -} -``` - -2) Here we call the Example5() function in two ways. It has a function splitFullName() that does not need to access anything (read or write data from the disks) and a variable scope that doesn't have to be part of the instance. It returns the firstname and lastname. - -```luceescript -// example05.cfm - person=new Example5("Sobchak Walter"); - dump(person.getLastName()); - dump(Example5::splitFullName("Quintana Jesus")); -``` - -### Footnotes ### - -[Lucee 5 features reviewed: static](https://dev.lucee.org/t/lucee-5-features-reviewed-static/433) - -[Video: Lucee Static Scopes in Component Code](https://www.youtube.com/watch?v=B5ILIAbXBzo&feature=youtu.be) diff --git a/docs/04.guides/04.cookbooks/29.Threads-Scope/page.md b/docs/04.guides/04.cookbooks/29.Threads-Scope/page.md deleted file mode 100644 index c97495ac6..000000000 --- a/docs/04.guides/04.cookbooks/29.Threads-Scope/page.md +++ /dev/null @@ -1,266 +0,0 @@ ---- -title: Threads -id: thread_usage -categories: -- scopes -- thread -description: How to use threads in Lucee ---- - -## Thread Scope ## - -This document explains how to use threads in Lucee. Threads are mainly used for executing code in parallel. - -### Example 1 ### - -The below example shows normal execution, waiting for all code to resolve. Here it takes 1000 milliseconds to complete the execution. - -```lucee - -function napASecond() localmode=true { - sleep(1000); -} -start=getTickCount(); -napASecond(); -dump("done in #getTickCount()-start#ms"); - -``` - -The below example shows thread execution. Code within the thread tag runs in parallel with the execution of the other code in the cfscript. Here execution does not wait for sleep. - -```lucee - -function napASecond() localmode=true { - thread { - sleep(1000); - } -} -start=getTickCount(); -napASecond(); -dump("done in #getTickCount()-start#ms"); - -``` - -Threads run independently of other threads or code in Lucee. Lucee does not the thread first and then the following code. - -Threads are mainly used to retrieve data from the database, cfhttp, or webservice. Threads are used when it does not matter how much time it takes to execute. - -### Example 2 ### - -Here we see an example using multiple threads in Lucee. All threads run in parallel. - -```lucee - -function napASecond(index) localmode=true { - thread { - thread.start=now(); - sleep(1000) - thread.end=now(); - } -} - -start=getTickCount(); -loop from=1 to=5 index="index" { - napASecond(index); -} - -// show threads -dump(var:cfthread,expand:false); -// wait for all threads to finish -thread action="join" name=cfthread.keyList(); -// show threads -dump(var:cfthread,expand:false); - -dump("done in #getTickCount()-start#ms"); - -``` - -The above example shows five threads running in parallel. The thread action= "join" line waits for all threads to finish ```cfthread``` returns struct info of all thread status. - -Same example within tag - -```lucee - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -Here the code joins three threads "t1,t2,t3". We can join threads by name. - -### Example 3 ### - -Example 3 shows threads running in parallel using the each function. - -```lucee - -tasks = ["Susi","Sorglos"]; -start=getTickCount(); -tasks.each( - function(value, index, array){ - systemOutput(value,true); - sleep(1000); - } - ,true -); -dump("done in #getTickCount()-start#ms"); - -``` - -The ```each``` function has an optional attribute called parallel. When we set the parallel attribute as true, it runs each element in parallel. By default, this attribute is false. - -Since the two array elements run in parallel, this code executes in 1 second. - -```lucee - -tasks = []; -loop from=1 to=100 index="i" { - arrayAppend(tasks,"t"&i) -} -start=getTickCount(); -tasks.each( - function(value, index, array){ - systemOutput(value,true); - sleep(1000); - } - ,true - //,100 -); -dump("done in #getTickCount()-start#ms"); - -``` - -Here we have 100 array elements. Setting the optional attribute parallel as true, it executes in 5 seconds - not in 1 second - because by default, Lucee runs 20 threads at a time and after that, it waits for free threads. So, it takes 5 seconds to complete. - -But we have the option to set the maximum threads open at a time. If it set to 100, Lucee can open 100 threads at a time to run in parallel. Then this code only takes 1 second to complete. - -The ```each``` function is not only used for an array. It can also be used for struct and query. The below example explains each type. - -```lucee - -// ARRAY -tasks = ["a","b"]; -tasks.each( - function(value, key, struct){ - systemOutput(arguments,true); - } - ,true -); -arrayEach( - tasks - ,function(value, key, struct){ - systemOutput(arguments,true); - } - ,true -); -// STRUCT -tasks = {a:1,b:2}; -structEach( - tasks - ,function(value, key, struct){ - systemOutput(arguments,true); - } - ,true -); -tasks.each( - function(value, key, struct){ - systemOutput(arguments,true); - } - ,true -); -// QUERY -persons = query( - 'firstName':['Susi','Harry'] - ,'lastName':['Sorglos','Hirsch'] -); -queryEach( - persons - ,function(value, row, query){ - systemOutput(arguments,true); - } - ,true -); -persons.each( - function(value, row, query){ - systemOutput(arguments,true); - } - ,true -); -dump("done"); - -``` - -### Example 4 ### - -Lucee members often discuss how to extend functionality to make Lucee easier to use or adding other new functionality. - -This example shows a future implementation of threads in Lucee. - -```lucee - -// Thread Pool -tasks.each( - function(value, key, struct){ - systemOutput(arguments,true); - } - ,true - ,20 // ATM default for max threads is 20, instead we plan to use a smart thread pool in the future (Java ExecutorService) -); - -``` - -Currently, the default max threads is 20. In the future, we plan to use a smart thread pool based on your JVM(Java ExecutorService). So you will not have to take care how many threads are being used. The system will do that, and provide the best choice for your code. - -```lucee - -thread /* action="thread" name="whatever" */ { - sleep(); -} - -``` - -In the future we will make threads smarter by also using a pool for threads. - -This feature is something we are planning. Changes will be implemented on the backend so that nothing changes on the front end. - -```lucee - -// Extend parallel -loop from=1 to=10 index="i" parallel=true { - ... -} -// ??? -for(i=0;i<10;i++;true) { -} - -``` - -Another planned enhancement is to extend parallel to the loop by simply adding ```parallel=true``` . It will execute the body of the loop in parallel. - -### Footnotes ### - -Here you can see above details in video - -[Lucee Threads](https://www.youtube.com/watch?v=oGUZRrcg9KE) diff --git a/docs/04.guides/04.cookbooks/30.NullSupport/page.md b/docs/04.guides/04.cookbooks/30.NullSupport/page.md deleted file mode 100644 index 9f7290f41..000000000 --- a/docs/04.guides/04.cookbooks/30.NullSupport/page.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Null Support -id: null_support -related: -- function-isnull -- function-nullvalue ---- - -## Null Support - -This document explains how to set null support in the Lucee server admin, assigning `null` value for a variable and how to use `null` and `nullvalue`. It is an annotation of the video found here: [https://www.youtube.com/watch?v=GSlWfLR8Frs](https://www.youtube.com/watch?v=GSlWfLR8Frs) - -### Enabling NULL support - -You can enable null support via the **Lucee Server Admin** --> **Language/compiler** and setting Null support to **complete support** (exclusive to Lucee) or **partial support** (default, same as Adobe CF). - -Or via [[tag-application]] - -``` -this.nullSupport = true; -``` - -### Explanation - -#### Illustration 1: - -```lucee - - function test() { - } - dump( test() ); - - t=test(); - dump(t); - - dump( isNull( t ) ); - dump( isNull( notexisting ) ); - -``` - -In this example, the function `test()` does not return a value. This, in effect, is the same as returning `null`. If you dump the result of the function (`dump( test( ) );`), you will see that the dump outputs `Empty: Null`. - -If we assign the function result to a variable, i.e. `t = test();`, and reference the variable, i.e. `dump( t );` an error will be thrown when using **partial support** for null: "the key [T] does not exist". If we enable **full support**, you will be able to reference the variable without error, the dump output will be `Empty: Null` and `IsNull( t )` will evaluate `true`. - -In all cases, `dump( isNull( notexisting ) );` will throw an error. - -#### Illustration 2: - -```luceescript -query datasource="test" name="qry" { - echo("select '' as empty, null as _null"); -} -dump( qry ); -dump( qry._null ); -``` - -With **partial support** for NULL enabled, `dump(qry._null);` will output an **empty string**. -With **full support**, `Empty: null` will be output and `IsNull( qry._null );` will evaluate `true`. - -### NullValue() function and null keyword - -With **partial support** for NULL, the `NullValue()` function must be used to explicitly return a null value (this will work in all scenarios). For example: - -```luceescript -var possibleVariable = functionThatMayOrMayNotReturnNull(); -return possibleVariable ?: NullValue(); -``` - -With **full support**, you are able to use the `null` keyword directly and, as illustrated above, can assign it to a variable directly: - -```luceescript -t = null; -dump( t ); -``` diff --git a/docs/04.guides/04.cookbooks/31.Externalize_Strings/page.md b/docs/04.guides/04.cookbooks/31.Externalize_Strings/page.md deleted file mode 100644 index 844a92727..000000000 --- a/docs/04.guides/04.cookbooks/31.Externalize_Strings/page.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Externalize strings -id: Externalizing_Strings ---- -## Externalize strings ## - -Externalize strings from generated class files to separate files. This method is used to reduce the memory of the static contents for templates. We explain this method with a simple example below: - -**Example:** - -//index.cfm - -```lucee - - - -

....

- ....... - ....... - It was popular in the #year# - ....... - .... - - -``` - -1. Here the Index.cfm file contains a lot of strings (static contents), but there is no functionality. The file just gives a cfoutput with year. The variable string 'year' is already declared by using in top of the Index.cfm page. - -2. Execute the CFMpage in a browser. A class file is created in the ``webapps\ROOT\WEB-INF\lucee\cfclasses\`` directory while the CFM file is executed. The run time compiler compiles that file to load the Java bytecode and execute it. - -3. Right click the class file. Then see ``Get info``. For example, in my class file there is 8Kb size on the disk. In Lucee the cfm file with its strings was also loaded. So a lot of memory could be occupied just by string loading the bytecode. To avoid this problem, the Lucee admin has the following solution: - - - Lucee admin --> Language/compiler --> Externalize strings - - This ``Externalize strings`` setting has four options. Select any one option to test. We selected the fourth option (externalize strings larger than 10 characters). - - Again run the cfm page in a browser. The class file is created with lower memory size than the original 8Kb on disk. - - In addition, it created a text file too. The txt file contains the strings from the CFM page. The cfoutput with year is simply not there. The byte code will crop the piece of cfoutput content from the CFM file. - -So, the string 'year' is no longer in memory. When the bytecode is called, it loads the string into memory. The memory is not occupied forever and this reduces the footprint of our application. - -### Footnotes ### - -Here you can see above details in video - -[Externalize strings](https://youtu.be/AUcsHkVFXHE) \ No newline at end of file diff --git a/docs/04.guides/04.cookbooks/32.Startup_Listeners/page.md b/docs/04.guides/04.cookbooks/32.Startup_Listeners/page.md deleted file mode 100644 index ba537cde0..000000000 --- a/docs/04.guides/04.cookbooks/32.Startup_Listeners/page.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Startup Listeners, server.cfc and web.cfc -id: Startup Listeners-code -related: -- function-configimport -categories: -- server -- system -description: Lucee supports two types of Startup Listeners, server.cfc and web.cfc -menuTitle: Startup Listeners ---- - -## Startup Listeners Code ## - -Lucee has two kinds of startup listeners. - -- **Server.cfc** which runs when the Lucee Server starts up. It exists only once per Lucee instance. -- **Web.cfc** which can be used for each web context. - -### Server.cfc ### - -Create a `Server.cfc` file in `lucee-server\context\context` directory. - -```lucee - -// lucee-server\context\context\Server.cfc - -component{ - public function onServerStart( reload ){ - if ( !arguments.reload ){ - systemOutput("-------Server Context started -----",true); - // this is when the server is first started. - // you can for example, use configImport() to import a .cfConfig.json setting file - var config_web = "/www/config/lucee_server_cfConfig.json"; - configImport( - type: "server", - data: deserializeJSON(fileRead(config_web)), - password: "your lucee server admin password" - ); - } else { - // the server config is reloaded each time an extension is installed / or the config is updated - systemOutput( "-------Server Context config reloaded -----", true ); - } - } -} -``` - -- Here, Server.cfc has one function ``onServerStart()`` -- Start Lucee Server. -- The server console or `out.log` should show the above systemOutput's which means it has run the `Server.cfc` - -### Web.cfc ### - -Create a `Web.cfc` file in `webapps\ROOT\WEB-INF\lucee\context\` directory, or the context webroot. - -```lucee - -// webapps\ROOT\WEB-INF\lucee\context\Web.cfc - -component { - public function onWebStart( reload ){ - if ( !arguments.reload ){ - systemOutput("-------Web Context started -----",true); - // this is when the web content is first started. - // you can for example, use configImport() to import a .cfConfig.json setting file - var config_web = "/www/config/lucee_web_cfConfig.json" - configImport( - type: "web", - data: deserializeJSON( fileRead( config_web ) ), - password: "your lucee web content admin password" - ); - } else { - // the web context is reloaded each time an extension is installed / or the config is updated - systemOutput("-------Web Context config reloaded -----",true); - } - } -} -``` - -Here `Web.cfc` has one function ``onWebStart()`` and one argument ``reload`` that indicates if the web context is a new startup of the server. - -Here ``reload`` is used to reload the web context. We see the difference when setting reload to true or false. - -- Start your Lucee server. -- Here we see the server context output first, then the web context output next. So you can see that both listeners get triggered by Lucee. -- Next, change the **settings --> charset** for web charset "UTF-8" in web admin. -- After setting the charset in web admin, the web context only is reloaded and we do not have the server context. So this feature is used to stop/prevent any difficulties with the server context. - -This is a simple way to stop the server context. It is never triggered because there is no event happening inside java. - -### Footnotes ### - -Here you can see above details in video - -[Lucee Startup Listeners](https://youtu.be/b1MWLwkKdLE) diff --git a/docs/04.guides/04.cookbooks/33.Hidden_gems/page.md b/docs/04.guides/04.cookbooks/33.Hidden_gems/page.md deleted file mode 100644 index 9131f9adf..000000000 --- a/docs/04.guides/04.cookbooks/33.Hidden_gems/page.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Hidden Gems -id: hidden_gems ---- -## Hidden Gems ## - -This document explains how to declare a variables, function call with dot and bracket notation, Passing arguments via URL/form scopes as array. Explain this three with simple example below: - -#### Example 1 : Declare variables #### - -// test.cfc - -```luceescript -component { - function getName() { - return "Susi"; - } -} -``` - -// example1.cfm - -```luceescript -function test() { - var qry; - dump(qry); - query name="qry" datasource="test" { - echo("select 1 as one"); - } - dump(qry); -} -test(); -``` - -* In cfm page have test() function with local variable scope, it normally assigned in empty string ``var qry``. Then execute this cfm, the qry is returns "1". -* Then dump the ``qry`` below of the var declaration. It returns empty string. - -#### Example 2 : Dot and bracket notation for function calls #### - -Lucee allow you to use bracket notations to call a component function. - -//example2.cfm - -```luceescript -// UDF call via dot notation - test=new Test(); - dump( test.getName() ); -// Dynamic function name - funcName="getName"; - dump(evaluate('test.#funcName#()')); -// UDF call via bracket notation - funcName="getName"; - dump( test[funcName]() ); -``` - -Here this three different types of function call. There are, - -* Calling the user defined function ``getname()`` from component. -* Second type of function call is dynamic function name with evaluate function. -* Third type of function call is user defined function via bracket notation. - -These all three different function call returns as same content ``susi`` what you defined in CFC page. - -#### Example 3 : Passing arguments via URL/form scopes as Array #### - -Lucee allow to pass URL and Form scope data as an Array instead of a string list. - -//example3.cfm - -```lucee - - dump(label:"URL",var:url); - dump(label:"Form",var:form); - // current name - curr=listLast(getCurrentTemplatePath(),'\/'); - - - -

Countries

-
-
-			Countries Europe:	
-			Countries America:	
-			
-		
-
-
-``` - -// index.cfm - -```luceescript -directory sort="name" action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example*.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -* In this cfm page have available in URL and form scopes. Here names are used as same as two times. -* Query string on URL scope have same name ``country`` as two times. Similarly form also have two same name ``country``. -* Execute this cfm page in browser & submit the form. It will showing a single URL string list in merged format instead of two fields & Form fields also merged as single ``country`` field. -* If we add square bracket behind the name ``country[]`` means, it returns as two separated strings in array format. We will see the difference on browser while dumping that name with square bracket. - -These simple ways are helpful for defining a variable as different methods. - -### Footnotes ### - -Here you can see above details in video - -[Lucee Hidden Gems](https://youtu.be/4MUKPiQv1kAsss) \ No newline at end of file diff --git a/docs/04.guides/04.cookbooks/34.Types_lucee/page.md b/docs/04.guides/04.cookbooks/34.Types_lucee/page.md deleted file mode 100644 index c7af3273a..000000000 --- a/docs/04.guides/04.cookbooks/34.Types_lucee/page.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: Types in lucee -id: types_lucee ---- -## Types in lucee ## - -This document explains types in Lucee. Lucee is still an untyped language. Types are only a check put on top of the language. The language is not based on types, however there are different places where types come into Lucee. This is explained with some simple examples below: - -#### Example 1 : Function Argument and Return Value #### - -For functions, the return value is returned with the specific type that was defined in that function. - -```luceescript - -// function1.cfm - - param application.names={}; - boolean function recExists(string name, number age) { - var exists = application.names.keyExists(name); - application.names[name]=age; - dump(age); - return exists; - } - dump(recExists("Susi","15")); - void function test(array arr) { - arr[2]="two"; - } - arr={'1':'one'}; - test(arr); - dump(arr); -``` - -* This example function has two arguments: name, age (One is a string, the other is a number). When this example is executed, the recExists() function checks if a certain record exists or not and It returns the boolean value ``true``. -* When dumping the function recExists() with arguments, if we give age as a string format in the argument, ``dump(recExists("Susi","15"))``, it shows ``string 15`` even though we defined it as a number data type in the arguments. -* The test() function takes an array, but in this example I do not pass an array into the function. I have passed a struct ``arr={'1':'one'}`` value into the test() function. The test() function contains an array value ``arr[2]= "two"``, so Lucee converts this array value into a structure. So the struct has two values as per keys are 1, 2 and values are one, two. -* Lucee can handle an array as long as the keys are all numbers, meaning it considers a struct ``'1' and [2]``. Execute this cfm page, the dump shows the structure format. - -#### Example 2 : CFParam #### - -```luceescript - -// param.cfm - -param name="url.age" type="number"; -dump(label:"Age:", var:url.age); -``` - -* In this example the dump of the age parameter has a URL scope. If you execute this cfm page without passing any value into the URL for age, it will throw an error like ``The required parameter [url.age] was not provided``. -* If I pass a numeric value ``age=15``for age in the URL, it returns as expected, 15. -* If I pass a string value ``age=old`` for age in the URL, it throws an error like ``Can't cast string [old] to a value of type [value]`` - -#### Example 3 : Queries #### - -```luceescript - -//queries.cfm - -query=queryNew(["name","age"],["string","numeric"]); - row=query.addRow(); - query.name[row]="Susi"; - query.age[row]=16; - - row=query.addRow(); - query.name[row]="Heidi"; - query.age[row]=9; - - query.sort("age"); - dump(query); - dump(getMetaData(query)); - - row=query.addRow(); - query.name[row]="Urs"; - query.age[row]="old"; - - query.sort("age"); - dump(query); - dump(getMetaData(query)); -``` - -* This example has queryNew() with two columns. Name and age are defined in string and numeric format. Then the example adds two rows of values to the columns. Then we dump the query with getMetaData(). It returns the column name with the corresponding data type of the field. -* If I change the age to as string format, ``query.age[row]="old"``, it does not throw an exception. It considers both name and age fields to be varchar type. - -#### Example 4 : ArrayNew #### - -```luceescript - -// array.cfm - -names=arrayNew(type:"string"); - names[1]="Susi"; - names[2]="Heidi"; - names[3]=7.9; - dump(names); - names[4]={a:1}; -// arrayNew["string"](1); -``` - -* This example demonstrates the new functionality of ACF_2018, Lucee5.3. Here we define arrayNew with type:"string". -* If we give a string or number value for the array, it returns a string format. Otherwise, if we give a struct value, ``{a:1}``, into the array, it throws an error like ``Can't cast complex object type struct to string``. - -#### Example 5 : Literals #### - -```luceescript - -// literals.cfm - -sct.bol=true; -sct.str="String"; -sct.nbr=123.456; - dump(sct); - dump(sct.nbr+100); -if(sct.bol)dump("is true"); - dump(serializeJson(sct)); -``` - -* Here we define three literals: literal boolean, literal string, literal number. -* Execute this example. The dump ``sct`` returns with their data type with values. -* We dump the number with a mathematical operation ``sct.nbr+100`` on it, and it returns ``223.456``. It checks the boolean literal as boolean or not. It returns "is true" while the if condition satisfied. - -#### Example 6 : Converting #### - -```luceescript - -//converting.cfm - -// convert string to date - d=dateAdd("d",0,"12/1/2018"); - dump(d); -// convert date to number - n=d+1; - dump(n); -// convert number to date - d=dateAdd("d",0,n); - dump(d); - sb=createObject("java","java.lang.StringBuilder").init("Susi Sorglos"); - dump(sb); - dump(sb.substring("5")); - dump(sb.substring(JavaCast("int","5"))); -//sb=createObject("java","java.lang.StringBuilder").init("1"); - sb=createObject("java","java.lang.StringBuilder").init(javaCast("int","1")); - dump(sb); -``` - -* Internally every object has a type and Lucee automatically takes care of converting from one type to another if necessary. For example when you define a function with a string, but then pass a number into that function, Lucee automatically converts the number to a string. -* The above example is useful for converting "string to date", "date to number", "number to date" formats. -* We have loaded a Java library and string builder. We pass a string into a constructor and execute this. We see that the string builder contains that value. We refer to this ``string builder`` method in the Java Doc. The method is called ``substring``. This substring takes an int as its argument. For example, we pass a string value instead of an int value ``sb.substring("5")``. Lucee returns a substring properly. -* Two constructors are available for string builder. There are ``StringBuilder(int), StringBuilder(string)``. - -```luceescript - -//index.cfm - -directory sort="name" action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example*.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -```luceescript - -// test.cfc - -component { - function getName() { - return "Susi"; - } -} -``` - -These types are on top of the language. Lucee contains some other different types too. Therefore, it is always good to do type checking in your code. - -### Footnotes ### - -Here you can see above details in video - -[Types of Lucee](https://youtu.be/02kMrN4PByc) diff --git a/docs/04.guides/04.cookbooks/35.loop_through_files/page.md b/docs/04.guides/04.cookbooks/35.loop_through_files/page.md deleted file mode 100644 index 1c59621bd..000000000 --- a/docs/04.guides/04.cookbooks/35.loop_through_files/page.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Looping Through File -id: loop_through_files ---- -## Looping Through File ## - -This document explains how to handle big files in Lucee in a better way. The classic way that you are familiar with uses cffile tag, fileRead, and fileReadBinary functions to read the file into memory. This is a simple solution, but it consumes a lot of memory. - -Example: - -Handle files with cffile tag, fileRead, and fileReadBinary functions - -```luceescript -include "_getPath2BigFile.cfm"; -NL=""; -// read the complete file into memory -content=fileRead(path); -// no we split, again everything lands in memory as an array -arr=listToArray(content,NL); -// now we loop over every single line -loop array=arr index="i" item="line" { - handle(line); -} -function handle(line) {} -dump(label:"String Size",var:len(content)); -dump(label:"Array Size",var:len(arr)); -``` - -In the example above, - -* Read the file into the memory -* Split into array -* loop over the array - -It consumes lot of memory. - -### Use Loop - File ### - -Use cfloop file, It allows you to read a file line by line, so you do not have to load an entire file into memory. You only load a line at a time into the memory. - -```lucee - -``` - -Example Using Loop - -```luceesript -include "_getPath2BigFile.cfm"; -// now we loop over every single line -loop file=path item="line" { - handle(line); -} -function handle(line) {} -``` - -In the above example, loop through the file and get each line, so in memory there is only ever the one line. This not only faster, it also consumes less memory. - -### Footnotes ### - -Here you can see above details in video - -[Looping through Files](https://www.youtube.com/watch?v=6w2Wr8snk50) diff --git a/docs/04.guides/04.cookbooks/36.s3_sourceCode/page.md b/docs/04.guides/04.cookbooks/36.s3_sourceCode/page.md deleted file mode 100644 index 519f199ab..000000000 --- a/docs/04.guides/04.cookbooks/36.s3_sourceCode/page.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Using S3 directly for source code -categories: -- s3 -description: Using S3 directly for source code ---- - -## S3 for source code ## - -This document explains how to use S3 as for your source code and how to use S3 for your artifacts when we look at the source code itself. - -Example : - -```luceescript -// get an image directly from s3 -content file = "s3:///cfml1/lucee.png" type = "image/png" -"s3://##:#awsSecretKey#@/"; -``` - -//Application.cfc - -```luceescript -component{ - this.name = 'exampleS3'; - this.s3.accesskeyid = "JHKLJHGSGSGVSGVS"; - this.s3.awssecretkey = "Jgftiutry3uwiumcx4bvhjf9ksepu5wrwnvwbh9gj"; -} -``` - -1) In this example we directly call an S3 resource of the image using ``file="s3:///cfml1/lucee.png"`` and also define the mime type. Then we see the image while calling it in the browser. - -2) In this example, we define the credentials of the S3 in the Application.cfc. Here we give dummy data for the accesskey Id and secretkey. - -3) In this example, if you have an exception, it will display on the page exposing your credential information. So, we never use an error template that shows the exception. Best practice is to never use the credential with the password itself. Instead, always defined it in the application.cfc - -4) Another option is to map with the admin. - - - Virtual : /s3 - - Resource : s3://somethingLikeThis@/ - -But again, that would expose your credentials for everybody that sees an exception message. - -5) Instead, set the credentials in the environment variable or system properties (This is a new feature in S3 0.9.4.118). So, we can remove the resource in the mapping and just simply define ``Resource : s3:///cfml1/`` and save this mapping. - -6) Two important things in mapping. - - * When enabling the flag ``Web Accessible``, this exposes that mapping directly to the user. So you can call it at /s3 in the browser. - * When removing the flag ``Web Accessible``, you can only include that mapping. So, we always use cfinclude s3. - -7) If we select ``Never`` in 'Inspect Templates' this tells Lucee to pick up the file on first request from s3. It will compile the file to a local folder. Then it will only use that local compiled file and never check again if the file has changed. - -8) We go to ``localhost:8888/s3/cfml1/index.cfm`` in the browser. We get the source from S3 which comes directly from a stream, so we are catching that. It will not pick up any changes at all. For example, if we change that file a little bit and then update the file on s3, and then call it again in the browser, it does not pick up the latest changes. Because it is cached, what you now can do is flush the change with the help of the function ``PagePoolClear()``. This function will create a complete page pool. - -9) Lucee will pick up the file including the new changes when we call and execute again. Here you have cached and flushed the cache manually. If you add new files to the s3, you can automate that step. - -It might be very useful to schedule a task that checks every five minutes or so to see if there are changes in the files on S3, and flush everything is there are changes. - -### Footnotes ### - -Here you can also see these details in the video: - -[S3 for source code](https://youtu.be/twQomRCbaCY) diff --git a/docs/04.guides/04.cookbooks/36.thread_task/page.md b/docs/04.guides/04.cookbooks/36.thread_task/page.md deleted file mode 100644 index acaa8636c..000000000 --- a/docs/04.guides/04.cookbooks/36.thread_task/page.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Thread Task -id: thread_task -related: -- tag-thread -categories: -- thread -description: 'How to use Thread Tasks ' ---- - -## Thread Task ## - -This document explains about the thread tasks. It useful to know the differences between regular threads and task threads. - -When a regular thread throws an exception, the default exception type is ``type='daemon'``. After an exception, the thread is dumped. If a regular thread is terminated due to an error, the information from the thread will be output with a 'terminated' status. - -Regular Threads have the following characteristics: - -1) **Bound to current request** : With the help of CFThread you can always see what the thread is doing. With ``action='join'`` you can wait until the thread ends and join it. You can also call "action='terminate'" and end the thread. You always have control over the thread with the various actions. - -2) **Runs only once** : The thread runs only once. It ends at the end of the Cfthread tag or if there is an exception. - -3) **It fails when it fails** : There is no special exception handling so when the thread fails it fails unless you have Cftry, cfcatch inside the thread and you have exception handling there. - -### Example 1 : ### - -In addition to daemon (regular) threads, Lucee also supports task threads. The main differences is that task threads execute completely Independent of the request that is calling the thread. We log the thread and can re-execute it. - -This example shows a task thread. It is similar to the daemon thread, but we do not have the join and output of the thread because these are not allowed with a task thread. - -```luceescript -thread name="test" type="daemon" { - throw "hopala!"; -} -thread action="join" name="test"; -dump(cfthread.test); -``` - -Note that when you execute example code, you will get no output. This is expected since no output was written in the code. - -However, view the Lucee _Admin --> Services --> Tasks_ and see the name of the tasks and their ``Type`` is cfthread. It could be mail or other tasks. - -We see the ``Number of tries`` is 1 because we only ran it once. When we go to detailed view, we see the exception that was thrown by the task, the template where it was executes, and the state. (The state is closed in this case.) - -### Example 2 : ### - -This example shows how to create a retry interval. A retry interval is useful when a task fails and you want to try it again. For example if you are contacting an external service and it does not always respond. - -```luceescript -thread name="test" type="task" - retryinterval={ - tries:3, - interval:createTimeSpan(0,0,0,1) - } { - throw "hopala!"; -} -``` - -In this example: - -1) It retries 3 times every 1 second when it fails. - -2) It will retry 3 times at 1 second intervals every time it does not get an output. Go to _admin --> Services --> Tasks_, we see two tasks. The tasks are closed, but you can see that the new task was executed 4 times. - -3) If you view the details, you can see that the ``Number of tries`` is 4,``Remaining tries`` are 0, ``State`` is closed. If we execute the thread again, the ``Number of tries`` will be increased to 5. - -### Example 3 : ### - -```luceescript -thread name="test" type="task" - retryinterval=[ - {tries:3, interval:createTimeSpan(0,0,0,1)}, - {tries:5, interval:createTimeSpan(0,0,0,5)}, - {tries:10, interval:createTimeSpan(0,0,0,10)}, - {tries:10, interval:createTimeSpan(0,0,1,0)}, - {tries:20, interval:createTimeSpan(0,0,10,0)} - ] { - throw "hopala!"; -} -``` - -This example is similar to the previous one, but it more complex. Here We have an array of multiple retry intervals defined. - -1) This example has the following retry intervals: - tries:3, interval:createTimeSpan(0,0,0,1), this means try 3 times every one second - {tries:5, interval:createTimeSpan(0,0,0,5)}, this means try 5 times every 5 seconds - {tries:10, interval:createTimeSpan(0,0,0,10)}, this means try 10 times every 10 seconds - {tries:10, interval:createTimeSpan(0,0,1,0)}, this means try 10 times every 1 minute - {tries:20, interval:createTimeSpan(0,0,10,0) this means try 20 times every 10 minutes - -2) When we execute, we again get no output. However, we see the result and it is not 'read', because it is not done retrying. We have only tried 5 times. - -3) Refresh the page, we see now it has tried more times. (Go to admin _Admin --> Services --> Tasks_) - -**Task thread** : Different than daemon threads, task threads can run more than once if they fail. You can schedule a later retry, and you can control it in the administrator. - -Task threads are not bound to the requests starting the threads as demon threads are, but you still can control them with help of the component administrator. That component is available everywhere so we can use it in a test page. - -### Example 4 : ### - -```luceescript -/**/thread name="test" type="task" - retryinterval=[ - {tries:3, interval:createTimeSpan(0,0,0,1)}, - {tries:5, interval:createTimeSpan(0,0,0,5)}, - {tries:10, interval:createTimeSpan(0,0,0,10)}, - {tries:10, interval:createTimeSpan(0,0,1,0)}, - {tries:20, interval:createTimeSpan(0,0,10,0)} - ] { - throw "hopala!"; -} -// wait for it( title="", body=any, labels=any, skip=any, data={} ) - sleep(1000); -// get admin component - admin=new Administrator(type:"web",password:"server"); -// list all tasks - tasks=admin.getTasks(); - dump(tasks); -// reexecute - admin.executeTask(tasks.id); -// delete a single task - admin.removeTask(tasks.id[tasks.recordcount]); -//delete all tasks - admin.removeAllTask(); -``` - -This example for getting the admin component and task is physically created on the system. - -1) ``admin.getTasks()`` is used to list out the all existing tasks. When executed, it returns a query that contains the information from the task. - -2) ``admin.executeTask()`` is used to execute the task and we see it in the browser. It throws an exception. - -3) ``admin.removeTask()`` and "admin.removeAllTask()" is used to remove tasks from administrator. - -### Footnotes ### - -Here you can see the details in the video: -[Thread Task](https://youtu.be/-SUbVWqJRME) diff --git a/docs/04.guides/04.cookbooks/37.lazy_queries/page.md b/docs/04.guides/04.cookbooks/37.lazy_queries/page.md deleted file mode 100644 index f8e4124a2..000000000 --- a/docs/04.guides/04.cookbooks/37.lazy_queries/page.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Lazy Queries -id: lazy_queries -categories: -- query -description: 'How to use lazy queries ' ---- - -## Lazy Queries ## - -This document explains about lazy queries with some simple examples as follows: - -### Example 1 : ### - -**Regular query** : Regular query tags/functions load all data inside a two-dimensional structure to use. - -```luceescript - -//regularQuery.cfm - -query name="qry" returntype="query" { - echo("select * from lazyQuery"); -} -dump(numberFormat(qry.getColumnCount()*qry.getRowCount())); -loop query=qry { - dump(qry.val); - if(qry.currentrow==10) break; -} -``` - -1) In this example we have a simple task. All statements that return a result set with 200,000 records. We output the first ten. Then we make a break when we add ten rows. - -2) We execute this in the browser and we get the expected result. - -### Example 2 : ### - -**Lazy query** : Lazy queries keep a pointer to the database and only load the data on demand. If you loop through a query the data is loaded on the spot. It does not create a two-dimensional struct to store all the data hand. When the query tag is done, it keeps a pointer to the database. - -As a lazy query loops through, it loads the data on demand so you do not have to wait until it has loaded all the data. It is faster when you only load the first 10 rows as you don't have to wait it until it's done loading everything. - -```luceescript - -//lazyQuery.cfm - -query name="qry" returntype="query" lazy=true { - echo("select * from lazyQuery"); -} -loop query=qry { - dump(qry.val); - if(qry.currentrow==10) break; -} - -``` - -This example is similar as regular query, but we define ``lazy=true``. So that lucee knows to do a lazy query. - -I have removed the column count from the example. Record count is no longer possible, because it does not read all the data initially. It does not know how many records there are. When you loop you can count the records, so you know the total number of records at the end, but not at the start. - -There is not really a difference between a regular query and a lazy query, just some limitations (you cannot get the record count in the beginning, and you cannot use cache) within a lazy query. - -With a lazy query, we do not have to wait until lucee has loaded all the data into a two-dimensional structure, and it is also better for memory because you do not have to store all the older data in the memory until you are ready to use it. So there are some benefits. - -### Example 3 : ### - -A comparison of lazy queries and regular queries follows: - -```luceescript - -types=['regular':false,'lazy':true]; -results=structNew("ordered"); -loop struct=types index="type" item="lazy" { - loop from=1 to=10 index="i" { - start=getTickCount('nano'); - query name="qry" returntype="query" lazy=lazy { - echo("select * from lazyQuery"); - } - x=qry.val; - time=getTickCount('nano')-start; - - if(isNull(results[type]) || results[type]>time)results[type]=time; - } -} -// format results -results.regular=decimalFormat(results.regular/1000000)&"ms"; -results.lazy=decimalFormat(results.lazy/1000000)&"ms"; -dump(results); -``` - -This example compares lazy queries with regular queries. It has a loop that loops two times: once for a regular query and a second one for a lazy query. The ``type`` is used here with ``lazy=lazy``, So it sets true or false and does that ten times, once for every time the loops execute. It stores the execution time but you only get the fastest execution time of the ten tries. - -Execute that example in the browser. The regular query takes 41 milliseconds and the lazy query takes 27 milliseconds. So we see the benefits of the lazy queries. - -### Footnotes ### - -You can see the details in this video: -[Lazy Query](https://youtu.be/X8_TB1py8n0) diff --git a/docs/04.guides/04.cookbooks/38.supercharge_website/page.md b/docs/04.guides/04.cookbooks/38.supercharge_website/page.md deleted file mode 100644 index a3f16168e..000000000 --- a/docs/04.guides/04.cookbooks/38.supercharge_website/page.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Supercharge your website -id: supercharge-your-website ---- - -## Supercharge your website ## - -This document explains how you can improve the performance of your website in a very short time with Lucee. - -### Example: ### - -```luceescript - -// index.cfm -writeDump(now()); - -``` - -Run the above index.cfm, and you get a timestamp. Whenever we call our file, Lucee checks once at every request if a file has changed or not (for files currently residing in the template cache). If a files has changed, Lucee recompiles it, and executes it. Checking the files at every request takes time. If you have a published server, and you know your server does not produce or change any files, you can simply avoid that check that happens all the time. - -### Using Admin ### - -* Go to _Admin -> Performance/ Caching -> Inspect Templates (CFM/CFC) -> Never_ - -* The default is "Once", checking any requested files one time within each request. You should check "Never" to avoid the checking at every request. - -* Change the index.cfm and run it again. No changes happen in the output because Lucee does not check if the file changed or not. Now, let's see the faster execution and less performance memory being used. - -* You can clear the cache by code using `pagePoolClear()`. This clears all template cache so that Lucee will check again if the template has changed. On the next request Lucee will check initially for the file. - -* Another option to clear the template cache is to use clear cache via the admin by clicking the button in _Admin -> Settings -> Performance/ Caching -> Page Pool Cache_. - -### Footnotes ### - -Here you can see this details on video also - -[Charge Your website](https://youtu.be/w-eeigEkmn0) diff --git a/docs/04.guides/04.cookbooks/39.Retry/page.md b/docs/04.guides/04.cookbooks/39.Retry/page.md deleted file mode 100644 index e935d5fb4..000000000 --- a/docs/04.guides/04.cookbooks/39.Retry/page.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Retry -id: retry -related: -- tag-catch -- tag-retry -- tag-try ---- - -## Retry ## - -This document explains how to use retry functionality with some simple examples. - -### Example 1 : ### - -```luceescript -// example1.cfm - -path="test.txt"; -function fr(){ - dump(fileRead(path)); -} -try { - fr(); -} -catch(e) { - if(!fileExists(path)) { - fileWrite(path,"content of the file"); - fr(); - } - else echo(e); -} -if(fileExists(path)) fileDelete(path); - -``` - -In this example have the "try" and "catch" blocks for reading a file and outputting the file content. Maybe that file does not exist in every case. So we have to checked in advanced if the file exists or not. In this example, the file read is a function ``fr()``, and we will call this function in the "try" block. If the file does not exist, the "catch" block is executed and the ``fr()`` function is called again. - -This is not a best way. 'Retry' is a better option. The retry code looks like example2.cfm - -### Example 2 : ### - -```luceescript -// example2.cfm - -path="test.txt"; -try { - dump(fileRead(path)); -} -catch(e) { - if(!fileExists(path)) { - fileWrite(path,"content of the file"); - retry; - } - echo(e); -} -if(fileExists(path)) fileDelete(path); - -``` - -In this example we use the retry functionality. Here we also still check if the file exist or not. If the file does not exist, we create a new file by using ``fileWrite``. Then call retry to avoid duplicate code ``fr()``. Retry points to the beginning of the try block and then it will read again the file and output the file content. - -We do not get an exception because if the file does not exist, we call retry (read the file again and output the file content). For this case we simply use retry, and if it fails we correct what is wrong. - -### Footnotes ### - -Here you can see this details on video also - -[Retry](https://youtu.be/zA9aAAimkk8) diff --git a/docs/04.guides/04.cookbooks/40.System_output/page.md b/docs/04.guides/04.cookbooks/40.System_output/page.md deleted file mode 100644 index 3acb491a8..000000000 --- a/docs/04.guides/04.cookbooks/40.System_output/page.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Function SystemOutput -id: systemoutput_function ---- -## Function Systemoutput ## - -This document explains the systemoutput function with some simple examples. - -#### Example 1 : #### - -```luceescript -// index.cfm - -directory action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example*.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -```luceescript - -// example1.cfm - -dump(cgi); // or writedump if you love to write more -echo(now()); // or writeoutput if you love to write more - -``` - -This example has a simple dump with CGI. It displays normally in the browser while we are running example1.cfm - -#### Example 2 : #### - -```luceescript - -// example2.cfm - -systemOutput(now(),true); // with new line - -``` - -systemOutput() creates output content in web the browser (console). Here the systemoutput has two arguments: first argument _now()_ for current date time and second argument _true_ for new line. Run this in the browser and see the content in the console. - -#### Example 3 : #### - -```luceescript -// example3.cfm - -systemOutput(now(),true,true); // send to error stream -``` - -This example uses three arguments: first argument ``now()`` for current date time, second argument ``true`` for new line, and third argument for stream). The stream argument indicates which stream the output should go. There are two streams to choose from: "Output stream" and "Error stream". A value of true in the third argument indicates the output should go to the error stream. Run this in the browser and see the contents with output stream in console. - -#### Example 4 : #### - -```luceescript -// example4.cfm - -systemOutput(cgi,true); // complex object -``` - -In addition to simple strings or simple values, you can also pass complex objects to the SystemOutput() function. In this example we pass CGI as the argument. When you run this in the browser, you get a serialized output in the console. - -#### Example 5 : #### - -```luceescript -// example5.cfm - -systemOutput("Here we are:",true); // complex object -``` - -SystemOutput() has another good feature too, There is ```` used to show helpful information (where it is, which template, on which line number) while we mouse over the dump content. Lucee will detect and show the stack-trace if we add ```` to the SystemOutput() function in our code. When we run this in the browser, we see the stack-trace in the console. - -### Footnotes ### - -Here you can see this details on video also - -[Function SystemOutput](https://www.youtube.com/watch?v=X_BQPFPD320) diff --git a/docs/04.guides/04.cookbooks/41.Encrypt_Decrypt/page.md b/docs/04.guides/04.cookbooks/41.Encrypt_Decrypt/page.md deleted file mode 100644 index 612095279..000000000 --- a/docs/04.guides/04.cookbooks/41.Encrypt_Decrypt/page.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Encryption/Decryption with RSA public and private keys -id: encryption_decryption -related: -- function-decrypt -- function-encrypt -- function-generatersakeys -categories: -- crypto -description: This document explains about Encryption/Decryption with public and private keys with simple examples. -menuTitle: 'Public and Private keys ' ---- - -## Encryption/Decryption ## - -This document explains about Encryption/Decryption with public and private keys with simple examples. - -Encryption/Decryption is a new functionality in Lucee 5.3. We have new way to encrypt/decrypt string values. First we start with keys. In this case, there are two keys: - -* Private key to encrypt -* Public key to decrypt - -#### Example 1 : #### - -```luceescript -//index.cfm -directory action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example*.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -```luceescript -key=generateRSAKeys(); -dump(key) -``` - -This function generates RSA keys. Execute the example code above in the browser and a struct is returned containing the two keys: a private key and a public key. So, we can create these keys, and store them somewhere for later use. - -#### Example 2 : #### - -```luceescript -key=generateRSAKeys(); -raw="Hi, Hello !!!"; -enc=encrypt(raw,key.private,"rsa"); -dump(enc); -``` - -We now create RSA keys using the [[function-generatersakeys]] function, and then use the key to encrypt using the [[function-encrypt]] function. The encrypt() function has some arguments. It has ``key.private`` which defines the key as the private key, and ``rsa`` indicates use of the RSA encryption algorithm. Then run the dump in the browser and we see the encrypted string for your input string. - -#### Example 3 : #### - -```luceescript -key=generateRSAKeys(); -raw="Hi, Hello !!!"; -enc=encrypt(raw,key.private,"rsa"); -dec=decrypt(enc,key.public,"rsa"); -dump(dec); -``` - -This is full detailed example of encrypt/decrypt functions. We create a key and we encrypt with the private key. Then we [[function-decrypt]] with the public key. Then run the dump in the browser and we see the original string returned as expected. - -### Footnotes ### - -Here you can see this details on video also - -[Encryption/Decryption with public and private keys](https://www.youtube.com/watch?v=2fgfq-3nWfk) diff --git a/docs/04.guides/04.cookbooks/42.Query_returntype/page.md b/docs/04.guides/04.cookbooks/42.Query_returntype/page.md deleted file mode 100644 index 9e946349a..000000000 --- a/docs/04.guides/04.cookbooks/42.Query_returntype/page.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Query return type -id: query_return_type -categories: -- query -description: This document explains the different return types for a query with some examples. ---- - -## Query return type ## - -This document explains the different return types for a query with some examples. - -### Example 1: query ### - -First we start with the regular return type for a query. This query simply returns a result set. - -```luceescript -// index.cfm -directory sort="name" action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example*.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -```luceescript -query name="qry" datasource="test" { - echo(" - select lastname,firstname from person - "); -} -dump(qry); -``` - -In this example we have a select statement with two columns in the ``person`` table. Execute the query in the browser and we get a simple result. - -### Example 2: Array ### - -Lucee can define the return type in a query tag. If we set array as follows: ``returntype="array"``. We will get the result as an array. - -```luceescript -query name="arr" datasource="test" returntype="array" { - echo(" - select lastname,firstname from person - "); -} -dump(arr); -``` - -In this array, for each row there is an item in the array and it has a struct with all the columns. So this array is special because it returns an array of struct, and it has meta information about the SQL statement. So it shows the record count and execution time of the query. - -### Example 3: struct ### - -This example shows the same concepts that were shown in the previous Example2, however instead of an array, we can do a struct. If you want to have a struct result, set the return type as struct. - -```luceescript -query name="sct" datasource="test" returntype="struct" columnKey="lastname" { - echo(" - select lastname,firstname from person - "); -} -dump(sct); -``` - -1) In this case you have to define which column is the key of the struct. Here I simply use the last name as the key of struct. - -2) Execute it in the browser, and we get struct as a result and the key is the last name. So you can directly choose one of these elements by writing the lastname. - -### Example 4: ### - -```luceescript -if(isNull(application.sex)) { - query name="application.sex" datasource="test" returntype="struct" columnKey="sex_id" { - echo(" - select sex_id,name from sex - "); - } -} -query name="qryPerson" datasource="test" { - echo(" - select sex_id,lastname,firstname from person - "); -} -loop query=qryPerson { - dump(qryPerson.lastname&" "&qryPerson.firstname&" ("&application.sex[qryPerson.sex_id].name&")"); -} -``` - -1) In this example we have two tables. We make a query to the ``person`` table. Notice that some fields are foreign key references too. We store ``sex_id`` in application scope because we use this on the second query. In this sex_id is the key of that struct, So we simply can address in ``("&application.sex[qryPerson.sex_id].name&")")`` this way. - -2) Execute this example in the browser and we get a result from the other table that is reference by a foreign key. - -### Footnotes ### - -You can see these details in the video here: - -[Query return type](https://www.youtube.com/watch?v=b9YHhnAuNiw) diff --git a/docs/04.guides/04.cookbooks/43.QOQ_Sucks/page.md b/docs/04.guides/04.cookbooks/43.QOQ_Sucks/page.md deleted file mode 100644 index da5d8d165..000000000 --- a/docs/04.guides/04.cookbooks/43.QOQ_Sucks/page.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: Query of Queries sometimes it rocks, sometimes it sucks -id: QOQ_Sucks -related: -- tag-query -- function-queryexecute -- function-queryfilter -categories: -- query ---- - -## The good, the bad and the ugly ## - -This document explains why Query of Queries (QoQ) may or not be best approach for your use case. - -- **PRO** it's nice to work with in memory datasets/queries using SQL. -- **CON** is can be very slow, depending on the use case. - -Update, the performance of QoQ has been dramatically for single tables improved since 5.3.8! - -[Improving Lucee's Query of Query Support](http://wwvv.codersrevolution.com/blog/improving-lucees-query-of-query-support) - -There has also been a lot of work done, to improve the "correctness" of the native SQL engine's behaviour - -[QoQ tickets](https://luceeserver.atlassian.net/issues/?jql=text%20~%20%22qoq%22%20ORDER%20BY%20updated) - -Currently, Lucee QoQ only supports `SELECT` statements, `UPDATE` and `INSERT` aren't yet supported. - -Lucee has two QoQ engines, a fast native engine which only works on a single table. - -Any SQL using a multiple tables, i.e. with a JOIN, will fallback to the HSQLDB engine. - -The HSQLDB engine requires loading all the queries into temporary tables and is currently java synchronized, all of which can affect performance. - -If the native QoQ engine fails on a single table query, by default, Lucee will attempt to fallback on the HSQLDB engine - - See `LUCEE_QOQ_HSQLDB_DISABLE` and `LUCEE_QOQ_HSQLDB_DEBUG`, under [[running-lucee-system-properties]] - -### Example : ### - -```lucee+trycf - - q = QueryNew("name, description"); - loop times=3 { - getFunctionList().each(function(f){ - var fd = getFunctionData(arguments.f); - var r =QueryAddRow(q); - QuerySetCell(q,"name", fd.name, r); - QuerySetCell(q,"description", fd.description, r); - }); - } - dump(server.lucee.version); - dump(var=q.recordcount, - label="demo data set size"); - s = "the"; - - - - - select name, description - from q - where description like - - - - - - - q2 = q.filter(function(row){ - return (arguments.row.description contains s); // works even better with variables.s in lucee 5.3.3 - }); - - - - - - - - q3 = q.filter(function(row){ - return (row.description contains s); - }); - - - -``` - -In this example have a QOQ with persons table. - -```luceescript -// index.cfm - -directory sort="name" action="list" directory=getDirectoryFromPath(getCurrentTemplatePath()) filter="example.cfm" name="dir"; -loop query=dir { - echo('#dir.name#
'); -} -``` - -```luceescript -// example.cfm - -max=1000; -persons=query( - "lastname":["Lebowski","Lebowski","Lebowski","Sobchak"], - "firstname":["Jeffrey","Bunny","Maude","Walter"] - ); - -// Query of Query -start=getTickCount("micro"); -loop times=max { - query dbtype="query" name="qoq" {echo(" - select * from persons - where lastname='Lebowski' - and firstname='Bunny' - order by lastname - ");} -} -dump("Query of Query Execution Time:"&(getTickCount("micro")-start)); - -// Query Filter/Sort -start=getTickCount("micro"); -loop times=max { - qf=queryFilter(persons,function (row,cr,qry) {return row.firstname=='Bunny' && row.lastname=='Lebowski';}); - qs=querySort(qf,"lastname"); -} -dump("Query Filter/Sort Execution Time:"&(getTickCount("micro")-start)); - -``` - -In this example have two different methods of queries. - -1) First one is QOQ. Here ``QoQ`` from the ``persons`` table. It is executed a thousand times due to the looping required by QoQ. - -2) The second one is calling the function query filter. Query filter filters out the same row the same way the QOQ does. - -3) Execute it in the browser and we get two results(Query of query execution time and Query filter/sort execution time). Query filter executes twice as fast, at least, as query of query. Because QOQ loops over and over again, it is slower. If you can avoid QOQ and use the Query filter/sort, your code will execute much faster. - -### Footnotes ### - -You can see these details in the video here: - -[Query of Query Sucks](https://www.youtube.com/watch?v=bUBXzo1WbSM) diff --git a/docs/04.guides/04.cookbooks/52.Flyingsaucer/page.md b/docs/04.guides/04.cookbooks/52.Flyingsaucer/page.md deleted file mode 100755 index c60a02810..000000000 --- a/docs/04.guides/04.cookbooks/52.Flyingsaucer/page.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: Flying Saucer PDF Engine - CFDOCUMENT -id: flying_saucer -related: -- tag-document -categories: -- pdf -description: The new CFDOCUMENT PDF engine, Flying Saucer in Lucee 5.3 -menuTitle: The new PDF engine, Flying Saucer in Lucee 5.3 ---- - -This document provides information about the new PDF engine, [Flying Saucer](https://github.com/flyingsaucerproject/flyingsaucer) (FS) in Lucee 5.3 - -Flying saucer is a new PDF engine in Lucee. PDF engines are mainly used to convert HTML to PDF format. - -### Benefits of moving to Flying Saucer from the old engine (PD4ML) ### - -* Full support for CSS 2.1 -* On average the generated PDFs are smaller -* Consume less Memory and CPU -* Engine in active development, -* Better Results - -### Downsides to Flying Saucer compared to the old engine (PD4ML) ### - -* The generated PDF does not always look exactly the same when generated with the new FC compared to files generated with the PD4ML. - -If it's important that the PDF output remains exactly the same as the old PD4ML-generated file, you will need to check it manually. - -If you don't have time to check all PDF outputs, or you really don't care about the fancy new engine, simply add the following code to use the old PDF engine. - -via Application.cfc, - -```luceescript -this.pdf.type = "classic"; -``` - -or if you are using an Application.cfm, - -```lucee - -``` - -and since the PDF Extension 1.0.0.92-SNAPSHOT you can specify the engine using type - -```lucee - - or - -``` - -### Features of Flying Saucer ### - -You can define a font directory where you have the fonts(.ttf,.otf) you are using in your PDF. - -### Define the font directory #### - -```lucee - -``` - -Define the font directory Application itself: - -via Application.cfc - -```luceescript -this.pdf.fontDirectory = "path/to/my/font"; -``` - -or via application.cfm - -```lucee - -``` - -If the font directory isn't specified, Lucee will look for fonts in /WEB_INF/lucee/fonts and uses them if they match. - -**Note**: Classic engine works using the font-family-name from pd4fonts.properties file. Modern (Flying saucer) engine works using the font-family-name from the .ttf file with the same case. - -#### Simplify Attributes #### - -Attributes with cfdocument are a mess. You can make it clearer using the following syntax: - -Example: - -```lucee - -``` - -In Lucee you can do the following: - -```lucee - -``` - -Or even simpler - -```lucee - -``` - -#### Additional Units #### - -In addition to "inch" and "cm", the attribute unit now supports "pixel" and "points". - -```lucee - -``` - -If you find any issues while using the new PDF engine, please ask a question on the [mailing list](https://dev.lucee.org/) - -### Footnotes ### - -You can see the details in this video: -[Flying saucer](https://www.youtube.com/watch?v=B3Yfa8SUKKg) diff --git a/docs/04.guides/04.cookbooks/54.xmlFast&Easy/page.md b/docs/04.guides/04.cookbooks/54.xmlFast&Easy/page.md deleted file mode 100644 index 914fd17f0..000000000 --- a/docs/04.guides/04.cookbooks/54.xmlFast&Easy/page.md +++ /dev/null @@ -1,514 +0,0 @@ ---- -title: XML Fast And Easy, using SAX - Listener Functions -id: xml_fast-easy -related: -- function-xmlparse -categories: -- XML ---- - -This document explains how to use XML parsing in lucee. - -I have XML as shown below: - -```luceescript -//catlog.xml - - - - Empire Burlesque - Bob Dylan - USA - Columbia - 10.90 - 1985 - - - Hide your heart - Bonnie Tyler - UK - CBS Records - 9.90 - 1988 - - - Greatest Hits - Dolly Parton - USA - RCA - 9.90 - 1982 - - - Still got the blues - Gary Moore - UK - Virgin records - 10.20 - 1990 - - - Eros - Eros Ramazzotti - EU - BMG - 9.90 - 1997 - - - One night only - Bee Gees - UK - Polydor - 10.90 - 1998 - - - Sylvias Mother - Dr.Hook - UK - CBS - 8.10 - 1973 - - - Maggie May - Rod Stewart - UK - Pickwick - 8.50 - 1990 - - - Romanza - Andrea Bocelli - EU - Polydor - 10.80 - 1996 - - - When a man loves a woman - Percy Sledge - USA - Atlantic - 8.70 - 1987 - - - Black angel - Savage Rose - EU - Mega - 10.90 - 1995 - - - 1999 Grammy Nominees - Many - USA - Grammy - 10.20 - 1999 - - - For the good times - Kenny Rogers - UK - Mucik Master - 8.70 - 1995 - - - Big Willie style - Will Smith - USA - Columbia - 9.90 - 1997 - - - Tupelo Honey - Van Morrison - UK - Polydor - 8.20 - 1971 - - - Soulsville - Jorn Hoel - Norway - WEA - 7.90 - 1996 - - - The very best of - Cat Stevens - UK - Island - 8.90 - 1990 - - - Stop - Sam Brown - UK - A and M - 8.90 - 1988 - - - Bridge of Spies - T`Pau - UK - Siren - 7.90 - 1987 - - - Private Dancer - Tina Turner - UK - Capitol - 8.90 - 1983 - - - Midt om natten - Kim Larsen - EU - Medley - 7.80 - 1983 - - - Pavarotti Gala Concert - Luciano Pavarotti - UK - DECCA - 9.90 - 1991 - - - The dock of the bay - Otis Redding - USA - Atlantic - 7.90 - 1987 - - - Picture book - Simply Red - EU - Elektra - 7.20 - 1985 - - - Red - The Communards - UK - London - 7.80 - 1987 - - - Unchain my heart - Joe Cocker - USA - EMI - 8.20 - 1987 - - -``` - -Normally we use DOM(Document Object Model): - -```luceescript - - file=GetDirectoryFromPath(GetCurrentTemplatePath())&'catalog.xml'; - - dom=XMLParse(file); - dump(dom); - - // ... extract data needed - -``` - -DOM parses the XML to extract the data. - -Disadvantages of the DOM model: - -Creates an object tree based on complete XML. - -* Slow - loads the complete XML in a very complex structure -* Memory Intensive - loads the complete XML in a very complex structure -* Complicated to use - -There is a jDOM that is more optimized for Java, and because of that, faster and easier to use. But sadly that project is not maintained any more!! - -### SAX - Simple API for XML ### - -In Java there is another way to handle the XML called SAX. SAX is an event driver parser. It does not produce the object, but instead you are part of the parsing process. - -#### Advantages #### - -* Fast -* Memory Efficient (only creates persistent objects in memory) - -### Disadvantage ### - -Complicated to use. - -### SAX - Listener Functions ### - -You can use SAX on Lucee to define component and listener functions to listen for certain events. The listener functions are as follows: - -- startDocument(), is called when it starts to parse the document -- startElement(string name, string attributes)- is called every time it goes into a new tag. This function provides the name of the tag and all attributes. -- body(string content), - is called every time it goes into new tag. This functions provides the content of the body. -- endElement(string name, struct attributes) - is called when you have reached the end of the element. -- endDocument() - is called when you have reached the end of the document. -- error(struct cfcatch) - is called while executing the parser. - -Example with SAX: - -```luceescript - - file=GetDirectoryFromPath(GetCurrentTemplatePath())&'catalog.xml'; - - catalog=new XMLcatalog(file); - dump(catalog.execute()); - - -``` - -XMLcatalog is component, - -```luceescript -//XMLcatalog.cfc - component { - - /** - * Start parsing an XML file. - * @param xmlFile XML file to parse - */ - function init(string xmlFile) { - variables.xmlFile=arguments.xmlFile; - } - - function execute() { - variables.cds=[]; - variables.cd={}; - variables.insideCD=false; - variables.currentName=""; - - - var xmlEventParser=createObject("java","lucee.runtime.helpers.XMLEventParser"); - xmlEventParser.init( - getPageContext(), - this.startDocument, - this.startElement, - this.body, - this.endElement, - this.endDocument, - this.error - ); - xmlEventParser.start(xmlFile); - return variables.cds; - } - - /** - * This function will be called on to start parsing an XML Element (Tag). - */ - public void function startElement(string uri, string localName, string qName, struct attributes) { - if(qName == "cd") { - variables.cd={}; - variables.insideCD=true; - } - else if(variables.insideCD) { - variables.currentName=qName; - } - } - - /** - * call with body of content - */ - public void function body(string content) { - if(len(variables.currentName)) { - //if(len(variables.currentName) && variables.currentName!="price") { - variables.cd[variables.currentName]=content; - } - } - - /** - * This function will be called at the end of parsing an XML Element (Tag). - */ - public void function endElement(string uri, string localName, string qName, struct attributes) { - if(qName == "cd") { - arrayAppend(variables.cds,variables.cd); - variables.insideCD=false; - } - variables.currentName=""; - } - - /** - * This function will be called at the start of parsing a document. - */ - public void function startDocument() {} - - /** - * This function will be called at the end of parsing a document. - */ - public void function endDocument() {} - - /** - * This function will be called when a error occurs. - */ - public void function error(struct cfcatch) { - echo(cfcatch); - } -``` - -In the XML catalog you can see the listener functions and the listener function passed to the Java object. This helps to parse the data. - -```luceescript -var xmlEventParser=createObject("java","lucee.runtime.helpers.XMLEventParser"); - xmlEventParser.init( - getPageContext(), - this.startDocument, - this.startElement, - this.body, - this.endElement, - this.endDocument, - this.error - ); -xmlEventParser.start(xmlFile); -``` - -If we pass an XML string to execute the function, it automatically parses the XML data and returns an array format of parsed data. - -You can use the filter on SAX: - -Component with filter - -```luceescript -//XMLcatalog.cfc -component { - - /** - * Start parsing an XML file. - * @param xmlFile XML file to parse - */ - function init(string xmlFile) { - variables.xmlFile=arguments.xmlFile; - } - - function execute(struct filter) { - variables.cds=[]; - variables.cd={}; - variables.insideCD=false; - variables.currentName=""; - variables.removeCD=false; - - - var xmlEventParser=createObject("java","lucee.runtime.helpers.XMLEventParser"); - variables.filter=filter; - xmlEventParser.init( - getPageContext(), - this.startDocument, - this.startElement, - this.body, - this.endElement, - this.endDocument, - this.error - ); - xmlEventParser.start(xmlFile); - return variables.cds; - } - - /** - * This function will be called at the start of parsing an XML Element (Tag). - */ - public void function startElement(string uri, string localName, string qName, struct attributes) { - if(qName == "cd") { - variables.cd={}; - variables.insideCD=true; - variables.removeCD=false; - } - else if(variables.insideCD) { - variables.currentName=qName; - } - } - - /** - * call with body of content - */ - public void function body(string content) { - if(len(variables.currentName)) { - variables.cd[variables.currentName]=content; - if(structKeyExists(variables.filter,variables.currentName) && content != variables.filter[variables.currentName]) { - variables.removeCD=true; - } - } - } - - /** - * This function will be called at the end of parsing an XML Element (Tag). - */ - public void function endElement(string uri, string localName, string qName, struct attributes) { - if(qName == "cd") { - if(!variables.removeCD) { - arrayAppend(variables.cds,variables.cd); - } - variables.insideCD=false; - } - variables.currentName=""; - } - - /** - * This function will be called at the start of parsing a document. - */ - public void function startDocument() {} - - /** - * This function will be called at the end of parsing a document. - */ - public void function endDocument() {} - - /** - * This function will be called when an error occurs. - */ - public void function error(struct cfcatch) { - echo(cfcatch); - } - -} - -``` - -You can pass the filter struct when you execute the function. - -Example: - -```luceescript - - file=GetDirectoryFromPath(GetCurrentTemplatePath())&'catalog.xml'; - catalog=new XMLCatalog2(file); - - dump(catalog.execute({year:"1995"})); - -``` - -The example above executes and returns a result array which contains only the year equal to 1995. - -You can modify the component as you like. Instead of storing the array, you can store the result in a database or mail, or whatever you like. - -### Footnotes ### - -You can see the details in this video: -[Xml-Fast and Easy](https://www.youtube.com/watch?v=_AP6GpVk7TE) diff --git a/docs/04.guides/04.cookbooks/56.query_listeners/page.md b/docs/04.guides/04.cookbooks/56.query_listeners/page.md deleted file mode 100644 index f3b807f01..000000000 --- a/docs/04.guides/04.cookbooks/56.query_listeners/page.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Query Listeners -id: cookbook-query-listeners -related: -- tag-application -- tag-query -- function-queryexecute -categories: -- application -- query -description: A query listener is a hook which can be configured to run before and after a query is executed. ---- - -# Query Listeners in Lucee - -A Query Listener is a hook which can be configured to run before and after a query is executed. - -This is available as an experimental feature in Lucee 5.3 and is officially supported in Lucee 6.0. - -This allows you to change the query arguments, including the SQL before it executes and then also modify the result before it's returned. - -**Remember, when working with the `after()` method, that a query can return a struct or array, not just a query object** - -They can be configured: - -- application wide, via [[tag-application]] i.e. `Application.cfc` -- per [[tag-query]] or [[function-queryexecute]] - -A Query Listener is a component with two methods, `before()` and `after()`. You can have other methods in your listener component, but Lucee will only call these two. - -The Query Listener can be a struct(that has a key before/after with closure as value)/ closure (that calls after the query execution is completed) - -```luceescript -this.query.listener = { - before = function (caller,args) { - systemOutput(arguments,1,1); - dump(arguments); - return args; - } - ,after = function () { - systemOutput(arguments,1,1); - dump(arguments); - } -}; - -OR - -this.query.listener = function () { - systemOutput(arguments, 1, 1); - dump(arguments); -}; -``` - -## Examples - -i.e. `QueryListener.cfc` - -```luceescript - -component { - - function before( caller, args ) { - dump( var=#arguments#, label="queryListener.before()" ); - args.sql &= " where TABLE_NAME like 'SCH%'"; // modify the sql statement before it executes - // args.maxrows=2; - return arguments; - } - - function after( caller, args, result, meta ) { - // remember, result maybe a query, array or struct, check the args! - dump( var=#arguments#, label="queryListener.after()" ); - // var row=queryAddRow(result); - // result.setCell("abc","123",row); - return arguments; - } -} - -``` - -To add an Application wide query listener, add the following to your `Application.cfc` - -```luceescript -this.query.listener = new QueryListener(); -``` - -To add a query listener to an individual [[tag-query]] - -```luceescript - - - SELECT COLUMN_NAME, TABLE_NAME F - FROM INFORMATION_SCHEMA.COLUMNS - -``` - -Or an individual [[function-queryexecute]] - -```luceescript - - qry = queryExecute( - sql="SELECT COLUMN_NAME, TABLE_NAME - FROM INFORMATION_SCHEMA.COLUMNS", - options={ - datasource : "local_mysql", - listener=new QueryListener() - } - ); - -```` - -### Dump of arguments to the query Listener before() method - -Query Listener Before() - -### Dump of arguments to the query Listener after() method (cfquery) - -Query Listener After() - -### Dump of arguments to the query Listener after() method (queryExecute) - -Query Listener After() - -### Sample query result - -Query Listener Result diff --git a/docs/04.guides/06.extensions/02.extension-websocket/page.md b/docs/04.guides/06.extensions/02.extension-websocket/page.md deleted file mode 100644 index ee2c213a7..000000000 --- a/docs/04.guides/06.extensions/02.extension-websocket/page.md +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Websocket gateway -id: extensions-websocket-gateway -categories: -- ajax -- gateways -- extensions -- protocols ---- - -### WebSockets Gateway Extension ### - -This extension enables you to launch a server that is capable to manage messaging from HTML WebSockets. The server runs on a dedicated port. Lucee will receive notifications when a connection is opened, closed and any time a message is sent invoking a cfc listener class. - -The gateway can also being invoked via SendGatewayMessage so to allow your app to push message to all the connected clients. - - - -[Extension Wiki](https://github.com/isapir/lucee-websocket/wiki) - - - - - -### Installing the Extension ### - -You can install the extension by adding the provider to your Providers section in the Lucee Web administration panel (not the Server administration panel). Then select the Websocket Gateway Extension app and simply click on the Install button. - -### Create the gateway instance ### - -Go into the Event Gateway section of your Lucee admin panel. Create a new gateway instance of type WebSocket. Choose a name that makes sense and is unique into your Lucee context. Click - -### Configure the gateway ### - -You can configure many aspect of your gateway. - -* **Port** : select the port you want the server will listen for your incoming messages. Default is port 10125. Please remember that the server will listen incoming messages using the ws protocol. For example : ws://localhost:10125 -* **Startup Mode** : Automatic will make the gateway start when Lucee server starts up automatically. Choose what selection better fits your need. -* **CFC Listener** : this is the cfc invoked by the websocket server and provides the hooks that you can use to manage the connections and the messages that arrive on the server. This can be any CFC. It must expose the functions defined in the configuration. A dummy example is provided with the extension in the location specified in the CFC listener field. - -When you are done click submit. - -### Usage ### - -Start and stop the gateway is easier as per any other gateway in Lucee. Access the Gateway section in the lucee admin and you will a set to start/stop, restart, edit and delete the gateway instances. Please note that stopping the gateway will also stop the websocket server and will destroy any actual connection. - -### Interact using the gateway listener ### - -You can use the interception provided by the gateway listener to change the default behaviour of the websocket gateway. The dummy listener that the extension ships looks like this: - -```lucee -component{ - - public void function onClientOpen(Struct data){ - } - - public void function onClientClose(Struct data){ - } - - public void function onMessage(Struct data){ - } -} -``` - -Any time a new connection is opened, closed and when a message is sent, the websocket server invokes the listener before sending out any message. The data map passed to the listener contains the following : - -* **conn** : the connection reference that created the message. -* **message** : the message that the connection carries. This is normally empty when a connection is Opened and Closed - -More in details: - -* **onClientOpen / onClientClose ** : these 2 events are fired by the client when a new connection is opened or an existing one is terminated. On these events the websocket server does not actually sends out any message but allows you to store the connections and using them later. For example : - -```lucee -public void function onClientOpen(Struct data){ - arrayAppend(variables.connections,data.conn); -} -``` - -Is important that you implement onClientClose removing the connection from your personal store. This is important if you want to force the server to send messages only to selected group of connections. - -* onMessage : this is the hook that allows to you to manage the message to be sent and the set of connection to be notified. - -Customizing the message is very easy. Just modify the data.message field and that will be the message pushed to the connections. - -```lucee -public void function onMessage(Struct data){ - data.message = data.message & " This is added to the message to be sent to any opened connection"; -} -``` - -If you want to force the server to notify only a set of connections you can add to the data map the attribute connections containing an array of actual opened connections. If a connection exists and is an array containing valid connections only these will be notified and will receive the message. - -```lucee -public void function onMessage(Struct data){ - data.connections = ['Array of connections that you have stored using the onClientOpen, onClientClose listener methods.']; -} -``` - -### sendGatewayMessage ### - -The gateway is running into your applications and can be invoked as any other gateway by id using the SendGatewayFunction: - -```lucee -sendGatewayMessage(String id,Struct data); -``` - -This is a great way for performing data push operations. The server will ping ANY REGISTERED CONNECTION and invokes the onMessage listener ( you can restrict the connection to be called at this level adding a data.connections array to the struct). - -** IMPORTANT ** : store the message as data.message in the struct you pass to the sendGatewayMessage function. - -### Logging ### - -The gateway creates a log file called WebSocket.log under your lucee context log folder. Any important event ( and error ) is logged in this file. This file is unique for all the gateways you start from a same Lucee context. - -### Client ### - -At the time of this script not all the browsers support WebSockets out of the box. - -Use this test page to find out if your browser supports it. - - - -If your browser supports websockets implementing a client is very easy: - -```lucee -ws = new WebSocket(server_url); - -ws.onopen = function(){ - //do staff or send a message -} - -ws.onmessage = function(message){ - do(message.data); -} - -ws.onclose = function(){ - //do staff or send a message -} -``` - -Please refer to the sample apps source code for more examples. - -If browser failover is important to you, many OS libraries exist that has the ability to failover to other technologies as flash or ajax longpolling if there is no WebSocket support available in the current browser. This is one of the best client around that offer exactly this failover : [http://socket.io/](http://socket.io/) diff --git a/docs/04.guides/08.lucee-5/06.component-static/page.md b/docs/04.guides/08.lucee-5/06.component-static/page.md deleted file mode 100644 index 449878d23..000000000 --- a/docs/04.guides/08.lucee-5/06.component-static/page.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Static support for components -id: lucee-5-component-static -related: -- tag-component -categories: -- component -- scopes -- static -description: Lucee 5 supports static variables and functions inside components ---- - -# Static support for components # - -**Lucee 5 supports static variables and functions inside components.** - -Example: - -```luceescript -component { - // inside the static constructor you can define static variables, this code is executed when the "class" instance is loaded - static { - susi=1; // written to the static scope (defining the scope is not necessary) - static.sorglos=2; // again written to the static scope - } - - public static function testStatic() { - - } - - public function testInstance() { - static.testStatic(); // calling a static function - return static.sorglos; // returning data from the static scope - } -} -``` - -The "static" constructor `static {...}` is executed once before the component is loaded for the first time, so every component of the same type shares the same static scope. - -You can use static functions and data as follows. - -```luceescript -component Test { - static { - staticValue=1; - } - public static function testStatic(){} -} -``` - -```luceescript -Test::testStatic(); -x=Test:: staticValue; -``` diff --git a/docs/04.guides/08.lucee-5/07.dialect-lucee/page.md b/docs/04.guides/08.lucee-5/07.dialect-lucee/page.md index 388248fee..2581f852c 100644 --- a/docs/04.guides/08.lucee-5/07.dialect-lucee/page.md +++ b/docs/04.guides/08.lucee-5/07.dialect-lucee/page.md @@ -1,9 +1,13 @@ --- -title: The Lucee dialect +title: The Lucee dialect (removed 6.1) id: lucee-5-dialect-lucee +related: + - breaking-changes-6-0-to-6-1 --- # New Language dialect Lucee # +>>>>> The Lucee dialect was removed in 6.1, as it was barely used and removing it made Lucee faster for CFML + **In addition to the existing "CFML" language dialect, Lucee 5 comes with a completely new dialect simply called "Lucee".** The Lucee dialect is a light-weight dynamic scripting and tag language for the JVM that enables the rapid development of simple to highly sophisticated web applications. diff --git a/docs/05.categories/295.thread/category.md b/docs/05.categories/295.thread/category.md index 306132362..fb984344c 100644 --- a/docs/05.categories/295.thread/category.md +++ b/docs/05.categories/295.thread/category.md @@ -1,6 +1,9 @@ --- title: Threads id: category-thread +categories: +- scopes +description: Threads --- - [Easy Parallelism in Lucee](https://www.rasia.io/blog/easy-parallelism-in-lucee.html) diff --git a/docs/recipes/README.md b/docs/recipes/README.md index b4b09b624..379c6f23b 100644 --- a/docs/recipes/README.md +++ b/docs/recipes/README.md @@ -24,6 +24,10 @@ Learn how to output the current date in Lucee. A guide to breaking changes introduced in Lucee between version 6.0 and 6.1 +## [Breaking Changes between Lucee 6.1 and 6.2](/docs/recipes/breaking-changes-6-2.md) + +A guide to breaking changes introduced in Lucee between version 6.1 and 6.2 + ## [Cache a Query for the current request](/docs/recipes/cached-within-request.md) Cache a Query for the current request in Lucee. @@ -148,7 +152,7 @@ Learn how Lucee logs all CFHTTP calls and how to manage these logs. This guide e Guide on using import to import components, Java classes, and custom tags in Lucee -## [Inline Component](/docs/recipes/inline-components.md) +## [Inline Components](/docs/recipes/inline-components.md) Learn how to create and use inline components in Lucee. This guide demonstrates how to define components directly within your CFML code, making it easier to create and use components without needing a separate .cfc file. Examples include creating an inline component and using it similarly to closures. @@ -168,6 +172,10 @@ Guide on using Java libraries in Lucee 6.2 with Maven and import Guide on configuring Java settings in Lucee using Application.cfc +## [Language Server Protocol (LSP) for Lucee](/docs/recipes/language-server.md) + +This document explains how to configure and use the Language Server Protocol implementation for Lucee CFML/CFScript. + ## [Lazy Queries](/docs/recipes/lazy-queries.md) How to use lazy queries @@ -176,6 +184,10 @@ How to use lazy queries List existing Cache Connections available in Lucee. +## [Logging in Lucee](/docs/recipes/logging.md) + +How to configure and customize logging + ## [Loop Labels](/docs/recipes/loop-labels.md) Lucee supports labels for all loop tags and statements, allowing you to control the flow of nested loops more precisely. @@ -280,6 +292,10 @@ Guide on configuring and interacting with specific S3 regions in Lucee using the Learn about script templates in Lucee. This guide explains how Lucee supports templates with the `.cfs` extension, allowing you to write direct script code without the need for the `` tag. +## [Single Mode vs Multi Mode in Lucee](/docs/recipes/single-vs-multi-mode.md) + +Understanding the differences between single mode and multi mode in Lucee. + ## [Startup Listeners - Server.cfc and Web.cfc](/docs/recipes/startup-listeners-code.md) Lucee supports two types of Startup Listeners: Server.cfc and Web.cfc. @@ -288,7 +304,7 @@ Lucee supports two types of Startup Listeners: Server.cfc and Web.cfc. Static scope in components is needed to create an instance of cfc and call its method. -## [Sub Component](/docs/recipes/sub-components.md) +## [Sub Components](/docs/recipes/sub-components.md) Learn how to create and use sub components in Lucee. This guide demonstrates how to define additional components within a .cfc file, making it easier to organize related components. Examples include creating a main component with sub components, and how to address/load these sub components. @@ -300,11 +316,11 @@ This document explains how you can improve the performance of your website in a How to use tags in script -## [Thread Task](/docs/recipes/thread-task.md) +## [Thread Tasks](/docs/recipes/thread-task.md) How to use Thread Tasks -## [Thread Usage](/docs/recipes/thread-usage.md) +## [Using Threads in Lucee](/docs/recipes/thread-usage.md) How to use threads in Lucee diff --git a/docs/recipes/archives-creating-and-deploy.md b/docs/recipes/archives-creating-and-deploy.md index d9d55c76d..f8603ae62 100644 --- a/docs/recipes/archives-creating-and-deploy.md +++ b/docs/recipes/archives-creating-and-deploy.md @@ -12,6 +12,9 @@ "Component", "CFC", "CFM" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/basic-date.md b/docs/recipes/basic-date.md index 4e26da217..7e7c471eb 100644 --- a/docs/recipes/basic-date.md +++ b/docs/recipes/basic-date.md @@ -3,6 +3,9 @@ "title": "Basic Date", "id": "cookbook-basic-date", "description": "Learn how to output the current date in Lucee.", + "categories": [ + "datetime" + ], "keywords": [ "Date", "Current date", diff --git a/docs/recipes/breaking-changes-6-1.md b/docs/recipes/breaking-changes-6-1.md index 92a3784e8..64a53e682 100644 --- a/docs/recipes/breaking-changes-6-1.md +++ b/docs/recipes/breaking-changes-6-1.md @@ -3,9 +3,12 @@ { "title": "Breaking Changes Between Lucee 6.0 and 6.1", "id": "breaking-changes-6-0-to-6-1", - "categories": ["breaking changes", "migration"], + "categories": ["breaking changes", "migration","compat"], "description": "A guide to breaking changes introduced in Lucee between version 6.0 and 6.1", - "keywords": ["breaking changes", "Lucee 6.0", "Lucee 6.1", "migration", "upgrade"] + "keywords": ["breaking changes", "Lucee 6.0", "Lucee 6.1", "migration", "upgrade"], + "related": [ + "logging-cfhttp-calls" + ] } --> diff --git a/docs/recipes/breaking-changes-6-2.md b/docs/recipes/breaking-changes-6-2.md new file mode 100644 index 000000000..c57cadec7 --- /dev/null +++ b/docs/recipes/breaking-changes-6-2.md @@ -0,0 +1,44 @@ + + +# Breaking Changes between Lucee 6.1 and 6.2 + +This document outlines the breaking changes introduced when upgrading from Lucee 6.1 to Lucee 6.2. Be aware of these changes when migrating your applications to ensure smooth compatibility. + +## Changing PreciseMath to be off by default + +With Lucee 6, we introduced support for higher precision maths, by switching the underlying Java class from Double to BigInteger. + +During the development of 6.2, which was heavily focussed on increasing Lucee's overall performance, it became apparent that the overhead of BigDecimal, both in terms of performance and memory usage was too simply high. + +So, we decided to switch the default back to preciseMath=false, which really improved performance as this affects any use of numbers. For most Lucee applications, this change will have no functional affect. + +Dynamically switching preciseMath on and off as required is recommended, rather than using it all the time. + +As part of this change, we updated all our test cases to test switching dynamically during a request and identified a few problems which we addressed. + +## Support for Jakarta Servlet + +Lucee 6.2 adds support for Jakarta Servlet, in addition to Javax. + +Javax libraries are still required for Lucee to work when deployed on a Jakarta based Servlet engine like Tomcat 10+. + +Our Official Lucee 6.2 Installers and Docker images have been updated to bundle Tomcat 10+. + +Older Javax Servlet engines (i.e. Tomcat 9) are still supported as well, just make sure they are updated and still maintained. + +## Lucee is up to 50% for some operations than Lucee 5.4 + +While not exactly what you might expect as a breaking change, we did find that all the improvements made with 6.2 managed to surface some other underlying bugs, simply because Lucee got faster. + +You also may find some race conditions, etc within your own code / applications. diff --git a/docs/recipes/check-for-changes.md b/docs/recipes/check-for-changes.md index 50bbd0483..5a0a50e7d 100644 --- a/docs/recipes/check-for-changes.md +++ b/docs/recipes/check-for-changes.md @@ -10,6 +10,9 @@ "Automatic update", "Server context", "Web context" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/checksum.md b/docs/recipes/checksum.md index b16e1ebf4..eac1055b0 100644 --- a/docs/recipes/checksum.md +++ b/docs/recipes/checksum.md @@ -9,6 +9,13 @@ "cfhttp", "hash", "fileReadBinary" + ], + "related": [ + "function-fileReadBinary", + "tag-http" + ], + "categories": [ + "crypto" ] } --> diff --git a/docs/recipes/configuration-administrator-cfc.md b/docs/recipes/configuration-administrator-cfc.md index 36312839c..9cf328046 100644 --- a/docs/recipes/configuration-administrator-cfc.md +++ b/docs/recipes/configuration-administrator-cfc.md @@ -10,6 +10,9 @@ "Lucee", "Web context", "Server configuration" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/configuration-lucee5.md b/docs/recipes/configuration-lucee5.md index a1b0fc7b4..2cd691ab3 100644 --- a/docs/recipes/configuration-lucee5.md +++ b/docs/recipes/configuration-lucee5.md @@ -2,10 +2,13 @@ diff --git a/docs/recipes/configuration.md b/docs/recipes/configuration.md index 9c6ec1a0f..46e1a4fb8 100644 --- a/docs/recipes/configuration.md +++ b/docs/recipes/configuration.md @@ -1,11 +1,18 @@ diff --git a/docs/recipes/convert-a-cfml-func-to-java.md b/docs/recipes/convert-a-cfml-func-to-java.md index c3eda0c5c..99d0b0d9c 100644 --- a/docs/recipes/convert-a-cfml-func-to-java.md +++ b/docs/recipes/convert-a-cfml-func-to-java.md @@ -12,6 +12,12 @@ "Java", "lambda", "Lucee" + ], + "categories":[ + "java" + ], + "related": [ + "tag-component" ] } --> diff --git a/docs/recipes/datasource-how-to-define-them.md b/docs/recipes/datasource-how-to-define-them.md index 00f3a7adb..e31247a3d 100644 --- a/docs/recipes/datasource-how-to-define-them.md +++ b/docs/recipes/datasource-how-to-define-them.md @@ -10,6 +10,10 @@ "Application.cfc", "Default datasource", "MySQL" + ], + "categories":[ + "query", + "server" ] } --> diff --git a/docs/recipes/docker.md b/docs/recipes/docker.md index a656f4bd0..2a8a21dd9 100644 --- a/docs/recipes/docker.md +++ b/docs/recipes/docker.md @@ -8,6 +8,9 @@ "commandbox", "installation", "kubernetes" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/environment-variables-system-properties.md b/docs/recipes/environment-variables-system-properties.md index 6c0cf188d..1ac9e5a2d 100644 --- a/docs/recipes/environment-variables-system-properties.md +++ b/docs/recipes/environment-variables-system-properties.md @@ -9,7 +9,10 @@ "Properties", "System Properties", "setting", - "cofig" + "config" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/event-gateway-in-app-cfc.md b/docs/recipes/event-gateway-in-app-cfc.md index e645534f6..3b265cd56 100644 --- a/docs/recipes/event-gateway-in-app-cfc.md +++ b/docs/recipes/event-gateway-in-app-cfc.md @@ -13,7 +13,8 @@ ], "categories": [ "application", - "event handling" + "event handling", + "gateways" ], "description": "An overview of event handling functions in Application.cfc for Lucee.", "images": { diff --git a/docs/recipes/exception-cause.md b/docs/recipes/exception-cause.md index ebe780402..d8d3f369e 100644 --- a/docs/recipes/exception-cause.md +++ b/docs/recipes/exception-cause.md @@ -10,6 +10,12 @@ "cause", "thread", "parent" + ], + "categories": [ + "debugging" + ], + "related": [ + "tag-throw" ] } --> diff --git a/docs/recipes/extension-installation.md b/docs/recipes/extension-installation.md index 7ca98c13a..bde7658a7 100644 --- a/docs/recipes/extension-installation.md +++ b/docs/recipes/extension-installation.md @@ -14,6 +14,9 @@ "system property", "hot deployment", "automation" + ], + "categories": [ + "extensions" ] } --> diff --git a/docs/recipes/externalizing-strings.md b/docs/recipes/externalizing-strings.md index 36495f6bf..eb96fb23c 100644 --- a/docs/recipes/externalizing-strings.md +++ b/docs/recipes/externalizing-strings.md @@ -9,6 +9,9 @@ "Class files", "Static contents", "Lucee" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/file-extensions.md b/docs/recipes/file-extensions.md index d31f430a5..3b66b10bc 100644 --- a/docs/recipes/file-extensions.md +++ b/docs/recipes/file-extensions.md @@ -10,6 +10,9 @@ "cfml", "cfs", "file extensions" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/function-listeners.md b/docs/recipes/function-listeners.md index 0275b8f3c..5786d6931 100644 --- a/docs/recipes/function-listeners.md +++ b/docs/recipes/function-listeners.md @@ -10,6 +10,13 @@ "thread", "function", "promises" + ], + "related": [ + "tag-function", + "tag-thread" + ], + "categories": [ + "thread" ] } --> diff --git a/docs/recipes/function-systemoutput.md b/docs/recipes/function-systemoutput.md index 5113c1329..017e75806 100644 --- a/docs/recipes/function-systemoutput.md +++ b/docs/recipes/function-systemoutput.md @@ -1,7 +1,7 @@ # Function SystemOutput -This document explains the systemoutput function with some simple examples. +This document explains the systemOutput function with some simple examples. + +It's like dump() for your console, including support for complex types. + +For example, if you are using Docker, you can see this output in the console logs. ## Example 1: diff --git a/docs/recipes/get-dbdriver-from-maven.md b/docs/recipes/get-dbdriver-from-maven.md index 34df78ce7..a48480ec6 100644 --- a/docs/recipes/get-dbdriver-from-maven.md +++ b/docs/recipes/get-dbdriver-from-maven.md @@ -9,6 +9,12 @@ "maven", "mysql" ,"db" + ], + "categories":[ + "query" + ], + "related": [ + "tag-query" ] } --> diff --git a/docs/recipes/http-logging.md b/docs/recipes/http-logging.md index b3cbe0e9b..07093f8c2 100644 --- a/docs/recipes/http-logging.md +++ b/docs/recipes/http-logging.md @@ -10,6 +10,9 @@ "Lucee", "log level", "http log" + ], + "related": [ + "tag-http" ] } --> diff --git a/docs/recipes/import.md b/docs/recipes/import.md index 8fc3c5f12..226f772c9 100644 --- a/docs/recipes/import.md +++ b/docs/recipes/import.md @@ -12,6 +12,14 @@ "java classes", "custom tags", "taglib" + ], + "categories": [ + "java" + ], + "related":[ + "function-createobject", + "tag-import", + "developing-with-lucee-server" ] } --> diff --git a/docs/recipes/index.json b/docs/recipes/index.json index 178c1783b..3bb93d68d 100644 --- a/docs/recipes/index.json +++ b/docs/recipes/index.json @@ -52,7 +52,7 @@ "file": "archives-creating-and-deploy.md", "title": "Archives - Creating and deploying Lucee Archives (.lar files)", "path": "/docs/recipes/archives-creating-and-deploy.md", - "hash": "4726b05d39364e952a48ede93b29a67f", + "hash": "1ca3f9e41d2123af29a9c2101b403e8f", "keywords": [ "Lucee", "Archives", @@ -68,7 +68,7 @@ "file": "basic-date.md", "title": "Basic Date - Output the current date", "path": "/docs/recipes/basic-date.md", - "hash": "f66410455e64f965fa03df7649e092a3", + "hash": "ac00857102cfd5086b6ac81fa6acdc46", "keywords": [ "Date", "Current date", @@ -83,7 +83,7 @@ "file": "breaking-changes-6-1.md", "title": "Breaking Changes Between Lucee 6.0 and 6.1", "path": "/docs/recipes/breaking-changes-6-1.md", - "hash": "90562d7712f038778721fceea4d4412d", + "hash": "83694a88a61b9435d594bd6f079e8f47", "keywords": [ "breaking changes", "Lucee 6.0", @@ -92,6 +92,19 @@ "upgrade" ] }, + { + "file": "breaking-changes-6-2.md", + "title": "Breaking Changes between Lucee 6.1 and 6.2", + "path": "/docs/recipes/breaking-changes-6-2.md", + "hash": "ddc246972a2f0e278ead2fa3cfd310aa", + "keywords": [ + "breaking changes", + "Lucee 6.1", + "Lucee 6.2", + "migration", + "upgrade" + ] + }, { "file": "cached-within-request.md", "title": "Cache a Query for the current request", @@ -123,7 +136,7 @@ "file": "check-for-changes.md", "title": "Check for changes in your configuration file automatically", "path": "/docs/recipes/check-for-changes.md", - "hash": "c953e038012d3949f25e943018d8688c", + "hash": "1871271c6d6c1d999fc25d9bfcce2f6e", "keywords": [ "Configuration", "Check for changes", @@ -137,7 +150,7 @@ "file": "checksum.md", "title": "Checksum", "path": "/docs/recipes/checksum.md", - "hash": "a1fef15b4e0bd041aa90bd1cbb126a5d", + "hash": "e0bdf3586c0a44803608af2981893fb7", "keywords": [ "Checksum", "File validation", @@ -150,7 +163,7 @@ "file": "configuration-administrator-cfc.md", "title": "Configure Lucee within your application", "path": "/docs/recipes/configuration-administrator-cfc.md", - "hash": "c8b3b9c27321db7bec51568b5d8b3a70", + "hash": "1eb98c1ab55de06cffc2aefac70b9fe9", "keywords": [ "Administrator.cfc", "cfadmin", @@ -164,7 +177,7 @@ "file": "configuration-lucee5.md", "title": "Configuration - Lucee 5", "path": "/docs/recipes/configuration-lucee5.md", - "hash": "16c3dbbc3b2c1efbbd7b808bbf94df9b", + "hash": "f12a649592d2371ea395566b63a28f03", "keywords": [ "configuration", "config", @@ -177,7 +190,7 @@ "file": "configuration.md", "title": "Configuration - How to Configure Lucee", "path": "/docs/recipes/configuration.md", - "hash": "2c4b6dbbcf904c2fa51de69e5f9519c1", + "hash": "fffc5b4a5d6f986c1371c2378cbb42f2", "keywords": [ "configuration", "config", @@ -190,7 +203,7 @@ "file": "convert-a-cfml-func-to-java.md", "title": "Convert a CFML Function/Component to use in Java", "path": "/docs/recipes/convert-a-cfml-func-to-java.md", - "hash": "0dcbbce8a20bcd390e27d396fd0985e1", + "hash": "9a48e8bbd3dfed94c2185ec898a2ba6c", "keywords": [ "conversion", "cfc", @@ -205,7 +218,7 @@ "file": "datasource-how-to-define-them.md", "title": "Datasource - How to define them", "path": "/docs/recipes/datasource-how-to-define-them.md", - "hash": "612c8cd0a200d9abfc8d5b9497971e88", + "hash": "9f62ba260513fc3d060ba0f345dbcaed", "keywords": [ "Datasource", "Define datasource", @@ -240,7 +253,7 @@ "file": "docker.md", "title": "Docker Information", "path": "/docs/recipes/docker.md", - "hash": "890489bc2e12ed673935f3b2d0263b78", + "hash": "417a8403f7b70a4b7be816e838ebe328", "keywords": [ "Docker", "commandbox", @@ -266,14 +279,14 @@ "file": "environment-variables-system-properties.md", "title": "Environment Variables / System Properties for Lucee", "path": "/docs/recipes/environment-variables-system-properties.md", - "hash": "ab594b0f78fc2d3cb133554e60c3fb09", + "hash": "f71a857a9386a98db4404aadd398d7dd", "keywords": [ "Environment", "Environment Variables", "Properties", "System Properties", "setting", - "cofig" + "config" ] }, { @@ -294,7 +307,7 @@ "file": "event-gateway-in-app-cfc.md", "title": "Event Handling in Application.cfc", "path": "/docs/recipes/event-gateway-in-app-cfc.md", - "hash": "81f8b93eaf6629dcdf512dd247bb5b13", + "hash": "d16a04c64dbcb4245d2c4dd729d697cb", "keywords": [ "Event Handling", "Application.cfc", @@ -361,7 +374,7 @@ "file": "exception-cause.md", "title": "Exception - Cause", "path": "/docs/recipes/exception-cause.md", - "hash": "d38b239656cae0e99e6784155a48433d", + "hash": "309daf755a417a7ef336093c917f0e0d", "keywords": [ "exception", "error", @@ -388,7 +401,7 @@ "file": "extension-installation.md", "title": "Extension Installation", "path": "/docs/recipes/extension-installation.md", - "hash": "9b5d3396c15710bdd224d63171ec3fd9", + "hash": "a9d945da5b5c3099edb1e1502693d1fb", "keywords": [ "extension", "install", @@ -405,7 +418,7 @@ "file": "externalizing-strings.md", "title": "Externalize strings", "path": "/docs/recipes/externalizing-strings.md", - "hash": "cac194b9345a0133c8c1985b75b8981f", + "hash": "0468a8eb799d2ba3305a3c3c15e3a32d", "keywords": [ "Externalize strings", "Memory reduction", @@ -418,7 +431,7 @@ "file": "file-extensions.md", "title": "File Extensions", "path": "/docs/recipes/file-extensions.md", - "hash": "649c74438e264a8e29eec5ea07aa9eab", + "hash": "ebe46feb87dbb9145ee212d08733ead0", "keywords": [ "CFML", "cfm", @@ -445,7 +458,7 @@ "file": "function-listeners.md", "title": "Function Listeners", "path": "/docs/recipes/function-listeners.md", - "hash": "fb4c0a4e5e8dc80158edf3dd680c048d", + "hash": "993f0ad6516c54c8021d77842f48aee1", "keywords": [ "parallel", "async", @@ -458,7 +471,7 @@ "file": "function-systemoutput.md", "title": "Function SystemOutput", "path": "/docs/recipes/function-systemoutput.md", - "hash": "59046be4f7a342b242f0fcc88468882e", + "hash": "c10c0a9e6ad2d16859747fce4831fd6a", "keywords": [ "SystemOutput function", "Debugging", @@ -471,7 +484,7 @@ "file": "get-dbdriver-from-maven.md", "title": "Get Datasource Drivers Directly from Maven", "path": "/docs/recipes/get-dbdriver-from-maven.md", - "hash": "34d33dd5ea56e9ccfb539c246bdd0f4e", + "hash": "cf117cb0ecd677ee2f077583403ef3ec", "keywords": [ "datasource", "maven", @@ -511,7 +524,7 @@ "file": "http-logging.md", "title": "Logging CFHTTP Calls", "path": "/docs/recipes/http-logging.md", - "hash": "ab58506857d7220412399d5b560d8152", + "hash": "517db531ed4aacd700ea4b78e1a3e168", "keywords": [ "cfhttp", "logging", @@ -524,7 +537,7 @@ "file": "import.md", "title": "Import", "path": "/docs/recipes/import.md", - "hash": "523e80ff0fd2993295b613c71e177c3c", + "hash": "d29fb9ca4c85701d43ecd0cc521686be", "keywords": [ "cfimport", "import", @@ -537,9 +550,9 @@ }, { "file": "inline-components.md", - "title": "Inline Component", + "title": "Inline Components", "path": "/docs/recipes/inline-components.md", - "hash": "cfea57ca49e66f2ba76a79d439adf2d8", + "hash": "8bff1dddaef137a0fee3bbd7cfb1e8a5", "keywords": [ "CFML", "component", @@ -551,7 +564,7 @@ "file": "java-explicit-casting.md", "title": "Java - Explicit Casting of a Component to a Specific Interface", "path": "/docs/recipes/java-explicit-casting.md", - "hash": "d7bf4af9b9a8bacd1cde12f9f2a15bc7", + "hash": "98c9cfb2af60e6e0e7785b735ccdee7a", "keywords": [ "java", "cast", @@ -563,7 +576,7 @@ "file": "java-in-functions-and-closures.md", "title": "Java in Functions and Closures", "path": "/docs/recipes/java-in-functions-and-closures.md", - "hash": "411e845bac8e2978a974ea3af94ab1a5", + "hash": "1e3e2d70e8be13df7caa2323edaf1fb8", "keywords": [ "function", "java", @@ -577,7 +590,7 @@ "file": "java-libraries.md", "title": "Interacting with Java Libraries in Lucee 6.2", "path": "/docs/recipes/java-libraries.md", - "hash": "87bc11020fc4f4df8ec76e5c9d732939", + "hash": "11e13ce9bec0c7d7e22148df7007a642", "keywords": [ "java", "maven", @@ -591,7 +604,7 @@ "file": "java-settings.md", "title": "Java Settings in Application.cfc (Now with Maven Support)", "path": "/docs/recipes/java-settings.md", - "hash": "cae010adbc2b292bfc8b5abfeb5d0027", + "hash": "3300140a483332be2ed57ab54e2f4256", "keywords": [ "Java settings", "Application.cfc", @@ -599,11 +612,25 @@ "cfapplication" ] }, + { + "file": "language-server.md", + "title": "Language Server Protocol (LSP) for Lucee", + "path": "/docs/recipes/language-server.md", + "hash": "19b8dbee03749dfa0283528d9a8cfe40", + "keywords": [ + "LSP", + "language server", + "IDE integration", + "VS Code", + "development tools", + "code completion" + ] + }, { "file": "lazy-queries.md", "title": "Lazy Queries", "path": "/docs/recipes/lazy-queries.md", - "hash": "8fe64da123e2f7e52abb3fb4f272c789", + "hash": "317d01daee08a03879da1870bae18c10", "keywords": [ "Lazy Queries", "Regular Queries", @@ -626,11 +653,22 @@ "Lucee" ] }, + { + "file": "logging.md", + "title": "Logging in Lucee", + "path": "/docs/recipes/logging.md", + "hash": "31a26b6ce13855824c8b7b9316429086", + "keywords": [ + "Logging", + "Log levels", + "Lucee" + ] + }, { "file": "loop-labels.md", "title": "Loop Labels", "path": "/docs/recipes/loop-labels.md", - "hash": "aea64c62a64313fa7d87e3b8c15ef5cd", + "hash": "8548e4d8f418737a716fafd4a2d3a6ab", "keywords": [ "loop", "label", @@ -644,7 +682,7 @@ "file": "loop-through-files.md", "title": "Looping Through File", "path": "/docs/recipes/loop-through-files.md", - "hash": "2387d7589d70fc3977f33db5989a8793", + "hash": "10d132ae7c5b8a435b6ebf3f9cc50519", "keywords": [ "Looping through files", "cffile", @@ -658,7 +696,7 @@ "file": "mail-how-to-send-a-mail.md", "title": "Mail - How to send a Mail", "path": "/docs/recipes/mail-how-to-send-a-mail.md", - "hash": "c278c5dff011da0798117834fdf3c9c7", + "hash": "3fad8fffd34a47eeaa9fb7dc070fe91a", "keywords": [ "Email", "Send mail", @@ -672,7 +710,7 @@ "file": "mail-listener.md", "title": "Mail Listeners", "path": "/docs/recipes/mail-listener.md", - "hash": "8cea64daf2a3141d4132d74a4238ac49", + "hash": "0be0699447d9fb3c7bbf2a111ac19337", "keywords": [ "mail", "listener", @@ -684,7 +722,7 @@ "file": "mappings-how-to-define-a-reg-mapping.md", "title": "Mappings - How to define a regular Mapping", "path": "/docs/recipes/mappings-how-to-define-a-reg-mapping.md", - "hash": "7a3dcbd7f77c1db9f805512d4d17d897", + "hash": "9a3a1faf1724628e3728db263d78052f", "keywords": [ "Mapping", "Filesystem", @@ -697,7 +735,7 @@ "file": "mathematical-precision.md", "title": "Mathematical Precision", "path": "/docs/recipes/mathematical-precision.md", - "hash": "fd0a4bf923840d968652e201575d3fd3", + "hash": "4c6eb9d898793974f428d91d3bbea1fb", "keywords": [ "CFML", "math", @@ -712,7 +750,7 @@ "file": "maven.md", "title": "Maven (Lucee 6.2)", "path": "/docs/recipes/maven.md", - "hash": "cee6ec1423dcbbb05bae1644915db162", + "hash": "2a607eda8b76d28a2194af17f4d0c975", "keywords": [ "Maven", "Java", @@ -723,7 +761,7 @@ "file": "monitoring-debugging.md", "title": "Monitoring/Debugging", "path": "/docs/recipes/monitoring-debugging.md", - "hash": "598cdd7328ecba6f890d19338abf375f", + "hash": "f468d23742fb1601c77f516a05ac8a78", "keywords": [ "monitoring", "debugging", @@ -739,7 +777,7 @@ "file": "monitoring-enable-for-your-session.md", "title": "Monitoring - Enable for your session", "path": "/docs/recipes/monitoring-enable-for-your-session.md", - "hash": "40b88dc626df5c52efe6c02b9e0601e9", + "hash": "f514983cf436185fd942585022ac198b", "keywords": [ "monitoring", "session" @@ -749,7 +787,7 @@ "file": "new-operator.md", "title": "New Operator in Lucee", "path": "/docs/recipes/new-operator.md", - "hash": "011473bdfa41fc6e27523f81b3d8c7d9", + "hash": "ffd14849f9bcf50b60c9ffb09dfce6f8", "keywords": [ "new", "java", @@ -763,7 +801,7 @@ "file": "null-support.md", "title": "Null Support", "path": "/docs/recipes/null-support.md", - "hash": "1632a30798317207a90f34f6c1167b74", + "hash": "a7203c9d96ab0a967bfaf4791975809b", "keywords": [ "Null support", "null keyword", @@ -776,7 +814,7 @@ "file": "overwrite-build-in-functions-tags.md", "title": "Overwriting and Adding Built-in Functions and Tags", "path": "/docs/recipes/overwrite-build-in-functions-tags.md", - "hash": "7ae2a5e35734651ee4d8b7b162f0f7e6", + "hash": "a5df43a5dd71fa65bd9020221219e79d", "keywords": [ "function", "BIF", @@ -793,7 +831,7 @@ "file": "pdf-engine-flying-saucer.md", "title": "PDF Engine - Flying Saucer (CFDocument)", "path": "/docs/recipes/pdf-engine-flying-saucer.md", - "hash": "58a53f406410c3915ad12f6bde20f158", + "hash": "c7c8d3949c973fa15922cfe032695ff7", "keywords": [ "Flying Saucer", "PDF Engine", @@ -805,7 +843,7 @@ "file": "precompiled-code.md", "title": "Precompiled Code", "path": "/docs/recipes/precompiled-code.md", - "hash": "106f0b51ff0b285f474d8b64add272d2", + "hash": "e044a8d4bd44415a11f2605c0a8e1495", "keywords": [ "Precompiled", "Pre-compile code", @@ -820,7 +858,7 @@ "file": "query-async.md", "title": "Query Async", "path": "/docs/recipes/query-async.md", - "hash": "185df889c6bf4de47668895c9c708d94", + "hash": "20015ca45615de7ad598684f678946c3", "keywords": [ "query", "async", @@ -848,7 +886,7 @@ "file": "query-indexes.md", "title": "Query Indexes", "path": "/docs/recipes/query-indexes.md", - "hash": "e1d9bdad9e6a50cc9d6ee1bb08b36765", + "hash": "23ea72b4476098df760244ec879dc208", "keywords": [ "query", "indexes", @@ -859,7 +897,7 @@ "file": "query-listener.md", "title": "Query Listeners", "path": "/docs/recipes/query-listener.md", - "hash": "9497bb3976a1910f94c2a631a43bc5eb", + "hash": "8c12fac2d5c427c2e91e354a90612524", "keywords": [ "query", "listener", @@ -900,7 +938,7 @@ "file": "query-return-type.md", "title": "Query return type", "path": "/docs/recipes/query-return-type.md", - "hash": "792f4fe5807a39611254146c37100db9", + "hash": "bae3c3089df32f5258c1f7bc2f6d1b24", "keywords": [ "Query return type", "Array return type", @@ -913,7 +951,7 @@ "file": "read-xml-with-a-listener-model-sax.md", "title": "Read XML with a listener Model (SAX)", "path": "/docs/recipes/read-xml-with-a-listener-model-sax.md", - "hash": "b0f18d5228f3cf2e7a889d7c3954b844", + "hash": "6d6838168dd41f7ea0a8cfc5e40334a7", "keywords": [ "XML", "SAX", @@ -927,7 +965,7 @@ "file": "request-timeout.md", "title": "Request Timeout", "path": "/docs/recipes/request-timeout.md", - "hash": "d29d7f0ace7a4a6b683c825af4fd36aa", + "hash": "0ee1b809bf69a96385f22edeef12f94d", "keywords": [ "request timeout", "timeout", @@ -973,7 +1011,7 @@ "file": "script-templates.md", "title": "Script Templates", "path": "/docs/recipes/script-templates.md", - "hash": "a31ad423369d46df7824c7c2e952d086", + "hash": "11f8398506ad1b0b4bbecbccfb473fa2", "keywords": [ "CFML", "script", @@ -982,6 +1020,18 @@ "cfs" ] }, + { + "file": "single-vs-multi-mode.md", + "title": "Single Mode vs Multi Mode in Lucee", + "path": "/docs/recipes/single-vs-multi-mode.md", + "hash": "506a91089c49eb3d05e3e18f57364619", + "keywords": [ + "Lucee", + "Single Mode", + "Multi Mode", + "Configuration" + ] + }, { "file": "startup-listeners-code.md", "title": "Startup Listeners - Server.cfc and Web.cfc", @@ -1020,9 +1070,9 @@ }, { "file": "sub-components.md", - "title": "Sub Component", + "title": "Sub Components", "path": "/docs/recipes/sub-components.md", - "hash": "479f64357ac885abaa16ac74dc171612", + "hash": "e4a1dfbae98fe363be8068cf896596ab", "keywords": [ "CFML", "component", @@ -1034,7 +1084,7 @@ "file": "supercharge-your-website.md", "title": "Supercharge your website", "path": "/docs/recipes/supercharge-your-website.md", - "hash": "cba98355eb7396979f04febd592cee35", + "hash": "16de007fd5dfccb78faba68082ad2b00", "keywords": [ "Supercharge website", "Performance", @@ -1047,19 +1097,22 @@ "file": "tag-syntax.md", "title": "How to Use Tags in Script", "path": "/docs/recipes/tag-syntax.md", - "hash": "84e96b6ce7a258509922945a9d434940", + "hash": "d621a06b65dc4a2b569451e56b57a46f", "keywords": [ "Syntax", "tag", "function", - "Script" + "Script", + "throw", + "abort", + "return" ] }, { "file": "thread-task.md", - "title": "Thread Task", + "title": "Thread Tasks", "path": "/docs/recipes/thread-task.md", - "hash": "e0fb0c5456add34c97c1adf447cd77fb", + "hash": "d587d6a05f098f792004b2e9963d5ac4", "keywords": [ "Thread Tasks", "Daemon Threads", @@ -1070,9 +1123,9 @@ }, { "file": "thread-usage.md", - "title": "Thread Usage", + "title": "Using Threads in Lucee", "path": "/docs/recipes/thread-usage.md", - "hash": "04376a0a607d55b64c206cdd386f08d1", + "hash": "3c74853a5d561187025bec3cbaa54c24", "keywords": [ "Threads", "Parallel execution", @@ -1085,7 +1138,7 @@ "file": "timeout.md", "title": "Timeout", "path": "/docs/recipes/timeout.md", - "hash": "b7e03149be0aa44af86508797a0f675c", + "hash": "dd2b8b3c1ab71400a17e6e3bd8077a8d", "keywords": [ "tag", "timeout", @@ -1099,7 +1152,7 @@ "file": "types-in-lucee.md", "title": "Types in Lucee", "path": "/docs/recipes/types-in-lucee.md", - "hash": "5c5fcd8d807661d0f0988282fe41b9a2", + "hash": "8542e36d691ed1c47e9a4516236c3d2d", "keywords": [ "Types", "Function argument", @@ -1112,7 +1165,7 @@ "file": "using-s3-directly-for-source-code.md", "title": "Using S3 directly for source code", "path": "/docs/recipes/using-s3-directly-for-source-code.md", - "hash": "4fc9da16c9ed40562120ffacaad51a80", + "hash": "da4c48de2627bc1301d7af1e9f215854", "keywords": [ "S3", "Source code", @@ -1157,7 +1210,7 @@ "file": "websocket-extension.md", "title": "WebSocket Extension", "path": "/docs/recipes/websocket-extension.md", - "hash": "849d999dd657e7a8485b15f2656fe969", + "hash": "df72ace8a16bc55cf2730f87dcce06a5", "keywords": [ "Lucee", "Extension" diff --git a/docs/recipes/inline-components.md b/docs/recipes/inline-components.md index 8ae66b366..b216e023a 100644 --- a/docs/recipes/inline-components.md +++ b/docs/recipes/inline-components.md @@ -1,6 +1,6 @@ -# Inline Component +# Inline Components -Since Lucee 6.0, Lucee allows you to create inline components. These are components you can create directly in your CFML code, with no need to create a .cfc file for it. This feature allows you to directly use them, similar to closures. +Since Lucee 6.0, Lucee allows you to create inline components. + +These are components you can create directly in your CFML code, with no need to create a `.cfc` file for it. + +This feature allows you to directly use them, similar to closures, enabling more dynamic programming approaches. This example shows how to create an inline component and then use it: diff --git a/docs/recipes/java-explicit-casting.md b/docs/recipes/java-explicit-casting.md index 8411ae2f8..276b414ef 100644 --- a/docs/recipes/java-explicit-casting.md +++ b/docs/recipes/java-explicit-casting.md @@ -12,6 +12,10 @@ "cast", "convert", "method" + ], + "related": [ + "function-javacast", + "tag-component" ] } --> diff --git a/docs/recipes/java-in-functions-and-closures.md b/docs/recipes/java-in-functions-and-closures.md index 60b377f51..fde6b841b 100644 --- a/docs/recipes/java-in-functions-and-closures.md +++ b/docs/recipes/java-in-functions-and-closures.md @@ -11,6 +11,12 @@ "components", "lambda", "Lucee" + ], + "categories": [ + "java" + ], + "related": [ + "tag-function" ] } --> @@ -19,9 +25,9 @@ You can write CFML code directly in a function or a closure. -## Function +## Functions -Inside the function, you write regular Java code. The arguments and return type definition must be Java types. +Inside the function, you can write regular Java code. The arguments and return type definition must be Java types. ```lucee int function echoInt(int i) type="java" { @@ -30,7 +36,7 @@ int function echoInt(int i) type="java" { } ``` -## Component +## Components Of course, the function can also be part of a component. @@ -43,9 +49,11 @@ component { } ``` -## Java Lambda Function +## Java Lambda Functions -If the interface of a function matches a functional Java interface (Lambda), Lucee automatically implements that interface. In the following example, we implement the `IntUnaryOperator` implicitly. You can then pass it to Java and use it as such. +If the interface of a function matches a functional Java interface (Lambda), Lucee automatically implements that interface. + +In the following example, we implement the `IntUnaryOperator` implicitly. You can then pass it to Java and use it as such. ```lucee int function echoInt(int i) type="java" { diff --git a/docs/recipes/java-libraries.md b/docs/recipes/java-libraries.md index 447c5f24c..0e50fa23b 100644 --- a/docs/recipes/java-libraries.md +++ b/docs/recipes/java-libraries.md @@ -11,6 +11,12 @@ "Lucee", "libraries", "new operator" + ], + "categories": [ + "java" + ], + "related": [ + "maven" ] } --> diff --git a/docs/recipes/java-settings.md b/docs/recipes/java-settings.md index 68c960d83..b85d2b304 100644 --- a/docs/recipes/java-settings.md +++ b/docs/recipes/java-settings.md @@ -9,6 +9,9 @@ "Application.cfc", "javasettings", "cfapplication" + ], + "categories": [ + "java" ] } --> diff --git a/docs/recipes/lazy-queries.md b/docs/recipes/lazy-queries.md index 3da3061de..02da29240 100644 --- a/docs/recipes/lazy-queries.md +++ b/docs/recipes/lazy-queries.md @@ -12,6 +12,9 @@ "Performance", "Memory Optimization", "Lucee" + ], + "related": [ + "tag-query" ] } --> diff --git a/docs/recipes/logging.md b/docs/recipes/logging.md index bebc86865..c2b988e20 100644 --- a/docs/recipes/logging.md +++ b/docs/recipes/logging.md @@ -2,27 +2,39 @@ { "title": "Logging", "id": "logging", - "description": "", + "description": "How to configure and customize logging", "keywords": [ "Logging", "Log levels", "Lucee" + ], + "related": [ + "tag-log", + "function-writelog" + ], + "categories": [ + "server" ] } --> # Logging in Lucee -Lucee's logging system is a powerful and flexible framework designed to provide insights into your application’s behavior. By configuring logs, you can monitor errors, track events, and troubleshoot efficiently. +Lucee's logging system is a powerful and flexible framework designed to provide insights into your application’s behavior. + +By configuring logs, you can monitor errors, track events, and troubleshoot efficiently. ## Why Logging? Logging is an essential practice for maintaining reliable and performant applications. It allows you to: + - Monitor runtime behavior and identify issues. - Gain insights into application usage and performance. - Maintain an audit trail of events and actions. -Lucee supports various log types (or levels), enabling you to control the verbosity and focus of your logs. Additionally, you can configure logging destinations and formats to integrate seamlessly with your infrastructure. +Lucee supports various log types (or levels), enabling you to control the verbosity and focus of your logs. + +Additionally, you can configure logging destinations and formats to integrate seamlessly with your infrastructure. ## How to Use Log Levels? @@ -37,7 +49,9 @@ Log levels (or types) categorize log entries based on their importance or severi ### Configuring Log Level Thresholds -You can configure the minimum log level (threshold) for each logger in the **Lucee Administrator** or directly in the configuration file (`.CFConfig.json`). For instance, setting a threshold of `warn` means only warnings, errors, and fatal logs are recorded, ignoring `info`, `debug`, and `trace` logs. +You can configure the minimum log level (threshold) for each logger in the **Lucee Administrator** or directly in the configuration file (`.CFConfig.json`). + +For instance, setting a threshold of `warn` means only warnings, errors, and fatal logs are recorded, ignoring `info`, `debug`, and `trace` logs. This allows you to start with minimal logging in production and increase verbosity (e.g., to `debug`) for deeper analysis when needed. @@ -74,7 +88,9 @@ You can add, modify, or remove loggers in the **Lucee Administrator** or directl ### Internals: Powered by Log4j2 -Lucee's logging system is powered by **Log4j2**, providing robust support for appenders and layouts. You can extend Lucee logging by using any appender or layout supported by Log4j2. +Lucee's logging system is powered by **Log4j2**, providing robust support for Appenders and Layouts. + +You can extend Lucee logging by using any Appender or Layout supported by Log4j2. --- @@ -82,7 +98,7 @@ Lucee's logging system is powered by **Log4j2**, providing robust support for ap ### Built-in Appenders -Lucee comes with built-in support for the following appenders: +Lucee comes with built-in support for the following Appenders: - **console**: Logs output to the console, ideal for debugging in development or server environments. - **datasource**: Logs to a database table, allowing structured storage and querying of log data. @@ -90,7 +106,7 @@ Lucee comes with built-in support for the following appenders: ### Built-in Layouts -Lucee also provides the following layouts for customizing log output: +Lucee also provides the following Layouts for customizing log output: - **classic**: Produces traditional CFML-compatible output. - **datadog**: Formats logs for direct ingestion into **Datadog**. @@ -103,7 +119,9 @@ Lucee also provides the following layouts for customizing log output: ## Extending Logging with Custom Appenders and Layouts -In addition to the built-in appenders and layouts, Lucee supports custom configurations using third-party libraries. Here’s how you can define custom appenders and layouts: +In addition to the built-in Appenders and Layouts, Lucee supports custom configurations using third-party libraries. + +Here’s how you can define custom Appenders and Layouts: ### Custom Appender Configuration @@ -144,7 +162,7 @@ In addition to the built-in appenders and layouts, Lucee supports custom configu } ``` -This configuration sends logs to a Kafka topic with a custom pattern layout. +This configuration sends logs to a Kafka topic with a custom pattern Layout. --- @@ -176,6 +194,9 @@ catch(e) { cflog(log="application", type="error", exception=e); } ``` +(Due to the existing math log function, the cf prefix is still required here, unlike with other tags in script.) + + Lucee's `` tag supports various attributes, including `log`, `type`, `text`, and `exception`. Using these attributes, you can customize log entries to suit your application's needs. diff --git a/docs/recipes/loop-labels.md b/docs/recipes/loop-labels.md index 7295bbf7c..e3566005b 100644 --- a/docs/recipes/loop-labels.md +++ b/docs/recipes/loop-labels.md @@ -10,6 +10,9 @@ "while", "continue", "break" + ], + "related": [ + "tag-loop" ] } --> diff --git a/docs/recipes/loop-through-files.md b/docs/recipes/loop-through-files.md index 8eff546ca..b3748e5cf 100644 --- a/docs/recipes/loop-through-files.md +++ b/docs/recipes/loop-through-files.md @@ -10,6 +10,9 @@ "fileReadBinary", "Memory optimization", "Lucee" + ], + "related": [ + "tag-loop" ] } --> diff --git a/docs/recipes/mail-how-to-send-a-mail.md b/docs/recipes/mail-how-to-send-a-mail.md index 5ff3a2f97..814041fd6 100644 --- a/docs/recipes/mail-how-to-send-a-mail.md +++ b/docs/recipes/mail-how-to-send-a-mail.md @@ -16,6 +16,10 @@ "Mail server", "Mail script", "Lucee" + ], + "categories": [ + "protocols", + "core" ] } --> diff --git a/docs/recipes/mail-listener.md b/docs/recipes/mail-listener.md index 5af034d91..2f29d27fb 100644 --- a/docs/recipes/mail-listener.md +++ b/docs/recipes/mail-listener.md @@ -9,6 +9,12 @@ "listener", "Application.cfc", "component" + ], + "related": [ + "tag-mail" + ], + "categories": [ + "protocols" ] } --> diff --git a/docs/recipes/mappings-how-to-define-a-reg-mapping.md b/docs/recipes/mappings-how-to-define-a-reg-mapping.md index 0b666a83e..535a21164 100644 --- a/docs/recipes/mappings-how-to-define-a-reg-mapping.md +++ b/docs/recipes/mappings-how-to-define-a-reg-mapping.md @@ -9,7 +9,8 @@ ], "categories": [ "application", - "files" + "files", + "server" ], "description": "All about the different mappings in Lucee and how to use them.", "keywords": [ diff --git a/docs/recipes/mathematical-precision.md b/docs/recipes/mathematical-precision.md index 5f44745ec..ab9b207fd 100644 --- a/docs/recipes/mathematical-precision.md +++ b/docs/recipes/mathematical-precision.md @@ -12,23 +12,37 @@ "Lucee", "Application.cfc", "PrecisionEvaluate" + ], + "related": [ + "function-precisionevaluate" + ], + "categories": [ + "math", + "number" ] + } --> # Mathematical Precision -So far, Lucee has handled numbers internally as “double”, but with Lucee 6 we have switched to “BigDecimal”. This makes math operations much more precise and there is no need anymore to use the function “PrecisionEvaluate”. +So far, Lucee has handled numbers internally as “double”, but with Lucee 6 we have added support for using “BigDecimal”. + +This makes math operations much more precise (but slower) and there is no need anymore to use the function “PrecisionEvaluate”. + +Since version 6.0, all numbers Lucee uses in the runtime are by default BigDecimal based and no longer double as before. + +However, for performance reasons, with Lucee 6.2, we reverted the default to the old behavior as it's much faster. -Since version 6.0, all numbers Lucee uses in the runtime are by default BigDecimal based and no longer double as before. You can still change that fact in the Application.cfc as follows: +You can toggle precise math in the `Application.cfc` as follows: ```lucee -this.preciseMath = false; +this.preciseMath = true | false; ``` ## Dynamically during a request -You also simply toggle precision on or off for the current request. +You also simply toggle precision on or off for the current request, only as required, which is recommended for best performance. ```lucee application action="update" preciseMath="true|false"; diff --git a/docs/recipes/maven.md b/docs/recipes/maven.md index 31e02c0c2..bc18a4597 100644 --- a/docs/recipes/maven.md +++ b/docs/recipes/maven.md @@ -1,14 +1,20 @@ @@ -57,6 +63,19 @@ In `.CFConfig.json`, you can define Maven dependencies that will be used globall The `version` attribute is optional. If not specified, Lucee will automatically fetch the latest version available for the specified Maven artifact. +In addition, we also support the more concise Gradle style. + +```json +{ + "javasettings": { + "maven": [ + "org.graalvm.polyglot:polyglot:24.1.1" + , "org.graalvm.polyglot:python:24.1.1" + ] + } +} +``` + ## Application.cfc In your `Application.cfc`, you can override or extend the global Java settings by adding Maven dependencies specific to your application. diff --git a/docs/recipes/monitoring-debugging.md b/docs/recipes/monitoring-debugging.md index 08639fc60..dc615c027 100644 --- a/docs/recipes/monitoring-debugging.md +++ b/docs/recipes/monitoring-debugging.md @@ -13,6 +13,11 @@ "debug", "showdebugoutput", "cfapplication" + ], + "categories": [ + "monitoring", + "debugging", + "server" ] } --> diff --git a/docs/recipes/monitoring-enable-for-your-session.md b/docs/recipes/monitoring-enable-for-your-session.md index 473dbf3c7..489efffec 100644 --- a/docs/recipes/monitoring-enable-for-your-session.md +++ b/docs/recipes/monitoring-enable-for-your-session.md @@ -4,7 +4,8 @@ "id": "monitoring-enable-for-your-session", "since": "6.1", "categories": [ - "monitoring" + "monitoring", + "debugging" ], "description": "Shows you a way to enable Monitoring for your session", "keywords": [ diff --git a/docs/recipes/new-operator.md b/docs/recipes/new-operator.md index 2bc71019a..e2cb4e7e6 100644 --- a/docs/recipes/new-operator.md +++ b/docs/recipes/new-operator.md @@ -10,6 +10,14 @@ "class", "createObject", "component" + ], + "related": [ + "tag-component", + "function-createobject", + "developing-with-lucee-server" + ], + "categories": [ + "core" ] } --> diff --git a/docs/recipes/null-support.md b/docs/recipes/null-support.md index e8329f8db..8daae8149 100644 --- a/docs/recipes/null-support.md +++ b/docs/recipes/null-support.md @@ -4,7 +4,8 @@ "id": "null_support", "related": [ "function-isnull", - "function-nullvalue" + "function-nullvalue", + "developing-with-lucee-server" ], "description": "This document explains how to set null support in the Lucee server admin, assigning `null` value for a variable and how to use `null` and `nullvalue`.", "keywords": [ @@ -13,6 +14,9 @@ "NullValue function", "isNull function", "Lucee" + ], + "categories": [ + "core" ] } --> diff --git a/docs/recipes/overwrite-build-in-functions-tags.md b/docs/recipes/overwrite-build-in-functions-tags.md index 9aecc8370..cebe6c2d3 100644 --- a/docs/recipes/overwrite-build-in-functions-tags.md +++ b/docs/recipes/overwrite-build-in-functions-tags.md @@ -1,6 +1,6 @@ diff --git a/docs/recipes/pdf-engine-flying-saucer.md b/docs/recipes/pdf-engine-flying-saucer.md index 68aac9d9e..6ac6825da 100644 --- a/docs/recipes/pdf-engine-flying-saucer.md +++ b/docs/recipes/pdf-engine-flying-saucer.md @@ -1,6 +1,6 @@ diff --git a/docs/recipes/query-async.md b/docs/recipes/query-async.md index b8ecb2902..97d9d3247 100644 --- a/docs/recipes/query-async.md +++ b/docs/recipes/query-async.md @@ -10,6 +10,12 @@ "listener", "thread", "parallel" + ], + "categories": [ + "query" + ], + "related": [ + "tag-query" ] } --> diff --git a/docs/recipes/query-indexes.md b/docs/recipes/query-indexes.md index bdf3692d0..00e5ee4e6 100644 --- a/docs/recipes/query-indexes.md +++ b/docs/recipes/query-indexes.md @@ -8,6 +8,15 @@ "query", "indexes", "cfquery" + ], + "categories": [ + "query" + ], + "related": [ + "tag-query", + "function-queryrowbyindex", + "function-querygetcellbyindex", + "function-queryrowdatabyindex" ] } --> diff --git a/docs/recipes/query-listener.md b/docs/recipes/query-listener.md index 063d19cc1..7fd0bab0b 100644 --- a/docs/recipes/query-listener.md +++ b/docs/recipes/query-listener.md @@ -10,6 +10,12 @@ "Lucee", "Application.cfc", "component" + ], + "categories": [ + "query" + ], + "related": [ + "tag-query" ] } --> diff --git a/docs/recipes/query-return-type.md b/docs/recipes/query-return-type.md index e0523e5c0..cfd40aeac 100644 --- a/docs/recipes/query-return-type.md +++ b/docs/recipes/query-return-type.md @@ -12,6 +12,9 @@ "Struct return type", "Foreign key", "Lucee" + ], + "related": [ + "tag-query" ] } --> diff --git a/docs/recipes/read-xml-with-a-listener-model-sax.md b/docs/recipes/read-xml-with-a-listener-model-sax.md index 8817e5371..626181fce 100644 --- a/docs/recipes/read-xml-with-a-listener-model-sax.md +++ b/docs/recipes/read-xml-with-a-listener-model-sax.md @@ -11,6 +11,12 @@ "Event Driven", "XML Event Parsing", "XML to Struct" + ], + "categories": [ + "xml" + ], + "related":[ + "function-xmlparse" ] } --> diff --git a/docs/recipes/request-timeout.md b/docs/recipes/request-timeout.md index 19cd0eef2..575b5e670 100644 --- a/docs/recipes/request-timeout.md +++ b/docs/recipes/request-timeout.md @@ -13,6 +13,14 @@ "Application.cfc", "cfsetting", "Threshold" + ], + "categories": [ + "server" + ], + "related":[ + "tag-timeout", + "tag-setting", + "timeout" ] } --> diff --git a/docs/recipes/script-templates.md b/docs/recipes/script-templates.md index 65d0db24e..e753b8d30 100644 --- a/docs/recipes/script-templates.md +++ b/docs/recipes/script-templates.md @@ -9,6 +9,9 @@ "templates", "Lucee", "cfs" + ], + "related": [ + "tag-script" ] } --> diff --git a/docs/recipes/single-vs-multi-mode.md b/docs/recipes/single-vs-multi-mode.md index 948efb724..34a1ccd64 100644 --- a/docs/recipes/single-vs-multi-mode.md +++ b/docs/recipes/single-vs-multi-mode.md @@ -8,6 +8,9 @@ "Single Mode", "Multi Mode", "Configuration" + ], + "categories": [ + "server" ] } --> @@ -32,18 +35,22 @@ Single Mode consolidates all configurations into a single context. This is ideal ## Key Differences ### **Configuration** + - **Multi Mode**: Separate configurations exist for each web context and the server context. Some settings may overlap or conflict, leading to potential confusion. - **Single Mode**: All configurations are unified in a single context. This eliminates ambiguity and simplifies administration, including having only one Lucee Administrator. ### **Logging** + - **Multi Mode**: Logs are divided between web context logs (e.g., request logs) and server context logs (e.g., global actions like tasks). - **Single Mode**: All logs are centralized under the server context, providing a clearer and more streamlined view of system activity. ### **Performance** + - **Multi Mode**: Startup times are longer due to the need to load configurations for multiple web contexts. - **Single Mode**: Faster startup times as only a single configuration is loaded. ### **Future Compatibility** + - **Multi Mode**: While supported in Lucee 6.x, it will be deprecated in Lucee 7. - **Single Mode**: Fully supported in Lucee 6.x and required in Lucee 7, making it the more future-proof choice. @@ -52,21 +59,26 @@ Single Mode consolidates all configurations into a single context. This is ideal You can easily switch between Single Mode and Multi Mode through the Lucee Administrator or directly in the configuration file. ### Using the Lucee Administrator + 1. Go to the overview page. 2. At the top, you can see the current mode with an option to switch to the other mode below it. In Multi Mode, you can also choose to either merge all configurations into one or use only the server configuration. ### Using `.CFConfig.json` + - Add or modify the `mode` flag in the configuration file (.CFConfig.json): + ```json { "mode": "single" } ``` + - Note: Switching via this method does not support merging configurations. ## Why Choose Single Mode? For setups like ours, where multiple web contexts with individual configurations are not needed, Single Mode provides significant benefits: + - **Simplified Configuration**: Easier to manage and eliminates redundant settings. - **Unified Logging**: Clearer and more efficient logging. - **Better Performance**: Faster startup times. diff --git a/docs/recipes/sub-components.md b/docs/recipes/sub-components.md index 79580c067..6be599c2c 100644 --- a/docs/recipes/sub-components.md +++ b/docs/recipes/sub-components.md @@ -1,21 +1,32 @@ -# Sub Component +# Sub Components -Since Lucee 6.0, Lucee allows you to create sub components. These are additional components created in a .cfc after the main component. +Since Lucee 6.0, Lucee allows you to create Sub Components. + +These are additional components created in a `.cfc` after the main component. + +Before this was introduced, CFML was limited to requiring every component to be placed in a separate CFC file. After the main component, simply add as many additional components as you like with the attribute "name" like this: diff --git a/docs/recipes/supercharge-your-website.md b/docs/recipes/supercharge-your-website.md index eaa8d2d32..24661b902 100644 --- a/docs/recipes/supercharge-your-website.md +++ b/docs/recipes/supercharge-your-website.md @@ -9,6 +9,9 @@ "Caching", "Template cache", "Lucee" + ], + "categories": [ + "server" ] } --> diff --git a/docs/recipes/tag-syntax.md b/docs/recipes/tag-syntax.md index 9766ff143..701d41f32 100644 --- a/docs/recipes/tag-syntax.md +++ b/docs/recipes/tag-syntax.md @@ -5,17 +5,22 @@ "id": "tag-syntax", "categories": [ "scopes", - "thread" + "thread", + "core" ], "description": "How to use tags in script", "keywords": [ "Syntax", "tag", "function", - "Script" - "throw" - "abort" + "Script", + "throw", + "abort", "return" + ], + "related": [ + "developing-with-lucee-server", + "tag-script" ] } --> @@ -99,12 +104,15 @@ In this case, the `max` variable is evaluated properly, and the code runs withou ## Exceptions to the rules Because some keywords already existed in script, before support for script tags was added to Lucee, this tags could not be added with migration syntax, because they would conflict with the existing keywords. + This includes the following keywords + - throw - return - abort So for example this code + ```html @@ -113,27 +121,32 @@ So for example this code ``` translates to migration syntax like this (this are not tags) + ```javascript abort "Upsi Dupsi!"; abort; throw "Upsi Dupsi!"; return "Upsi Dupsi!"; ``` + so you can for example not translate this + ```html ``` to migration syntax, but you can to function syntax like this + ```javascript cfthrow (message="Upsi Dupsi!", detail="Upsi dasy!"); ``` - ## Exceptions to Tag-to-Script Migration + Certain tags cannot be directly translated into migration syntax due to conflicts with existing keywords in Lucee’s script language. This applies to tags that use keywords already reserved in script, such as throw, return, and abort. These keywords function differently in script and don’t support direct migration syntax translation. ### Unsupported Migration Syntax for Specific Tags + For example, the following tags in tag syntax: ```html @@ -142,6 +155,7 @@ For example, the following tags in tag syntax: ``` + translate to the following in script syntax (note: these are not actual tags in script but standalone statements): ```javascript @@ -150,15 +164,19 @@ abort; throw "Oops!"; return "Oops!"; ``` + ### Example of Syntax Limitation + Since the throw tag uses additional attributes like message and detail, it cannot be fully expressed in migration syntax. Instead, you’ll need to use function syntax for more complex cases. For example: ```html ``` + would translate to function syntax as follows: ```javascript cfthrow(message="Oops!", detail="More details here."); ``` + Using function syntax here allows you to specify multiple attributes, overcoming the limitations of migration syntax. This flexibility makes function syntax ideal when using tags with additional parameters or complex functionality. diff --git a/docs/recipes/thread-task.md b/docs/recipes/thread-task.md index 34dda69dd..1999a1dbd 100644 --- a/docs/recipes/thread-task.md +++ b/docs/recipes/thread-task.md @@ -1,9 +1,10 @@ -# Thread Task +# Thread Tasks This document explains about the thread tasks. It is useful to know the differences between regular threads and task threads. diff --git a/docs/recipes/thread-usage.md b/docs/recipes/thread-usage.md index 7b022c282..b1a265bf4 100644 --- a/docs/recipes/thread-usage.md +++ b/docs/recipes/thread-usage.md @@ -1,6 +1,6 @@ -# Thread Usage +# Using Threads in Lucee This document explains how to use threads in Lucee. Threads are mainly used for executing code in parallel. +Prior to Lucee 6.2, the thread scope wasn't an actual real scope, which led to some strange behavior, this has been resolved. + ## Example 1 The below example shows normal execution, waiting for all code to resolve. Here it takes 1000 milliseconds to complete the execution. diff --git a/docs/recipes/timeout.md b/docs/recipes/timeout.md index 84ff2c698..a48877c9f 100644 --- a/docs/recipes/timeout.md +++ b/docs/recipes/timeout.md @@ -10,6 +10,9 @@ "Lucee", "cftimeout", "error handling" + ], + "related": [ + "tag-timeout" ] } --> diff --git a/docs/recipes/types-in-lucee.md b/docs/recipes/types-in-lucee.md index 5ed27f9c5..61e163a86 100644 --- a/docs/recipes/types-in-lucee.md +++ b/docs/recipes/types-in-lucee.md @@ -1,6 +1,6 @@ diff --git a/docs/recipes/using-s3-directly-for-source-code.md b/docs/recipes/using-s3-directly-for-source-code.md index 8d215107e..2f91c3a07 100644 --- a/docs/recipes/using-s3-directly-for-source-code.md +++ b/docs/recipes/using-s3-directly-for-source-code.md @@ -3,7 +3,8 @@ "title": "Using S3 directly for source code", "id": "using-s3-directly-for-source-code", "categories": [ - "s3" + "s3", + "server" ], "description": "Using S3 directly for source code", "keywords": [ diff --git a/docs/recipes/websocket-extension.md b/docs/recipes/websocket-extension.md index c806f6bbe..2de8197a9 100644 --- a/docs/recipes/websocket-extension.md +++ b/docs/recipes/websocket-extension.md @@ -3,12 +3,16 @@ "title": "WebSocket Extension", "id": "extension-websocket", "categories": [ - "websocket" + "websocket", + "protocols" ], "description": "How to install, congigure and create WebSockets", "keywords": [ "Lucee", "Extension" + ], + "related": [ + "function-websocketinfo" ] } -->