001package Torello.Browser;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Java.Additional.*;
013
014import static Torello.Java.Additional.JFlag.*;
015
016import Torello.Java.StrCmpr;
017import Torello.JavaDoc.StaticFunctional;
018import Torello.JavaDoc.JDHeaderBackgroundImg;
019import Torello.JavaDoc.Excuse;
020
021/**
022 * <SPAN CLASS=CopiedJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
023 * 
024 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
025 */
026@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
027@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
028public class Database
029{
030    // ********************************************************************************************
031    // ********************************************************************************************
032    // Class Header Stuff
033    // ********************************************************************************************
034    // ********************************************************************************************
035
036
037    // No Pubic Constructors
038    private Database () { }
039
040    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
041    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
042    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
043    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
044
045    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
046    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
047    // offically, two empty-vectors.  One for String's, and the other for Classes.
048
049    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
050    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
051
052    static
053    {
054        for (Method m : Database.class.getMethods())
055        {
056            // This doesn't work!  The parameter names are all "arg0" ... "argN"
057            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
058            //
059            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
060
061            Vector<Class<?>> parameterTypesList = new Vector<>();
062        
063            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
064
065            parameterTypes.put(
066                m.getName(),
067                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
068            );
069        }
070    }
071
072    static
073    {
074        Vector<String> v = null;
075
076        parameterNames.put("disable", EMPTY_VEC_STR);
077
078        parameterNames.put("enable", EMPTY_VEC_STR);
079
080        v = new Vector<String>(2);
081        parameterNames.put("executeSQL", v);
082        Collections.addAll(v, new String[]
083        { "databaseId", "query", });
084
085        v = new Vector<String>(1);
086        parameterNames.put("getDatabaseTableNames", v);
087        Collections.addAll(v, new String[]
088        { "databaseId", });
089    }
090
091
092    // ********************************************************************************************
093    // ********************************************************************************************
094    // Types - Static Inner Classes
095    // ********************************************************************************************
096    // ********************************************************************************************
097
098    // public static class DatabaseId => String
099    
100    /** Database object. */
101    public static class _Database extends BaseType
102    {
103        /** For Object Serialization.  java.io.Serializable */
104        protected static final long serialVersionUID = 1;
105        
106        public boolean[] optionals()
107        { return new boolean[] { false, false, false, false, }; }
108        
109        /** Database ID. */
110        public final String id;
111        
112        /** Database domain. */
113        public final String domain;
114        
115        /** Database name. */
116        public final String name;
117        
118        /** Database version. */
119        public final String version;
120        
121        /**
122         * Constructor
123         *
124         * @param id Database ID.
125         * 
126         * @param domain Database domain.
127         * 
128         * @param name Database name.
129         * 
130         * @param version Database version.
131         */
132        public _Database(String id, String domain, String name, String version)
133        {
134            // Exception-Check(s) to ensure that if any parameters which are not declared as
135            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
136            
137            if (id == null)      BRDPC.throwNPE("id");
138            if (domain == null)  BRDPC.throwNPE("domain");
139            if (name == null)    BRDPC.throwNPE("name");
140            if (version == null) BRDPC.throwNPE("version");
141            
142            this.id       = id;
143            this.domain   = domain;
144            this.name     = name;
145            this.version  = version;
146        }
147        
148        /**
149         * JSON Object Constructor
150         * @param jo A Json-Object having data about an instance of {@code 'Database'}.
151         */
152        public _Database (JsonObject jo)
153        {
154            this.id       = ReadJSON.getString(jo, "id", false, true);
155            this.domain   = ReadJSON.getString(jo, "domain", false, true);
156            this.name     = ReadJSON.getString(jo, "name", false, true);
157            this.version  = ReadJSON.getString(jo, "version", false, true);
158        }
159        
160    }
161    
162    /** Database error. */
163    public static class Error extends BaseType
164    {
165        /** For Object Serialization.  java.io.Serializable */
166        protected static final long serialVersionUID = 1;
167        
168        public boolean[] optionals()
169        { return new boolean[] { false, false, }; }
170        
171        /** Error message. */
172        public final String message;
173        
174        /** Error code. */
175        public final int code;
176        
177        /**
178         * Constructor
179         *
180         * @param message Error message.
181         * 
182         * @param code Error code.
183         */
184        public Error(String message, int code)
185        {
186            // Exception-Check(s) to ensure that if any parameters which are not declared as
187            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
188            
189            if (message == null) BRDPC.throwNPE("message");
190            
191            this.message  = message;
192            this.code     = code;
193        }
194        
195        /**
196         * JSON Object Constructor
197         * @param jo A Json-Object having data about an instance of {@code 'Error'}.
198         */
199        public Error (JsonObject jo)
200        {
201            this.message  = ReadJSON.getString(jo, "message", false, true);
202            this.code     = ReadJSON.getInt(jo, "code");
203        }
204        
205    }
206    
207    /** <CODE>[No Description Provided by Google]</CODE> */
208    public static class addDatabase extends BrowserEvent
209    {
210        /** For Object Serialization.  java.io.Serializable */
211        protected static final long serialVersionUID = 1;
212        
213        public boolean[] optionals()
214        { return new boolean[] { false, }; }
215        
216        /** <CODE>[No Description Provided by Google]</CODE> */
217        public final Database._Database database;
218        
219        /**
220         * Constructor
221         *
222         * @param database -
223         */
224        public addDatabase(Database._Database database)
225        {
226            super("Database", "addDatabase", 1);
227            
228            // Exception-Check(s) to ensure that if any parameters which are not declared as
229            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
230            
231            if (database == null) BRDPC.throwNPE("database");
232            
233            this.database  = database;
234        }
235        
236        /**
237         * JSON Object Constructor
238         * @param jo A Json-Object having data about an instance of {@code 'addDatabase'}.
239         */
240        public addDatabase (JsonObject jo)
241        {
242            super("Database", "addDatabase", 1);
243        
244            this.database  = ReadJSON.XL.getObject(jo, "database", Database._Database.class, false, true);
245        }
246        
247    }
248    
249    
250    // Counter for keeping the WebSocket Request ID's distinct.
251    private static int counter = 1;
252    
253    /**
254     * Disables database tracking, prevents database events from being sent to the client.
255     * 
256     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
257     * {@link Ret0}&gt;</CODE>
258     *
259     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
260     * browser receives the invocation-request.
261     *
262     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
263     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
264     * {@code >} to ensure the Browser Function has run to completion.
265     */
266    public static Script<String, JsonObject, Ret0> disable()
267    {
268        final int          webSocketID = 19000000 + counter++;
269        final boolean[]    optionals   = new boolean[0];
270        
271        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
272        String requestJSON = WriteJSON.get(
273            parameterTypes.get("disable"),
274            parameterNames.get("disable"),
275            optionals, webSocketID,
276            "Database.disable"
277        );
278        
279        // This Remote Command does not have a Return-Value.
280        return new Script<>
281            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
282    }
283    
284    /**
285     * Enables database tracking, database events will now be delivered to the client.
286     * 
287     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
288     * {@link Ret0}&gt;</CODE>
289     *
290     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
291     * browser receives the invocation-request.
292     *
293     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
294     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
295     * {@code >} to ensure the Browser Function has run to completion.
296     */
297    public static Script<String, JsonObject, Ret0> enable()
298    {
299        final int          webSocketID = 19001000 + counter++;
300        final boolean[]    optionals   = new boolean[0];
301        
302        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
303        String requestJSON = WriteJSON.get(
304            parameterTypes.get("enable"),
305            parameterNames.get("enable"),
306            optionals, webSocketID,
307            "Database.enable"
308        );
309        
310        // This Remote Command does not have a Return-Value.
311        return new Script<>
312            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
313    }
314    
315    /**
316     * <CODE>[No Description Provided by Google]</CODE>
317     * 
318     * @param databaseId -
319     * 
320     * @param query -
321     * 
322     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
323     * {@link Ret3}&gt;</CODE>
324     *
325     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
326     * {@link Script#exec()}), and a {@link Promise} returned.
327     *
328     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
329     * (using {@link Promise#await()}), the {@code Ret3} will subsequently
330     * be returned from that call.
331     * 
332     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
333     * in an instance of <B>{@link Ret3}</B>
334     *
335     * <BR /><BR /><UL CLASS=JDUL>
336     * <LI><CODE><B>Ret3.a:</B> String[] (<B>columnNames</B>)</CODE>
337     *     <BR />-
338     *     <BR /><BR /></LI>
339     * <LI><CODE><B>Ret3.b:</B> JsonArray (<B>values</B>)</CODE>
340     *     <BR />-
341     *     <BR /><BR /></LI>
342     * <LI><CODE><B>Ret3.c:</B> {@link Database.Error} (<B>sqlError</B>)</CODE>
343     *     <BR />-
344     *     </LI>
345     * </UL>
346     */
347    public static Script<String, JsonObject, Ret3<String[], JsonArray, Database.Error>> executeSQL
348        (String databaseId, String query)
349    {
350        // Exception-Check(s) to ensure that if any parameters which are not declared as
351        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
352        
353        if (databaseId == null) BRDPC.throwNPE("databaseId");
354        if (query == null)      BRDPC.throwNPE("query");
355        
356        final int       webSocketID = 19002000 + counter++;
357        final boolean[] optionals   = { false, false, };
358        
359        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
360        String requestJSON = WriteJSON.get(
361            parameterTypes.get("executeSQL"),
362            parameterNames.get("executeSQL"),
363            optionals, webSocketID,
364            "Database.executeSQL",
365            databaseId, query
366        );
367        
368        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret3'
369        Function<JsonObject, Ret3<String[], JsonArray, Database.Error>> 
370            responseProcessor = (JsonObject jo) -> new Ret3<>(
371                (jo.getJsonArray("columnNames") == null)
372                    ? null
373                    : ReadArrJSON.DimN.strArr(jo.getJsonArray("columnNames"), null, 0, String[].class),
374                jo.getJsonArray("values"),
375                ReadJSON.XL.getObject(jo, "sqlError", Database.Error.class, true, false)
376            );
377        
378        // Pass the 'defaultSender' to Script-Constructor
379        // The sender that is used can be changed before executing script.
380        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
381    }
382    
383    /**
384     * <CODE>[No Description Provided by Google]</CODE>
385     * 
386     * @param databaseId -
387     * 
388     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
389     * String[]&gt;</CODE>
390     * 
391     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
392     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
393     * String[]&gt;</CODE> will be returned.
394     *
395     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
396     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
397      * may be retrieved.</I>
398     *
399     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
400     * <BR /><BR /><UL CLASS=JDUL>
401     * <LI><CODE>String[] (<B>tableNames</B></CODE>)
402     *     <BR />-
403     * </LI>
404     * </UL> */
405    public static Script<String, JsonObject, String[]> getDatabaseTableNames(String databaseId)
406    {
407        // Exception-Check(s) to ensure that if any parameters which are not declared as
408        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
409        
410        if (databaseId == null) BRDPC.throwNPE("databaseId");
411        
412        final int       webSocketID = 19003000 + counter++;
413        final boolean[] optionals   = { false, };
414        
415        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
416        String requestJSON = WriteJSON.get(
417            parameterTypes.get("getDatabaseTableNames"),
418            parameterNames.get("getDatabaseTableNames"),
419            optionals, webSocketID,
420            "Database.getDatabaseTableNames",
421            databaseId
422        );
423        
424        // 'JSON Binding' ... Converts Browser Response-JSON to 'String[]'
425        Function<JsonObject, String[]> responseProcessor = (JsonObject jo) ->
426            (jo.getJsonArray("tableNames") == null)
427                ? null
428                : ReadArrJSON.DimN.strArr(jo.getJsonArray("tableNames"), null, 0, String[].class);
429        
430        // Pass the 'defaultSender' to Script-Constructor
431        // The sender that is used can be changed before executing script.
432        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
433    }
434    
435}