diff --git a/core.d b/core.d index 3eca15c..b2814bd 100644 --- a/core.d +++ b/core.d @@ -26,6 +26,23 @@ +/ module arsd.core; + +static if(__traits(compiles, () { import core.interpolation; })) { + import core.interpolation; + + alias InterpolationHeader = core.interpolation.InterpolationHeader; + alias InterpolationFooter = core.interpolation.InterpolationFooter; + alias InterpolatedLiteral = core.interpolation.InterpolatedLiteral; + alias InterpolatedExpression = core.interpolation.InterpolatedExpression; +} else { + // polyfill for old versions + struct InterpolationHeader {} + struct InterpolationFooter {} + struct InterpolatedLiteral(string literal) {} + struct InterpolatedExpression(string code) {} +} + + // FIXME: add callbacks on file open for tracing dependencies dynamically // see for useful info: https://devblogs.microsoft.com/dotnet/how-async-await-really-works/ diff --git a/database.d b/database.d index 15a188b..7d21c75 100644 --- a/database.d +++ b/database.d @@ -105,6 +105,25 @@ interface Database { return queryImpl(sql, args); } + final ResultSet query(Args...)(arsd.core.InterpolationHeader header, Args args, arsd.core.InterpolationFooter footer) { + import arsd.core; + Variant[] vargs; + string sql; + foreach(arg; args) { + static if(is(typeof(arg) == InterpolatedLiteral!str, string str)) { + sql ~= str; + } else static if(is(typeof(arg) == InterpolatedExpression!str, string str)) { + // intentionally blank + } else static if(is(typeof(arg) == InterpolationHeader) || is(typeof(arg) == InterpolationFooter)) { + static assert(0, "Nested interpolations not allowed at this time"); + } else { + sql ~= "?"; + vargs ~= Variant(arg); + } + } + return queryImpl(sql, vargs); + } + /// turns a systime into a value understandable by the target database as a timestamp to be concated into a query. so it should be quoted and escaped etc as necessary string sysTimeToValue(SysTime); diff --git a/dom.d b/dom.d index 9b36106..3b947fc 100644 --- a/dom.d +++ b/dom.d @@ -122,6 +122,8 @@ bool isConvenientAttribute(string name) { document.parseUtf8("", true, true); // changes the trues to false to switch from xml to html mode --- + You can also modify things like [selfClosedElements] and [rawSourceElements] before calling the `parse` family of functions to do further advanced tasks. + However you parse it, it will put a few things into special variables. [root] contains the root document. @@ -432,8 +434,25 @@ class Document : FileResource, DomParent { History: Added February 8, 2021 (included in dub release 9.2) + + Changed from `string[]` to `immutable(string)[]` on + February 4, 2024 (dub v11.5) to plug a hole discovered + by the OpenD compiler's diagnostics. +/ - string[] selfClosedElements = htmlSelfClosedElements; + immutable(string)[] selfClosedElements = htmlSelfClosedElements; + + /++ + List of elements that contain raw CDATA content for this + document, e.g. ` + my plaintext & stuff + `); + + // please note that if we did `document.toString()` right now, the original source - almost your same + // string you passed to parseStrict - would be spit back out. Meaning the embedded-plaintext still has its + // special text inside it. Another parser won't understand how to use this! So if you want to pass this + // document somewhere else, you need to do some transformations. + // + // This differs from cases like CDATA sections, which dom.d will automatically convert into plain html entities + // on the output that can be read by anyone. + + assert(document.root.tagName == "html"); // the root element is normal + + int foundCount; + // now let's loop through the whole tree + foreach(element; document.root.tree) { + // the asp thing will be in + if(auto asp = cast(AspCode) element) { + // you use the `asp.source` member to get the code for these + assert(asp.source == "% some asp code %"); + foundCount++; + } else if(element.tagName == "script") { + // and for raw source elements - script, style, or the ones you add, + // you use the innerHTML method to get the code inside + assert(element.innerHTML == "embedded && javascript"); + foundCount++; + } else if(element.tagName == "embedded-plaintext") { + // and innerHTML again + assert(element.innerHTML == "my plaintext & stuff"); + foundCount++; + } + + } + + assert(foundCount == 3); + + // writeln(document.toString()); +} + +// FIXME: