2019-04-08 20:38:26 -04:00
#!/usr/bin/env node
/ *
* Licensed to the Apache Software Foundation ( ASF ) under one
* or more contributor license agreements . See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership . The ASF licenses this file
* to you under the Apache License , Version 2.0 ( the
* "License" ) ; you may not use this file except in compliance
* with the License . You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
const fs = require ( 'fs-extra' ) ;
2021-12-22 19:31:17 -05:00
const snarkdown = require ( 'snarkdown' ) ;
2019-06-14 10:53:19 -04:00
2019-08-24 14:35:30 -04:00
const writefile = 'lib/sql-docs.js' ;
2019-04-08 20:38:26 -04:00
2022-08-19 20:12:19 -04:00
const MINIMUM _EXPECTED _NUMBER _OF _FUNCTIONS = 158 ;
2021-07-10 10:56:50 -04:00
const MINIMUM _EXPECTED _NUMBER _OF _DATA _TYPES = 14 ;
2021-12-22 19:31:17 -05:00
function hasHtmlTags ( str ) {
return /<(a|br|span|div|p|code)\/?>/ . test ( str ) ;
2020-07-24 01:45:01 -04:00
}
2021-12-22 19:31:17 -05:00
function sanitizeArguments ( str ) {
str = str . replace ( /`<code>|<\/code>`/g , '|' ) ; // convert the hack to get | in a table to a normal pipe
// Ensure there are no more html tags other than the <code> we just removed
if ( hasHtmlTags ( str ) ) {
throw new Error ( ` Arguments contain HTML: ${ str } ` ) ;
}
return str ;
}
function convertMarkdownToHtml ( markdown ) {
markdown = markdown . replace ( /<br\/?>/g , '\n' ) ; // Convert inline <br> to newlines
// Ensure there are no more html tags other than the <br> we just removed
if ( hasHtmlTags ( markdown ) ) {
throw new Error ( ` Markdown contains HTML: ${ markdown } ` ) ;
}
// Concert to markdown
markdown = snarkdown ( markdown ) ;
return markdown
. replace ( /<br \/>/g , '<br /><br />' ) // Double up the <br>s
. replace ( /<a[^>]*>(.*?)<\/a>/g , '$1' ) ; // Remove links
2021-08-30 01:04:35 -04:00
}
2019-06-21 00:14:54 -04:00
const readDoc = async ( ) => {
2022-02-11 17:43:30 -05:00
const data = [
await fs . readFile ( '../docs/querying/sql-data-types.md' , 'utf-8' ) ,
await fs . readFile ( '../docs/querying/sql-scalar.md' , 'utf-8' ) ,
await fs . readFile ( '../docs/querying/sql-aggregations.md' , 'utf-8' ) ,
await fs . readFile ( '../docs/querying/sql-multivalue-string-functions.md' , 'utf-8' ) ,
2022-08-19 20:12:19 -04:00
await fs . readFile ( '../docs/querying/sql-json-functions.md' , 'utf-8' ) ,
2022-02-11 17:43:30 -05:00
await fs . readFile ( '../docs/querying/sql-operators.md' , 'utf-8' ) ,
] . join ( '\n' ) ;
2019-06-21 00:14:54 -04:00
const lines = data . split ( '\n' ) ;
2021-12-22 19:31:17 -05:00
const functionDocs = { } ;
2022-08-24 19:17:12 -04:00
const dataTypeDocs = { } ;
2019-06-21 00:14:54 -04:00
for ( let line of lines ) {
2021-08-30 17:36:23 -04:00
const functionMatch = line . match ( /^\|\s*`(\w+)\(([^|]*)\)`\s*\|([^|]+)\|(?:([^|]+)\|)?$/ ) ;
2019-06-21 00:14:54 -04:00
if ( functionMatch ) {
2021-12-22 19:31:17 -05:00
const functionName = functionMatch [ 1 ] ;
const args = sanitizeArguments ( functionMatch [ 2 ] ) ;
const description = convertMarkdownToHtml ( functionMatch [ 3 ] ) ;
functionDocs [ functionName ] = functionDocs [ functionName ] || [ ] ;
functionDocs [ functionName ] . push ( [ args , description ] ) ;
2019-06-21 00:14:54 -04:00
}
2021-07-10 10:56:50 -04:00
const dataTypeMatch = line . match ( /^\|([A-Z]+)\|([A-Z]+)\|([^|]*)\|([^|]*)\|$/ ) ;
2019-06-21 00:14:54 -04:00
if ( dataTypeMatch ) {
2022-08-24 19:17:12 -04:00
dataTypeDocs [ dataTypeMatch [ 1 ] ] = [ dataTypeMatch [ 2 ] , convertMarkdownToHtml ( dataTypeMatch [ 4 ] ) ] ;
2019-06-21 00:14:54 -04:00
}
}
2021-07-10 10:56:50 -04:00
// Make sure there are enough functions found
2021-12-22 19:31:17 -05:00
const numFunction = Object . keys ( functionDocs ) . length ;
if ( numFunction < MINIMUM _EXPECTED _NUMBER _OF _FUNCTIONS ) {
2019-06-26 18:50:48 -04:00
throw new Error (
2021-12-22 19:31:17 -05:00
` Did not find enough function entries did the structure of ' ${ readfile } ' change? (found ${ numFunction } but expected at least ${ MINIMUM _EXPECTED _NUMBER _OF _FUNCTIONS } ) ` ,
2019-06-26 18:50:48 -04:00
) ;
2019-06-21 00:14:54 -04:00
}
2020-12-01 16:16:14 -05:00
// Make sure there are at least 10 data types for sanity
2021-12-22 19:31:17 -05:00
const numDataTypes = dataTypeDocs . length ;
if ( numDataTypes < MINIMUM _EXPECTED _NUMBER _OF _DATA _TYPES ) {
2019-06-26 18:50:48 -04:00
throw new Error (
2021-12-22 19:31:17 -05:00
` Did not find enough data type entries did the structure of ' ${ readfile } ' change? (found ${ numDataTypes } but expected at least ${ MINIMUM _EXPECTED _NUMBER _OF _DATA _TYPES } ) ` ,
2019-06-26 18:50:48 -04:00
) ;
2019-06-21 00:14:54 -04:00
}
const content = ` /*
2019-04-08 20:38:26 -04:00
* Licensed to the Apache Software Foundation ( ASF ) under one
* or more contributor license agreements . See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership . The ASF licenses this file
* to you under the Apache License , Version 2.0 ( the
* "License" ) ; you may not use this file except in compliance
* with the License . You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
2019-06-14 10:53:19 -04:00
* /
2019-04-08 20:38:26 -04:00
2019-06-14 10:53:19 -04:00
// This file is auto generated and should not be modified
2019-04-08 20:38:26 -04:00
2019-06-21 19:52:33 -04:00
// prettier-ignore
2019-08-23 16:40:48 -04:00
exports . SQL _DATA _TYPES = $ { JSON . stringify ( dataTypeDocs , null , 2 ) } ;
2019-04-08 20:38:26 -04:00
2019-06-21 19:52:33 -04:00
// prettier-ignore
2019-08-23 16:40:48 -04:00
exports . SQL _FUNCTIONS = $ { JSON . stringify ( functionDocs , null , 2 ) } ;
2019-06-21 00:14:54 -04:00
` ;
2019-04-08 20:38:26 -04:00
2021-12-22 19:31:17 -05:00
console . log ( ` Found ${ numDataTypes } data types and ${ numFunction } functions ` ) ;
2019-06-21 00:14:54 -04:00
await fs . writeFile ( writefile , content , 'utf-8' ) ;
} ;
2019-04-08 20:38:26 -04:00
readDoc ( ) ;