355 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			355 lines
		
	
	
		
			8.8 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (C)2005-2019 Haxe Foundation
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Permission is hereby granted, free of charge, to any person obtaining a
							 | 
						||
| 
								 | 
							
								 * copy of this software and associated documentation files (the "Software"),
							 | 
						||
| 
								 | 
							
								 * to deal in the Software without restriction, including without limitation
							 | 
						||
| 
								 | 
							
								 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
							 | 
						||
| 
								 | 
							
								 * and/or sell copies of the Software, and to permit persons to whom the
							 | 
						||
| 
								 | 
							
								 * Software is furnished to do so, subject to the following conditions:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The above copyright notice and this permission notice shall be included in
							 | 
						||
| 
								 | 
							
								 * all copies or substantial portions of the Software.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						||
| 
								 | 
							
								 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						||
| 
								 | 
							
								 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
							 | 
						||
| 
								 | 
							
								 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						||
| 
								 | 
							
								 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
							 | 
						||
| 
								 | 
							
								 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
							 | 
						||
| 
								 | 
							
								 * DEALINGS IN THE SOFTWARE.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package cs.db;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import sys.db.*;
							 | 
						||
| 
								 | 
							
								import cs.system.data.*;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class AdoNet {
							 | 
						||
| 
								 | 
							
									public static function create(cnx:IDbConnection, dbName:String):Connection {
							 | 
						||
| 
								 | 
							
										return new AdoConnection(cnx, dbName);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private class AdoConnection implements Connection {
							 | 
						||
| 
								 | 
							
									private static var ids = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private var id:Int;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private var cnx:IDbConnection;
							 | 
						||
| 
								 | 
							
									// escape handling
							 | 
						||
| 
								 | 
							
									private var escapeRegex:EReg;
							 | 
						||
| 
								 | 
							
									private var escapes:Array<IDbDataParameter>;
							 | 
						||
| 
								 | 
							
									private var name:String;
							 | 
						||
| 
								 | 
							
									private var command:IDbCommand;
							 | 
						||
| 
								 | 
							
									private var transaction:IDbTransaction;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(cnx, name:String) {
							 | 
						||
| 
								 | 
							
										this.id = cs.system.threading.Interlocked.Increment(ids);
							 | 
						||
| 
								 | 
							
										this.cnx = cnx;
							 | 
						||
| 
								 | 
							
										this.name = name;
							 | 
						||
| 
								 | 
							
										this.escapes = [];
							 | 
						||
| 
								 | 
							
										this.command = cnx.CreateCommand();
							 | 
						||
| 
								 | 
							
										this.escapeRegex = ~/@HX_ESCAPE(\d+)_(\d+)/;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function close():Void {
							 | 
						||
| 
								 | 
							
										cnx.Close();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function escape(s:String):String {
							 | 
						||
| 
								 | 
							
										var param = command.CreateParameter();
							 | 
						||
| 
								 | 
							
										var name = "@HX_ESCAPE" + id + "_" + escapes.push(param) + "";
							 | 
						||
| 
								 | 
							
										param.ParameterName = name;
							 | 
						||
| 
								 | 
							
										param.Value = s;
							 | 
						||
| 
								 | 
							
										return name;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function quote(s:String):String {
							 | 
						||
| 
								 | 
							
										var param = command.CreateParameter();
							 | 
						||
| 
								 | 
							
										var name = "@HX_ESCAPE" + id + "_" + escapes.push(param) + "";
							 | 
						||
| 
								 | 
							
										param.ParameterName = name;
							 | 
						||
| 
								 | 
							
										param.Value = s;
							 | 
						||
| 
								 | 
							
										return name;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function addValue(s:StringBuf, v:Dynamic) {
							 | 
						||
| 
								 | 
							
										if (Std.isOfType(v, Date)) {
							 | 
						||
| 
								 | 
							
											v = Std.string(v);
							 | 
						||
| 
								 | 
							
										} else if (Std.isOfType(v, haxe.io.Bytes)) {
							 | 
						||
| 
								 | 
							
											var bt:haxe.io.Bytes = v;
							 | 
						||
| 
								 | 
							
											v = bt.getData();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										var param = command.CreateParameter();
							 | 
						||
| 
								 | 
							
										var name = "@HX_ESCAPE" + id + "_" + escapes.push(param) + "";
							 | 
						||
| 
								 | 
							
										param.ParameterName = name;
							 | 
						||
| 
								 | 
							
										param.Value = v;
							 | 
						||
| 
								 | 
							
										s.add(name);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function lastInsertId():Int {
							 | 
						||
| 
								 | 
							
										var ret = cnx.CreateCommand();
							 | 
						||
| 
								 | 
							
										ret.CommandText = switch (name) {
							 | 
						||
| 
								 | 
							
											case 'SQLite':
							 | 
						||
| 
								 | 
							
												'SELECT last_insert_rowid()';
							 | 
						||
| 
								 | 
							
											case _:
							 | 
						||
| 
								 | 
							
												'SELECT @@IDENTITY';
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										ret.CommandType = CommandType.Text;
							 | 
						||
| 
								 | 
							
										var r = cast ret.ExecuteScalar();
							 | 
						||
| 
								 | 
							
										ret.Dispose();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										return r;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function dbName():String {
							 | 
						||
| 
								 | 
							
										return name;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function startTransaction():Void {
							 | 
						||
| 
								 | 
							
										if (this.transaction != null)
							 | 
						||
| 
								 | 
							
											throw 'Transaction already active';
							 | 
						||
| 
								 | 
							
										this.transaction = cnx.BeginTransaction();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function commit():Void {
							 | 
						||
| 
								 | 
							
										if (this.transaction == null)
							 | 
						||
| 
								 | 
							
											throw 'No transaction was initiated';
							 | 
						||
| 
								 | 
							
										this.transaction.Commit();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function rollback():Void {
							 | 
						||
| 
								 | 
							
										if (this.transaction == null)
							 | 
						||
| 
								 | 
							
											throw 'No transaction was initiated';
							 | 
						||
| 
								 | 
							
										this.transaction.Rollback();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private static function getFirstStatement(s:String) {
							 | 
						||
| 
								 | 
							
										var buf = new StringBuf();
							 | 
						||
| 
								 | 
							
										var hasData = false;
							 | 
						||
| 
								 | 
							
										var chr = 0, i = 0;
							 | 
						||
| 
								 | 
							
										inline function getch()
							 | 
						||
| 
								 | 
							
											return chr = StringTools.fastCodeAt(s, i++);
							 | 
						||
| 
								 | 
							
										while (!StringTools.isEof(getch())) {
							 | 
						||
| 
								 | 
							
											inline function peek() {
							 | 
						||
| 
								 | 
							
												var c = StringTools.fastCodeAt(s, i);
							 | 
						||
| 
								 | 
							
												if (StringTools.isEof(c))
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												return c;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											switch (chr) {
							 | 
						||
| 
								 | 
							
												case ' '.code | '\t'.code | '\n'.code:
							 | 
						||
| 
								 | 
							
													if (hasData)
							 | 
						||
| 
								 | 
							
														return buf.toString();
							 | 
						||
| 
								 | 
							
												case '-'.code if (peek() == '-'.code):
							 | 
						||
| 
								 | 
							
													if (hasData)
							 | 
						||
| 
								 | 
							
														return buf.toString();
							 | 
						||
| 
								 | 
							
													while (!StringTools.isEof(getch())) {
							 | 
						||
| 
								 | 
							
														if (chr == '\n'.code)
							 | 
						||
| 
								 | 
							
															break;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case '#'.code:
							 | 
						||
| 
								 | 
							
													if (hasData)
							 | 
						||
| 
								 | 
							
														return buf.toString();
							 | 
						||
| 
								 | 
							
													while (!StringTools.isEof(getch())) {
							 | 
						||
| 
								 | 
							
														if (chr == '\n'.code)
							 | 
						||
| 
								 | 
							
															break;
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case '/'.code if (peek() == '*'.code):
							 | 
						||
| 
								 | 
							
													i++;
							 | 
						||
| 
								 | 
							
													if (hasData)
							 | 
						||
| 
								 | 
							
														return buf.toString();
							 | 
						||
| 
								 | 
							
													while (!StringTools.isEof(getch())) {
							 | 
						||
| 
								 | 
							
														if (chr == '*'.code && peek() == '/'.code) {
							 | 
						||
| 
								 | 
							
															i++;
							 | 
						||
| 
								 | 
							
															break;
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												case _:
							 | 
						||
| 
								 | 
							
													hasData = true;
							 | 
						||
| 
								 | 
							
													buf.addChar(chr);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return buf.toString();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function request(s:String):ResultSet {
							 | 
						||
| 
								 | 
							
										var newst = new StringBuf();
							 | 
						||
| 
								 | 
							
										// cycle through the request string, adding any @HX_ESCAPE reference to the command
							 | 
						||
| 
								 | 
							
										var ret:ResultSet = null;
							 | 
						||
| 
								 | 
							
										var r = escapeRegex;
							 | 
						||
| 
								 | 
							
										var myid = id + "", escapes = escapes, elen = escapes.length;
							 | 
						||
| 
								 | 
							
										var cmd = this.command;
							 | 
						||
| 
								 | 
							
										try {
							 | 
						||
| 
								 | 
							
											while (r.match(s)) {
							 | 
						||
| 
								 | 
							
												var id = r.matched(1);
							 | 
						||
| 
								 | 
							
												#if debug
							 | 
						||
| 
								 | 
							
												if (id != myid)
							 | 
						||
| 
								 | 
							
													throw "Request quotes are only valid for one single request; They can't be cached.";
							 | 
						||
| 
								 | 
							
												#end
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												newst.add(r.matchedLeft());
							 | 
						||
| 
								 | 
							
												var eid = Std.parseInt(r.matched(2));
							 | 
						||
| 
								 | 
							
												#if debug
							 | 
						||
| 
								 | 
							
												if (eid == null || eid > elen)
							 | 
						||
| 
								 | 
							
													throw "Invalid request quote ID " + eid;
							 | 
						||
| 
								 | 
							
												#end
							 | 
						||
| 
								 | 
							
												cmd.Parameters.Add(escapes[eid - 1]);
							 | 
						||
| 
								 | 
							
												newst.add(escapes[eid - 1].ParameterName);
							 | 
						||
| 
								 | 
							
												s = r.matchedRight();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											newst.add(s);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											s = newst.toString();
							 | 
						||
| 
								 | 
							
											cmd.CommandText = s;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											var stmt = getFirstStatement(s).toLowerCase();
							 | 
						||
| 
								 | 
							
											if (stmt == 'select') {
							 | 
						||
| 
								 | 
							
												ret = new AdoResultSet(cmd.ExecuteReader());
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												cmd.ExecuteNonQuery();
							 | 
						||
| 
								 | 
							
												ret = EmptyResultSet.empty;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (escapes.length != 0)
							 | 
						||
| 
								 | 
							
												this.escapes = [];
							 | 
						||
| 
								 | 
							
											this.id = cs.system.threading.Interlocked.Increment(ids);
							 | 
						||
| 
								 | 
							
											cmd.Dispose();
							 | 
						||
| 
								 | 
							
											this.command = cnx.CreateCommand();
							 | 
						||
| 
								 | 
							
											return ret;
							 | 
						||
| 
								 | 
							
										} catch (e:Dynamic) {
							 | 
						||
| 
								 | 
							
											if (escapes.length != 0)
							 | 
						||
| 
								 | 
							
												this.escapes = [];
							 | 
						||
| 
								 | 
							
											this.id = cs.system.threading.Interlocked.Increment(ids);
							 | 
						||
| 
								 | 
							
											try {
							 | 
						||
| 
								 | 
							
												cmd.Dispose();
							 | 
						||
| 
								 | 
							
											} catch (e:Dynamic) {}
							 | 
						||
| 
								 | 
							
											this.command = cnx.CreateCommand();
							 | 
						||
| 
								 | 
							
											cs.Lib.rethrow(e);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private class AdoResultSet implements ResultSet {
							 | 
						||
| 
								 | 
							
									public var length(get, null):Int;
							 | 
						||
| 
								 | 
							
									public var nfields(get, null):Int;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private var reader:IDataReader;
							 | 
						||
| 
								 | 
							
									private var didNext:Bool;
							 | 
						||
| 
								 | 
							
									private var names:Array<String>;
							 | 
						||
| 
								 | 
							
									private var types:Array<Class<Dynamic>>;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new(reader) {
							 | 
						||
| 
								 | 
							
										this.reader = reader;
							 | 
						||
| 
								 | 
							
										this.names = [for (i in 0...reader.FieldCount) reader.GetName(i)];
							 | 
						||
| 
								 | 
							
										this.types = [for (i in 0...names.length) cs.Lib.fromNativeType(reader.GetFieldType(i))];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private function get_length() {
							 | 
						||
| 
								 | 
							
										return reader.Depth;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private function get_nfields() {
							 | 
						||
| 
								 | 
							
										return names.length;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function hasNext():Bool {
							 | 
						||
| 
								 | 
							
										didNext = true;
							 | 
						||
| 
								 | 
							
										return reader.Read();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function next():Dynamic {
							 | 
						||
| 
								 | 
							
										if (!didNext && !hasNext())
							 | 
						||
| 
								 | 
							
											return null;
							 | 
						||
| 
								 | 
							
										didNext = false;
							 | 
						||
| 
								 | 
							
										var ret = {}, names = names, types = types;
							 | 
						||
| 
								 | 
							
										for (i in 0...names.length) {
							 | 
						||
| 
								 | 
							
											var name = names[i], t = types[i], val:Dynamic = null;
							 | 
						||
| 
								 | 
							
											if (reader.IsDBNull(i)) {
							 | 
						||
| 
								 | 
							
												val = null;
							 | 
						||
| 
								 | 
							
											} else if (t == cs.system.Single) {
							 | 
						||
| 
								 | 
							
												val = reader.GetDouble(i);
							 | 
						||
| 
								 | 
							
											} else if (t == cs.system.DateTime || t == cs.system.TimeSpan) {
							 | 
						||
| 
								 | 
							
												var d = reader.GetDateTime(i);
							 | 
						||
| 
								 | 
							
												if (d != null)
							 | 
						||
| 
								 | 
							
													val = @:privateAccess Date.fromNative(d);
							 | 
						||
| 
								 | 
							
											} else if (t == cs.system.DBNull) {
							 | 
						||
| 
								 | 
							
												val = null;
							 | 
						||
| 
								 | 
							
											} else if (t == cs.system.Byte) {
							 | 
						||
| 
								 | 
							
												var v2:cs.StdTypes.UInt8 = reader.GetValue(i);
							 | 
						||
| 
								 | 
							
												val = cast(v2, Int);
							 | 
						||
| 
								 | 
							
											} else if (Std.string(t) == 'System.Byte[]') {
							 | 
						||
| 
								 | 
							
												val = haxe.io.Bytes.ofData(reader.GetValue(i));
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												val = reader.GetValue(i);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if (Std.isOfType(val, cs.system.DBNull))
							 | 
						||
| 
								 | 
							
												val = null;
							 | 
						||
| 
								 | 
							
											Reflect.setField(ret, name, val);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return ret;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function results():List<Dynamic> {
							 | 
						||
| 
								 | 
							
										var l = new List();
							 | 
						||
| 
								 | 
							
										while (hasNext())
							 | 
						||
| 
								 | 
							
											l.add(next());
							 | 
						||
| 
								 | 
							
										return l;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getResult(n:Int):String {
							 | 
						||
| 
								 | 
							
										return reader.GetString(n);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getIntResult(n:Int):Int {
							 | 
						||
| 
								 | 
							
										return reader.GetInt32(n);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getFloatResult(n:Int):Float {
							 | 
						||
| 
								 | 
							
										return reader.GetDouble(n);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getFieldsNames():Null<Array<String>> {
							 | 
						||
| 
								 | 
							
										return names;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private class EmptyResultSet implements ResultSet {
							 | 
						||
| 
								 | 
							
									public static var empty = new EmptyResultSet();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function new() {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public var length(get, null):Int;
							 | 
						||
| 
								 | 
							
									public var nfields(get, null):Int;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private function get_length() {
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									private function get_nfields() {
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function hasNext():Bool
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function next():Dynamic
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function results():List<Dynamic>
							 | 
						||
| 
								 | 
							
										return new List();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getResult(n:Int):String
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getIntResult(n:Int):Int
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getFloatResult(n:Int):Float
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									public function getFieldsNames():Null<Array<String>>
							 | 
						||
| 
								 | 
							
										return null;
							 | 
						||
| 
								 | 
							
								}
							 |