builder.pg avro_schema

This commit is contained in:
msyu
2025-09-13 11:40:16 +03:00
parent 951588a929
commit ab658a5a48
11 changed files with 341 additions and 56 deletions
+87 -21
View File
@@ -37,7 +37,8 @@ order by o.table_type, o.table_name
<!---<cfdump var=#qObj#/>--->
<!--- *** надо ключевые поля выводить первыми --->
<cfquery name="qCol" datasource="#request.DS#">
select c.column_name as name, c.data_type, c.character_maximum_length as max_length, c.is_nullable, c.is_identity
select c.column_name as name, c.data_type, c.character_maximum_length as max_length, c.is_nullable, c.is_identity,
c.numeric_precision, c.numeric_precision_radix, c.numeric_scale
from information_schema.columns c
join information_schema.tables o on (c.table_name=o.table_name AND c.table_schema=o.table_schema)
where o.table_name=<cfqueryparam cfsqltype="cf_sql_varchar" value="#obj#"/>
@@ -84,7 +85,7 @@ AND o.table_schema=<cfqueryparam cfsqltype="cf_sql_varchar" value="#schema#"/>
<input type="checkbox" name="out_all" id="out_all" value="1" onchange="; for (var i=0, checkboxes=document.getElementsByName('out'), n=checkboxes.length; i < n ; i++) {checkboxes[i].checked = this.checked;}" style="margin-right:0;"/>
<label for="out_all">(все)</label>
&nbsp;
<cfloop list="select,update,insert,export,bean,grid,simple_grid,detail,fields_spec,field_set" item="outformat">
<cfloop list="select,update,insert,export,bean,grid,simple_grid,detail,fields_spec,field_set,avro_schema,query_dump" item="outformat">
<cfoutput>
<input type="checkbox" name="out" id="#outformat#" value
="#outformat#"<cfif structKeyExists(form, "out")><cfif listFind(form.out,outformat)> checked</cfif></cfif> style="margin-right:0;"/>
@@ -118,10 +119,10 @@ AND o.table_schema=<cfqueryparam cfsqltype="cf_sql_varchar" value="#schema#"/>
select <cfoutput query="qCol"><cfif listLen(column_list) EQ 0 OR listFind(#column_list#,#name#)>
<cfif comma>,<cfelse> <cfset comma="Yes"/></cfif><cfif len(alias)>#alias#.</cfif>#name#</cfif></cfoutput>
from <cfoutput>#schema#.#obj#<cfif len(alias)> #alias#</cfif></cfoutput>;
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"insert")>
<pre>
@@ -132,10 +133,10 @@ insert into <cfoutput>#schema#.#obj#</cfoutput> (<cfset comma="No"/> <cfoutput q
,<cfelse>
<cfset comma="Yes"/></cfif>&lt;cfqueryparam cfsqltype="#cfSqlType(data_type)#" value="###name###"/&gt;</cfif></cfif></cfoutput>
);
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"export")>
<cfquery name="qExport">
@@ -152,10 +153,10 @@ values
--->'#qExport[qCol.name]#'</cfif></cfloop>)<!---
---><cfif qExport.currentRow LT qExport.recordCount>,</cfif>
</cfoutput>;
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"update")>
<cfset comma="No"/>
@@ -163,10 +164,10 @@ values
update <cfoutput>#obj#</cfoutput> set <cfoutput query="qCol"><cfif !is_identity OR listLen(column_list)><cfif listLen(column_list) EQ 0 OR listFind(#column_list#,#name#)>
<cfif comma>,<cfelse> <cfset comma="Yes"/></cfif>#name#=&lt;cfqueryparam cfsqltype="#cfSqlType(data_type)#" value="###name###"/&gt;</cfif></cfif></cfoutput>
<cfoutput>where #obj#_id=&lt;cfqueryparam cfsqltype="cf_sql_integer" value="###obj#_id##" null=##!isNumeric(#obj#_id)##/&gt;</cfoutput>;
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"bean")>
<pre>
@@ -179,10 +180,10 @@ update <cfoutput>#obj#</cfoutput> set <cfoutput query="qCol"><cfif !is_identity
<cfdefaultcase>&lt;d:param field="#name#" type="#translateDataType(data_type)#"<cfif isStringType(data_type) AND (max_length GT 0)> size="#max_length#" preprocessor=##cleanInput##</cfif><cfif isStringType(data_type) AND (max_length LE 0)> preprocessor=##plain2HtmClean##</cfif><cfif "#name#" EQ "#obj#_id"> key autoincrement<cfelseif is_nullable AND true> forNull=""</cfif><cfif isIntegerType(data_type)> default="0" init="0"</cfif>/&gt;</cfdefaultcase>
</cfswitch></cfif></cfoutput>
&lt;/d:bean&gt;
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"grid")>
<pre>
@@ -199,7 +200,7 @@ update <cfoutput>#obj#</cfoutput> set <cfoutput query="qCol"><cfif !is_identity
&lt;/tr&gt;
&lt;/cfoutput&gt;
&lt;/table&gt;
</pre>
</pre><hr/>
</cfif>
<cfif listFind(form.out,"simple_grid")>
@@ -217,10 +218,10 @@ update <cfoutput>#obj#</cfoutput> set <cfoutput query="qCol"><cfif !is_identity
&lt;/tr&gt;
&lt;/cfoutput&gt;
&lt;/table&gt;
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"detail")>
<pre>
@@ -235,10 +236,10 @@ update <cfoutput>#obj#</cfoutput> set <cfoutput query="qCol"><cfif !is_identity
&lt;/div&gt;
</cfif></cfoutput>
&lt;/div&gt;
</pre>
</pre><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"fields_spec")><!--- webkit bug? it changes order of pre with left curved bracket inside,
minimum sample: 1<pre>{</pre>3 Пытается парсить Error: Parse error on line 1:
@@ -250,9 +251,9 @@ Expecting 'STRING', '}', got 'undefined'--->
<cfset comma="No"/><cfoutput query="qCol"><cfif listLen(column_list) EQ 0 OR listFind(#column_list#,#name#)><cfif comma>
,<cfelse> <cfset comma="Yes"/></cfif>#name#={prefix="#alias#", type="#cfSqlType(data_type)#"}</cfif></cfoutput>
}
</div>
</div><hr/>
</cfif>
<hr/>
<cfif listFind(form.out,"field_set")>
<pre>
@@ -276,10 +277,33 @@ select
---></cfif></cfif></cfoutput>
<cfoutput>&lt;/#tag_prefix#field_set&gt;</cfoutput>
from <cfoutput>#obj#<cfif len(alias)> #alias#</cfif></cfoutput>;
</pre>
</pre><hr/>
</cfif>
<cfif listFind(form.out,"avro_schema")>
<div style="white-space:pre; font-family:monospace;">
{
"type": "record",
"name": <cfoutput>"#obj#"</cfoutput>,
"namespace": "org.apache.nifi",
"fields": [
<cfoutput query="qCol"><!---
---> {"name": "#name#", "type": #avroType(data_type,(is_nullable EQ 'YES'))#}<cfif qCol.currentRow LT qCol.recordCount>,
</cfif></cfoutput>
]
}
</div><hr/>
</cfif>
<cfif listFind(form.out,"query_dump")>
<cfdump var=#qCol#/>
</cfif>
<hr/>
</cfif>
</cfif>
@@ -367,6 +391,48 @@ from <cfoutput>#obj#<cfif len(alias)> #alias#</cfif></cfoutput>;
</cfswitch>
</cffunction>
<!--- https://community.cloudera.com/t5/Support-Questions/PutDatabaseRecord-and-ARRAY-type/m-p/293564 --->
<!--- https://avro.apache.org/docs/1.12.0/specification/ --->
<!--- {
"type": "fixed",
"size": 16,
"logicalType": "uuid"
} --->
<!--- {
"type": "bytes",
"logicalType": "big-decimal"
} --->
<cffunction name="avroType" output="No">
<cfargument name="type" type="string"/>
<cfargument name="nullable" type="boolean" default="true"/>
<cfset var out=""/>
<cfswitch expression=#arguments.type#>
<cfcase value="uuid"><cfset out='{"type": "string", "logicalType": "uuid"}'/></cfcase>
<cfcase value="bit,bool,boolean"><cfset out= '"boolean"'/></cfcase>
<cfcase value="bigint"><cfset out= '"long"'/></cfcase>
<cfcase value="integer,smallilnt,tinyint"><cfset out= '"int"'/></cfcase>
<!--- для простоты мы не пытаемся поддержать указание точности
"type":[{"type": "bytes", "logicalType": "decimal", "precision": 4, "scale": 0} ,"null"] --->
<cfcase value="decimal,numeric"><cfset out= '[{"type":"bytes", "logicalType":"big-decimal"}'/></cfcase>
<cfcase value="real"><cfset out= '"float"'/></cfcase>
<cfcase value="float"><cfset out= '"float"'/></cfcase>
<cfcase value="double"><cfset out= '"double"'/></cfcase>
<cfcase value="char"><cfset out= '"string"'/></cfcase>
<cfcase value="varchar,character varying,text"><cfset out= '"string"'/></cfcase>
<cfcase value="date"><cfset out= '{"type":"int", "logicalType":"date"}'/></cfcase>
<cfcase value="time"><cfset out= '{"type":"int", "logicalType":"time-millis"}'/></cfcase>
<cfcase value="timestamp,timestamptz,timestamp with time zone"><cfset out= '{"type": "long", "logicalType": "local-timestamp-millis"}'/></cfcase>
<cfcase value="array"><cfset out= '{"type":"array", "items":"string", "default": []}'/></cfcase>
<cfdefaultcase><cfset out= "***#arguments.type#***"/></cfdefaultcase>
</cfswitch>
<cfif arguments.nullable>
<cfreturn '[#out#, "null"]'/>
<cfelse>
<cfreturn out/>
</cfif>
</cffunction>
<!--- https://cfdocs.org/cfsqltype-cheatsheet
CF_SQL_* JDBC DB2 Oracle SQL Server
CF_SQL_ARRAY ARRAY N/A N/A N/A