static void Main(string[] args)
        {
            #if DEBUG
            // Debug mode only: 12-second pause to allow Visual Studio debugger to attach via "Debug | Attach to Process".
            Thread.Sleep(12000);
            #endif
            // Initialize the Log4Net based logger.
            _logger = new SimpleLogger("QvBigDataConn");
            String log_path = Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "QvBigDataConn");
            if (!Directory.Exists(log_path))
            {
                try
                {
                    Directory.CreateDirectory(log_path);
                }
                catch (Exception)
                {
                    log_path = Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
                }
            }
            _logger.EnableFileLogging(log_path, log4net.Core.Level.Debug);
            _logger.LogMsg(log4net.Core.Level.Debug, "Entering Main() function of connector.");

            try
            {
                //_logger.LogMsg(Level.Debug, String.Format("Application config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.None)));
                //_logger.LogMsg(Level.Debug, String.Format("Roaming user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoaming)));
                //_logger.LogMsg(Level.Debug, String.Format("Local user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal)));
                _logger.LogMsg(Level.Debug, String.Format("Initializing local user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal)));

                // Initialize the User settings from saved config file.
                if (Properties.Settings.Default.UpgradeFromPrevious)
                {
                    // If this is the first time the user has run the app and a previous version exists,
                    // copy in the existing user settings.
                    Properties.Settings.Default.Upgrade();
                    Properties.Settings.Default.UpgradeFromPrevious = false;
                    Properties.Settings.Default.Save();
                }
                if (Properties.Settings.Default.Drivers.Count > 0)
                {
                    _driverName = Properties.Settings.Default.Drivers[0];
                    if (Properties.Settings.Default.LastDriver >= 0 && Properties.Settings.Default.LastDriver <= Properties.Settings.Default.Drivers.Count)
                    {
                        _driverName = Properties.Settings.Default.Drivers[Properties.Settings.Default.LastDriver];
                    }
                }
                _userName = Properties.Settings.Default.User;
                _password = Properties.Settings.Default.Password;

                if( Properties.Settings.Default.MessageWaitMilliseconds > 0 && Properties.Settings.Default.MessageWaitMilliseconds < 60000 )
                {
                    _messageWaitMilliseconds = Properties.Settings.Default.MessageWaitMilliseconds;
                }

            }
            catch (Exception ex)
            {
                 _logger.LogMsg(Level.Error, String.Format("Error initializing User settings: {0}", ex.Message ));
            }

            // Flag to force use of direct named pipe handler instead of "QvxLibrary.dll" objects.
            // We force this to true for now. We may want to allow an option from a configuration setting.
            Boolean _usePipeHandler = true;

            // Check command line arguments.
            // If there are 2, assume we are running as a (hidden) named pipe connector. Else run as a Windows GUI application.
            if (args != null && args.Length >= 2)
            {

                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Running as named pipe connector. Parent window handle = [{0}], QlikView command pipe = [{1}].", args[0].ToString(), args[1].ToString()));

                // Convert window handle (hexadecimal string format) to 32-bit integer.
                int handle = Int32.Parse(args[0].ToString(), System.Globalization.NumberStyles.HexNumber);
                _parentWindowHandle = handle;

                // Full path to command pipe from second argument. This will be formatted as "\\hostname\pipe\mypipename.pip". Hostname ="." if local.
                _commandPipePath = args[1].ToString();

                // For now this flag is always true so we always execute as a raw named pipe handler.
                if (_usePipeHandler)
                {
                    RunNamedPipeHandler(handle, args[1].ToString());
                }
                else
                {
                    // This sets off the QlikView ".NET objects" API.
                    new QvBigDataServer().Run(args[0], args[1]);
                }
            }
            else if (args != null && args.Length == 0)
            {
                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Running as stand-alone."));
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Standalone());
            }

            _logger.LogMsg(Level.Debug, "Exiting program.");
        }
        private IEnumerable <QvxDataRow> GetBillToCodes()
        {
            String tableName   = "BillToCodes";
            String xml_results = "";

            try
            {
                //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "GetBillToCodes()");
                _logger.LogMsg(log4net.Core.Level.Info, "Enter callback function GetBillToCodes()");

                // DEBUGGING: try to connect to named pipe from here.
                //Program.RunNamedPipeHandler(Program._parentWindowHandle, Program._commandQueue, _logger);


                //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, String.Format("GetEvents(log: {0}, tableName: {1})", log, tableName));

                // TO DO: put this back in?
                //VerifyCredentials();

                // TO DO: put in basic validation of query ?
                //if (!EventLog.Exists(log))
                //{
                //    throw new QvxPleaseSendReplyException(QvxResult.QVX_TABLE_NOT_FOUND,
                //        String.Format("There is no EventLog with name: {0}", tableName));
                //}

                // Run the query, get a dataset in XML ?

                // Get the path to the executing program so we can add it to the Java CLASSPATH.
                String local_path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                _logger.LogMsg(log4net.Core.Level.Info, "Working folder: " + local_path);


                //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Opening DotNet-Java bridge.");
                _logger.LogMsg(log4net.Core.Level.Info, "Opening DotNet-Java bridge.");

                var bridgeSetup = new BridgeSetup();
                bridgeSetup.AddAllJarsClassPath(".");
                bridgeSetup.AddAllJarsClassPath(local_path);

                Bridge.CreateJVM(bridgeSetup);
                Bridge.RegisterAssembly(typeof(MojoHiveDriver).Assembly);

                String drivername = "org.apache.hive.jdbc.HiveDriver";
                String url        = "jdbc:hive2://54.218.97.70:21050/;auth=noSasl";
                String username   = "";
                String password   = "";
                String queuename  = "";

                // *** Create the Java proxy class
                //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Creating MojoHiveDriver proxy.");
                _logger.LogMsg(log4net.Core.Level.Info, "Creating MojoHiveDriver proxy.");
                IMojoHiveDriver driver = new MojoHiveDriver();

                // *** Test Cloudera connection
                //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, String.Format("Testing connection: driver={0} | url={1} | queuename={2} | username={3} | password={4}.", drivername, url, queuename, username, password));
                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Testing connection: driver={0} | url={1} | queuename={2} | username={3} | password={4}.", drivername, url, queuename, username, password));
                int result = driver.TestConnection(drivername, url, queuename, username, password);
                if (result == 0)
                {
                    //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Connection successful.");
                    _logger.LogMsg(log4net.Core.Level.Info, "Connection successful.");
                }
                else
                {
                    //QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Connection failed: " + driver.GetLastExceptionMessage());
                    _logger.LogMsg(log4net.Core.Level.Info, "Connection failed: " + driver.GetLastExceptionMessage());
                }

                // *** Run an actual query
                //TO DO: get this from QlikView ? Must use named pipes?
                //String sql = "SELECT * FROM billtocodes WHERE billtocode='3DAKE'";
                //String sql = "SELECT * FROM billtocodes WHERE billtocode LIKE '4P%'";
                String sql = "SELECT * FROM billtocodes WHERE billtoeffdt > '2008-02-01 00:00:00' AND billtoeffdt < '2008-02-28 00:00:00'";

                _logger.LogMsg(log4net.Core.Level.Info, "Running query: " + sql);
                xml_results = driver.QueryResultSetAsXML(drivername, url, queuename, username, password, sql);
                //_logger.LogMsg(log4net.Core.Level.Info, "XML results:\r\n" + xml_results);
            }
            catch (System.Exception ex)
            {
                _logger.LogMsg(log4net.Core.Level.Error, "Fatal exception: " + ex.Message);
            }

            _logger.LogMsg(log4net.Core.Level.Info, "Loading XML into parser." + xml_results);
            System.Xml.XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml_results);
            XmlNode root = doc.FirstChild;

            if (root.HasChildNodes)
            {
                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Query returned {0} rows.", root.ChildNodes.Count.ToString()));

                _logger.LogMsg(log4net.Core.Level.Info, "Moving data from XML to QlikView objects." + xml_results);
                foreach (XmlNode row_node in root.ChildNodes)
                {
                    //Debug.WriteLine(row_node.Name);
                    yield return(MakeEntry(row_node, FindTable(tableName, MTables)));

                    //foreach (XmlNode field_node in row_node.ChildNodes)
                    //{
                    //    Debug.WriteLine(field_node.Name + " = " + field_node.InnerText);
                    //}
                }
            }
            else
            {
                _logger.LogMsg(log4net.Core.Level.Warn, "No rows returned!" + xml_results);
            }
        }
        // Has been hardcoded, should preferably be done programatically.
        public override void Init()
        {
            // Set to true true to get more logging.
            //QvxLog.SetLogLevels(false, false);
            QvxLog.SetLogLevels(true, true);
            QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Init()");

            _logger = new SimpleLogger("QvBigDataConn");
            _logger.EnableFileLogging(Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), log4net.Core.Level.Debug);

            _logger.LogMsg(log4net.Core.Level.Info, "Initializing QlikView API connection class.");

            _logger.LogMsg(log4net.Core.Level.Info, String.Format("Command queue path: [{0}].", Program.CommandPipe));


            VerifyCredentials();

            var billToCodesFields = new QvxField[]
            {
                new QvxField("billtocode", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                new QvxField("billtodesc", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                new QvxField("billtoeffdt", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                new QvxField("billtoexpdt", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
            };

            /*
             * var applicationsEventLogFields = new QvxField[]
             *  {
             *      new QvxField("Category", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("EntryType", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("Message", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("CategoryNumber", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("Index", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("MachineName", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("Source", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("TimeGenerated", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
             *  };
             *
             * var systemEventLogFields = new QvxField[]
             *  {
             *      new QvxField("Category", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("EntryType", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("Message", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("CategoryNumber", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("Index", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("MachineName", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("Source", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
             *      new QvxField("TimeGenerated", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
             *  };
             */
            MTables = new List <QvxTable> {
                new QvxTable {
                    TableName = "BillToCodes",
                    GetRows   = GetBillToCodes,
                    Fields    = billToCodesFields
                }
            };

            /*
             * MTables = new List<QvxTable> {
             *  new QvxTable {
             *      TableName = "ApplicationsEventLog",
             *      GetRows = GetApplicationEvents,
             *      Fields = applicationsEventLogFields
             *  },
             *  new QvxTable {
             *      TableName = "SystemEventLog",
             *      GetRows = GetSystemEvents,
             *      Fields = systemEventLogFields
             *  }
             * };
             */
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
#if DEBUG
            // Debug mode only: 12-second pause to allow Visual Studio debugger to attach via "Debug | Attach to Process".
            Thread.Sleep(12000);
#endif
            // Initialize the Log4Net based logger.
            _logger = new SimpleLogger("QvBigDataConn");
            String log_path = Path.Combine(Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "QvBigDataConn");
            if (!Directory.Exists(log_path))
            {
                try
                {
                    Directory.CreateDirectory(log_path);
                }
                catch (Exception)
                {
                    log_path = Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
                }
            }
            _logger.EnableFileLogging(log_path, log4net.Core.Level.Debug);
            _logger.LogMsg(log4net.Core.Level.Debug, "Entering Main() function of connector.");


            try
            {
                //_logger.LogMsg(Level.Debug, String.Format("Application config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.None)));
                //_logger.LogMsg(Level.Debug, String.Format("Roaming user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoaming)));
                //_logger.LogMsg(Level.Debug, String.Format("Local user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal)));
                _logger.LogMsg(Level.Debug, String.Format("Initializing local user config file: {0}", GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal)));

                // Initialize the User settings from saved config file.
                if (Properties.Settings.Default.UpgradeFromPrevious)
                {
                    // If this is the first time the user has run the app and a previous version exists,
                    // copy in the existing user settings.
                    Properties.Settings.Default.Upgrade();
                    Properties.Settings.Default.UpgradeFromPrevious = false;
                    Properties.Settings.Default.Save();
                }
                if (Properties.Settings.Default.Drivers.Count > 0)
                {
                    _driverName = Properties.Settings.Default.Drivers[0];
                    if (Properties.Settings.Default.LastDriver >= 0 && Properties.Settings.Default.LastDriver <= Properties.Settings.Default.Drivers.Count)
                    {
                        _driverName = Properties.Settings.Default.Drivers[Properties.Settings.Default.LastDriver];
                    }
                }
                _userName = Properties.Settings.Default.User;
                _password = Properties.Settings.Default.Password;

                if (Properties.Settings.Default.MessageWaitMilliseconds > 0 && Properties.Settings.Default.MessageWaitMilliseconds < 60000)
                {
                    _messageWaitMilliseconds = Properties.Settings.Default.MessageWaitMilliseconds;
                }
            }
            catch (Exception ex)
            {
                _logger.LogMsg(Level.Error, String.Format("Error initializing User settings: {0}", ex.Message));
            }


            // Flag to force use of direct named pipe handler instead of "QvxLibrary.dll" objects.
            // We force this to true for now. We may want to allow an option from a configuration setting.
            Boolean _usePipeHandler = true;


            // Check command line arguments.
            // If there are 2, assume we are running as a (hidden) named pipe connector. Else run as a Windows GUI application.
            if (args != null && args.Length >= 2)
            {
                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Running as named pipe connector. Parent window handle = [{0}], QlikView command pipe = [{1}].", args[0].ToString(), args[1].ToString()));

                // Convert window handle (hexadecimal string format) to 32-bit integer.
                int handle = Int32.Parse(args[0].ToString(), System.Globalization.NumberStyles.HexNumber);
                _parentWindowHandle = handle;

                // Full path to command pipe from second argument. This will be formatted as "\\hostname\pipe\mypipename.pip". Hostname ="." if local.
                _commandPipePath = args[1].ToString();

                // For now this flag is always true so we always execute as a raw named pipe handler.
                if (_usePipeHandler)
                {
                    RunNamedPipeHandler(handle, args[1].ToString());
                }
                else
                {
                    // This sets off the QlikView ".NET objects" API.
                    new QvBigDataServer().Run(args[0], args[1]);
                }
            }
            else if (args != null && args.Length == 0)
            {
                _logger.LogMsg(log4net.Core.Level.Info, String.Format("Running as stand-alone."));
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Standalone());
            }

            _logger.LogMsg(Level.Debug, "Exiting program.");
        }
Ejemplo n.º 5
0
        public static IMojoHiveDriver CreateCustomDriver(String drivername)
        {
            IMojoHiveDriver driver = null;

            try
            {
                String local_path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                _logger.LogMsg(log4net.Core.Level.Debug, "Connector program folder: " + local_path);

                _logger.LogMsg(log4net.Core.Level.Debug, "Creating .NET-Java bridge.");
                var bridgeSetup = new BridgeSetup();

                // The local_path is the folder where the connector EXE itself is located.
                bridgeSetup.AddAllJarsClassPath(local_path);

                // Check to see if a specific folder has been configured as the location for the current driver.
                // If so, load all JARs in that folder.
                String  driver_folder    = "";
                Boolean found_the_folder = false;
                try
                {
                    if (Properties.Settings.Default.Drivers.Contains(drivername))
                    {
                        int driver_index = Properties.Settings.Default.Drivers.IndexOf(drivername);

                        if (Properties.Settings.Default.DriverLocations.Count > driver_index)
                        {
                            driver_folder = Properties.Settings.Default.DriverLocations[driver_index];
                            // First assume the folder is a full path, check if it exists.
                            if (Directory.Exists(driver_folder))
                            {
                                found_the_folder = true;
                            }
                            else
                            {
                                // Try to append to the driver folder to the current local EXE path as a sub-folder.
                                driver_folder = Path.Combine(local_path, driver_folder);
                                if (Directory.Exists(driver_folder))
                                {
                                    found_the_folder = true;
                                }
                            }
                            // Always try to add the folder if it exists.
                            if (found_the_folder)
                            {
                                bridgeSetup.AddAllJarsClassPath(driver_folder);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogMsg(Level.Warn, String.Format("Error adding custom driver folder [{0}] to Java CLASSPATH: {1}.", driver_folder, ex.Message));
                }


                _logger.LogMsg(log4net.Core.Level.Debug, "Creating Java virtual machine (JVM).");
                Bridge.CreateJVM(bridgeSetup);

                _logger.LogMsg(log4net.Core.Level.Debug, "Registering custom driver assembly with .NET-Java bridge.");
                Bridge.RegisterAssembly(typeof(MojoHiveDriver).Assembly);

                _logger.LogMsg(log4net.Core.Level.Debug, "Creating custom driver proxy for .NET.");
                driver = new MojoHiveDriver();
            }
            catch (System.Exception ex)
            {
                _logger.LogMsg(log4net.Core.Level.Error, "Error creating MojoHiveDriver proxy: " + ex.Message);
            }

            return(driver);
        }
        // Has been hardcoded, should preferably be done programatically.
        public override void Init()
        {
            // Set to true true to get more logging.
            //QvxLog.SetLogLevels(false, false);
            QvxLog.SetLogLevels(true, true);
            QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Init()");

            _logger = new SimpleLogger("QvBigDataConn");
            _logger.EnableFileLogging(Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), log4net.Core.Level.Debug);

            _logger.LogMsg(log4net.Core.Level.Info, "Initializing QlikView API connection class.");

            _logger.LogMsg(log4net.Core.Level.Info, String.Format("Command queue path: [{0}].", Program.CommandPipe ) );

            VerifyCredentials();

            var billToCodesFields = new QvxField[]
                {
                    new QvxField("billtocode", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("billtodesc", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("billtoeffdt", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("billtoexpdt", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
                };

            /*
            var applicationsEventLogFields = new QvxField[]
                {
                    new QvxField("Category", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("EntryType", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Message", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("CategoryNumber", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Index", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("MachineName", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Source", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("TimeGenerated", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
                };

            var systemEventLogFields = new QvxField[]
                {
                    new QvxField("Category", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("EntryType", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Message", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("CategoryNumber", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Index", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("MachineName", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("Source", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII),
                    new QvxField("TimeGenerated", QvxFieldType.QVX_TEXT, QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, FieldAttrType.ASCII)
                };
            */
            MTables = new List<QvxTable> {
                new QvxTable {
                    TableName = "BillToCodes",
                    GetRows = GetBillToCodes,
                    Fields = billToCodesFields
                }

            };

            /*
            MTables = new List<QvxTable> {
                new QvxTable {
                    TableName = "ApplicationsEventLog",
                    GetRows = GetApplicationEvents,
                    Fields = applicationsEventLogFields
                },
                new QvxTable {
                    TableName = "SystemEventLog",
                    GetRows = GetSystemEvents,
                    Fields = systemEventLogFields
                }
            };
             */
        }