TryGhost / NQL

MIT License
4 stars 8 forks source link

Better string support (double quotes or escaped singles) #18

Open ErisDS opened 6 years ago

ErisDS commented 6 years ago

NQL works mostly on literals - strings that don't need to be quoted because they are obviously strings.

E.g. tag:photo, we don't need to do tag:'photo', it's totally redundant!

However, if a string contains a character that has another purpose in NQL, we have to use quotes (or escaping) to make it clear the whole thing is intended as a string.

E.g. in a date string published_at:<2017-09-01 12:45:12, both the space and the colons mean that we cannot use a literal, and we need to use quotes e.g. published_at:<'2017-09-01 12:45:12'.

NOTE: should colons be allowed inside of literals?! Or should they be allowed as escaped-chars!??!

This works absolutely wonderfully if the filter lives in a URL encoded URL string, or in JSON, but poses a problem in javascript code:

Example from the prev/next helper in Ghost:

  apiOptions = {
            include: 'author,tags',
            order: 'published_at ' + order,
            limit: 1,
            filter: "slug:-" + slug + "+published_at:" + op + "'" + publishedAt + "'", // jscs:ignore
        }

Normally we would use single quotes around the code, but we can't because this would clash with NQL.

In other languages, you'd switch to using double quotes, but NQL doesn't support this.

If we switch to using template literals:

  apiOptions = {
            filter: `slug:-${slug}+published_at:${op}'${publishedAt}'`, // jscs:ignore
}

The single quotes end up escaped like \' inside the string, which NQL also doesn't seem to understand - or it goes wrong somewhere on the way to NQL - need to test this better to understand what's happening - it definitely should work

TODO:

ErisDS commented 2 years ago

As far as I can tell, everything is working correctly the only thing we don't support is allowing an unescaped double quote in a single-quoted string, this is weird.

Ideally we'd support either quote style, and not require the other quote to be escaped within it.

Beyond that, it's possible to escape an apostrophe inside a single-quoted string, so we can represent 'john o'nolan'.