0.1.5 • Published 2 years ago

sqlmacro v0.1.5

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

sqlmacro

This is a stupidly simple template engine for SQL.

The code below

  import { sqlmacro } from 'sqlmacro';
  // or
  const { sqlmacro } = require('sqlmacro');

  const result = sqlmacro`
    params: {flg=false},
    SELECT
    <% if ( flg ) { %>
      cat_name
    <% } else { %>
      dog_name
    <% } %>
    FROM
      animals
  `({ flg: false });
  console.error( result );

generates

    SELECT

      dog_name

    FROM
      animals

The code below

  const result = sqlmacro`
    params: {column_name='cat_name'},
    SELECT
      <%=column_name%>
    FROM
      animals
  `({ column_name: 'dog_name' });

  console.error( result );

generates

    SELECT
      dog_name
    FROM
      animals

Directives

When the first line of the input starts with a hash mark, the macro engine takes it as a directive line.

   #params: foo
   SELECT * FROM users 
   <% if (foo) {%>WHERE id=100<% } %>

A directive line consists colon :. The part before : is taken as a verb of the directive and the other part is taken as its parameters.

Now sqlmacro supports only directive params which are treated as JavaScript`s parameters of the function expression

   #params: a,b=1,c=3
   SELECT * FROM users 
   <% if (c===3) {%>WHERE id=100<% } %>

is compiled to something loosely like :

  ((a,b=1,c=3)=>{
    s='';
    s+='SELECT * FROM users';
    if ( c===3) { s+='WHERE id=100 }
  })

The sqlmacro uses Function class which accepts parameter definitions as arguments; sqlmacro had to parse the expression ( that is a,b=1,c=3 part ). The current parser is far from perfect so use it with care.

If the first line starts with a string params: with any leading spaces, it is also taken as a directive line,too. This is intended to keep backward compatibility; don't use this if you are working with a newly created project, though.

   params: a,b=1,c=3
   SELECT * FROM users 
   <% if (c===3) {%>WHERE id=100<% } %>

DON'T USE THIS MODULE IF YOU DON'T UNDERSTAND WHAT YOU ARE DOING

This module is inherently vulnerable for SQL injection. If it is properly applied, it will reduce your code. But if you are careless for SQL injection, the result is catastrophic.

You most likely to do something like :

  const data = request.json;
  const columns = Object.keys( data );

  const result = sqlmacro`
    params: {columns},
    UPDATE  a_table
           (<%= columns.join(',')       %>)
    VALUES (<%= columns.map(c=>':' + c) %>)
    WHERE
       ...
  `({ data, columns });

  console.error( result );

which appearently gives malicious attackers a widely open door.

You are warned.

If you want to set values which come from outside, you must sanitize your values manually. This module does not do it for you.

I recommend you to apply this module only for conditional generation as you have seen in above; it still gives you an amount of benefit in my oppinion, like the C preprocessor.

About JSP

JSP (Java Server Page) is a old-school technology which is a kind of template engines. It was developped around 2000 and it is still being used today. JSP has gradually lost popularity for years; most people tent to start new projects with modern template engines these days. But it has still some strong points which are missing in modern technologies in 2022.

sqlmacro takes some of syntax from JSP.

Around 2010, I wrote a module which named "JSSP" which syntax was loosely resembling JSP's syntax but its host language is not Java but JavaScript. After that, by my nature, I abandoned the project "JSSP" under a deep nested directory in my harddisk without publishing it to any repositories whicy are available to people; I am just interested in just writing code, not interested in publishing them.

This time I have to write some SQL things due to my personal economical problem; this became a good reason to revibe the project in a reality of 2022.

This module is named after SQL like database things but you can generate whatever you want. Please, just be careful about code injection and don't forget sanitize your parameter values before put them into the macro engine.

I actually use sqlmacro to share code between mjs/cjs so that the files written in .js are converted to both .mjs and *.cjs in which process is totally not related to SQL itself.

Conclusion

That's all. Thank you very much for your attention.

History

  • v0.1.0 released. (Sat, 22 Oct 2022 14:24:45 +0900)
  • v0.1.1 removed unnecessary logging ouputs (Sat, 22 Oct 2022 14:53:06 +0900)
  • v0.1.2 supported dynamic directive lines (Wed, 02 Nov 2022 20:38:29 +0900)
  • v0.1.3 now it can handle ` and \ properly (Wed, 02 Nov 2022 21:35:04 +0900)
  • v0.1.4 updated README.md (Thu, 03 Nov 2022 16:41:35 +0900)
  • v0.1.5 show the content of the script when error (Thu, 03 Nov 2022 18:43:44 +0900)
0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.2

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago