'"', '”' => '"', '—' => '-', ' ' => ' ', ]; $numVersions = []; foreach($iniEntries as $iniEntry) { if(!isset($numVersions[$iniEntry['name']])) $numVersions[$iniEntry['name']] = 0; $numVersions[$iniEntry['name']]++; } // var_dump($numVersions); $sections = $finalEntries = []; foreach($iniEntries as $iniEntry) { if($numVersions[$iniEntry['name']] > 1) { for($i=1; $i<100; $i++) { $section = $iniEntry['name'] . $i; if(!in_array($section, $sections)) { $sections[] = $section; break; } } } else { $section = $iniEntry['name']; $sections[] = $section; } $entry = "[".$section."]".NL; if($section != $iniEntry['name']) { $entry .= "name=".$iniEntry['name'].NL; } $descr = $iniEntry['description']; $descr = strtr($descr, $replaceMap); // Limit description to 50 lines, if the rest is longer than 100 chars $numLinebreaks = 0; $lenDescr = strlen($descr); for($i=0; $i $i + 100) { $descr = substr($descr, 0, $i+1) . ' ...'; break; } } //die(); if($doWordWrap) { $descr = wordwrap($descr); } $descr = str_replace(["\r\n", "\r", "\n"], '\n', $descr); $entry .= "declaration=".$iniEntry['declaration'].NL . "category=".$iniEntry['category'].NL . "description=".html_entity_decode($descr); $finalEntries[$section] = $entry; } ksort($finalEntries); //var_dump($finalEntries); return implode(NL, $finalEntries); } function gen_sqlite(): string { $urls = [ 'Aggregate Functions'=>'https://www.sqlite.org/lang_aggfunc.html', 'Scalar SQL Functions'=>'https://www.sqlite.org/lang_corefunc.html', 'Window Functions' =>'https://www.sqlite.org/windowfunctions.html', ]; $iniEntries = []; foreach($urls as $category=>$url) { //echo $url."\n"; $contents = file_get_contents($url); /* *

sum(X)
total(X)

some text

some text

some text

*/ preg_match_all('#\(.+)\\s*\(.+)\#isU', $contents, $matches); //var_dump($matches); for($i=0; $i', "\n", $matches[1][$i])); //echo $defs."\n\n"; $defs = explode("\n", $defs); foreach($defs as $def) { if(!preg_match('#^(\w+)\(([^\)]*)\)#', $def, $matchesDef)) { continue; } //var_dump($matchesDef); $entry = ['name'=>strtoupper($matchesDef[1]), 'declaration'=>$matchesDef[2], 'category'=>$category]; $descr = $matches[2][$i]; $descr = preg_replace('#\\s*\#', '\\n', $descr); $descr = strip_tags($descr); $descr = preg_replace('#\s+#', ' ', $descr); $entry['description'] = trim($descr); //var_dump($entry); //break(2); $iniEntries[] = $entry; } } //break; } /* * non-parsable date functions: date(time-value, modifier, modifier, ...) time(time-value, modifier, modifier, ...) datetime(time-value, modifier, modifier, ...) julianday(time-value, modifier, modifier, ...) strftime(format, time-value, modifier, modifier, ...) */ $iniEntries[] = [ 'name'=>'DATE', 'declaration'=>'time-value, modifier, modifier, ...', 'category'=>'Date And Time Functions', 'description'=>'All five date and time functions take a time value as an argument. The time value is followed by zero or more modifiers. The strftime() function also takes a format string as its first argument.', ]; $iniEntries[] = [ 'name'=>'TIME', 'declaration'=>'time-value, modifier, modifier, ...', 'category'=>'Date And Time Functions', 'description'=>'All five date and time functions take a time value as an argument. The time value is followed by zero or more modifiers. The strftime() function also takes a format string as its first argument.', ]; $iniEntries[] = [ 'name'=>'DATETIME', 'declaration'=>'time-value, modifier, modifier, ...', 'category'=>'Date And Time Functions', 'description'=>'All five date and time functions take a time value as an argument. The time value is followed by zero or more modifiers. The strftime() function also takes a format string as its first argument.', ]; $iniEntries[] = [ 'name'=>'JULIANDAY', 'declaration'=>'time-value, modifier, modifier, ...', 'category'=>'Date And Time Functions', 'description'=>'All five date and time functions take a time value as an argument. The time value is followed by zero or more modifiers. The strftime() function also takes a format string as its first argument.', ]; $iniEntries[] = [ 'name'=>'STRFTIME', 'declaration'=>'format, time-value, modifier, modifier, ...', 'category'=>'Date And Time Functions', 'description'=>'All five date and time functions take a time value as an argument. The time value is followed by zero or more modifiers. The strftime() function also takes a format string as its first argument.', ]; return finalizeEntries($iniEntries, true); } function gen_mysql(int $port) { // Insert your custom password and port $mysqli = mysqli_connect('localhost', 'root', null, null, $port); $query = mysqli_query($mysqli, "SELECT t.name, t.description, c.name AS categ FROM mysql.help_topic t, mysql.help_category c WHERE t.help_category_id = c.help_category_id AND c.name NOT LIKE 'Internal%' -- and t.name like 'CURRENT_TIMESTAMP' ORDER BY t.name"); if(mysqli_errno($mysqli)) { die ('MySQL connection error: '.mysqli_error($mysqli)); } $iniEntries = []; while($row = mysqli_fetch_object($query)) { $name = $row->name; // Exclude function names with spaces, or other non-word characters: if(!preg_match('#^\w+$#', $name)) { //echo "10\n"; continue; } #echo $name."\n"; $matchCount = preg_match( '#\b'.preg_quote($row->name).'\s?\[?\(([^\)]*)\)[^\r\n]*[\r\n](.*)$#is', $row->description, $matches); if(!$matchCount) { //echo "20\n"; continue; } $declaration = trim($matches[1]); $declaration = preg_replace('#[\r\n]#', ' ', $declaration); $description = trim($matches[2]); if(preg_match('#Description\s+\-+[\r\n](.+)#is', $description, $matchesD)) { $description = trim($matchesD[1]); } //$description = preg_replace('#[\r\n]#', ' ', $description); #echo $row->name."\n".$matches[2]."\n".$matches[3]."\n\n"; $iniEntries[] = [ 'name'=>$row->name, 'declaration'=>$declaration, 'category'=>$row->categ, 'description'=>$description, ]; } return finalizeEntries($iniEntries, false); } function gen_pg(): string { /* * https://www.postgresql.org/docs/current/functions-string.html * *

ascii ( text ) → integer

Returns the numeric code of the first character of the argument. In UTF8 encoding, returns the Unicode code point of the character. In other multibyte encodings, the argument must be an ASCII character.

ascii('x')120

*/ static $categoryUrls = [ 'Numeric/Math Functions' => 'https://www.postgresql.org/docs/current/functions-math.html', 'String Functions' => 'https://www.postgresql.org/docs/current/functions-string.html', 'Binary String Functions' => 'https://www.postgresql.org/docs/current/functions-binarystring.html', 'Bit String Functions' => 'https://www.postgresql.org/docs/current/functions-bitstring.html', 'Date/Time Functions' => 'https://www.postgresql.org/docs/current/functions-datetime.html', 'Enum Support Functions' => 'https://www.postgresql.org/docs/current/functions-enum.html', 'Geometric Functions' => 'https://www.postgresql.org/docs/current/functions-geometry.html', 'Network Address Functions' => 'https://www.postgresql.org/docs/current/functions-net.html', 'Text Search Functions' => 'https://www.postgresql.org/docs/current/functions-textsearch.html', 'JSON Functions' => 'https://www.postgresql.org/docs/current/functions-json.html', 'Sequence Manipulation Functions' => 'https://www.postgresql.org/docs/current/functions-sequence.html', 'Array Functions' => 'https://www.postgresql.org/docs/current/functions-array.html', 'Range Functions' => 'https://www.postgresql.org/docs/current/functions-range.html', 'Aggregate Functions' => 'https://www.postgresql.org/docs/current/functions-aggregate.html', 'Window Functions' => 'https://www.postgresql.org/docs/current/functions-window.html', 'Merge Support Functions' => 'https://www.postgresql.org/docs/current/functions-merge-support.html', 'Session Information Functions' => 'https://www.postgresql.org/docs/current/functions-info.html', 'System Administration Functions' => 'https://www.postgresql.org/docs/current/functions-admin.html', 'Trigger Functions' => 'https://www.postgresql.org/docs/current/functions-trigger.html', 'Statistics Information Functions' => 'https://www.postgresql.org/docs/current/functions-statistics.html', ]; $iniEntries = []; foreach($categoryUrls as $category => $url) { $doc = file_get_contents($url); if(empty($doc)) { throw new RuntimeException("Could not read $url"); } $numMatches = preg_match_all('#

]*>\s*(\w+)\s*\(([^)]*)\).*

\s*

(.+)

#', $doc, $matches); if($numMatches === false) { throw new RuntimeException("Regexp error: ".preg_last_error()); } #var_dump($matches); foreach($matches[1] as $i=>$name) { $iniEntries[] = [ 'name' => strtoupper($name), 'declaration' => trim(strip_tags($matches[2][$i])), 'category' => $category, 'description' => trim(strip_tags($matches[3][$i])), ]; } #break; } return finalizeEntries($iniEntries, true); } // SQLite: # echo gen_sqlite(); // MySQL 5.7: echo gen_mysql(3334); // MySQL 8.3: #echo gen_mysql(3308); // MariaDB 11.7: # echo gen_mysql(3317); // PostgreSQL: #echo gen_pg();