815 lines
34 KiB
Plaintext
815 lines
34 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#ISO-8859-1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"\"\"\"\n",
|
|
"The module PySecondo implements an API for interaction between Python and Secondo. \n",
|
|
"After stablishing connections to Secondo server and Optimizer server reading the cofiguration parameters from a file, \n",
|
|
"the queries canbe executed.\n",
|
|
"\"\"\"\n",
|
|
"\n",
|
|
"import import_ipynb\n",
|
|
"import asyncio\n",
|
|
"import nest_asyncio\n",
|
|
"nest_asyncio.apply()\n",
|
|
"import time\n",
|
|
"\n",
|
|
"from config_pkg.load_secondo_config import *\n",
|
|
"from optimizer_pkg.optimizer_server import *\n",
|
|
"from optimizer_pkg.optimize_query import *\n",
|
|
"from libs_pkg.nested_list import *\n",
|
|
"from libs_pkg.command_execution import *\n",
|
|
"from libs_pkg.exception_handler import *\n",
|
|
"from secondo_datatypes_pkg.secondo_int import *\n",
|
|
"from secondo_datatypes_pkg.secondo_real import *\n",
|
|
"from secondo_datatypes_pkg.Attribute import *\n",
|
|
"from secondo_datatypes_pkg.Tuple import *\n",
|
|
"from secondo_datatypes_pkg.Relation import *\n",
|
|
"\n",
|
|
"\n",
|
|
"class Secondo():\n",
|
|
" \"\"\"\n",
|
|
" This class contains attributes and methods for connecting to a running Secondo server, \n",
|
|
" executing commands and queries, returning the result sets and parsing the results to implemented\n",
|
|
" data structurs in python.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def __init__(self):\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" This constructor which reads from configuration file, connects to secondo server\n",
|
|
" and initialises the object to connect to Optimizer server.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" cfg = Config(\"config_pkg/secondo.cfg\")\n",
|
|
" params = cfg.initialize()\n",
|
|
" self.server = params[0]\n",
|
|
" self.port = params[1]\n",
|
|
" self.user = params[2]\n",
|
|
" self.bin_format = params[6]\n",
|
|
" self.password = params[3]\n",
|
|
" self.initialized = False\n",
|
|
" self.conn = None\n",
|
|
" self.reader = None\n",
|
|
" self.writer = None\n",
|
|
" self.opendb = \"\"\n",
|
|
" #loop = asyncio.get_event_loop()\n",
|
|
" #loop.run_until_complete(self.connect())\n",
|
|
" asyncio.run(self.connect())\n",
|
|
" self.opt = Optimizer(params[4], params[5])\n",
|
|
" self.opt_reader, self.opt_writer = self.opt.get_opt_streams()\n",
|
|
" self.result_error_code = None\n",
|
|
" self.result_error_message = None\n",
|
|
" self.result = []\n",
|
|
" self.stream_result = []\n",
|
|
" \n",
|
|
" async def connect(self):\n",
|
|
" \"\"\"\n",
|
|
" This method connects to Secondo server using asyncio methods and sets the connection, \n",
|
|
" stream- reader and writer attributes of the Secondo class. \n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" if self.initialized == True:\n",
|
|
" raise SecondoAPI_Error('Secondo already initialised.')\n",
|
|
" \n",
|
|
" try:\n",
|
|
" self.conn = asyncio.open_connection(self.server, int(self.port))\n",
|
|
" except ConnectionRefusedError as e:\n",
|
|
" raise SecondoAPI_Error(e.args[1] + ' - Connection to Secondo server refused.')\n",
|
|
" except OSError as e:\n",
|
|
" raise SecondoAPI_Error(e.args[1] + ' - Connection to Secondo couldnt be stablished.')\n",
|
|
" \n",
|
|
" try:\n",
|
|
" self.reader, self.writer = await asyncio.wait_for(self.conn, timeout = 10)\n",
|
|
" except ConnectionRefusedError as e:\n",
|
|
" raise SecondoAPI_Error(e.args[1] + ' - Stream reader and stream writer for Secondo couldnt be initialised.')\n",
|
|
" except OSError as e:\n",
|
|
" raise SecondoAPI_Error(e.args[1] + ' - Stream reader and stream writer for Secondo couldnt be initialised.')\n",
|
|
" \n",
|
|
" \n",
|
|
" message = \"<Connect>\\n\" + self.user + \"\\n\" + self.password + \"\\n\" + \"</Connect>\\n\"\n",
|
|
" \n",
|
|
" while True:\n",
|
|
" line = await self.reader.readline()\n",
|
|
" if not line:\n",
|
|
" raise SecondoAPI_Error('An empty line was read from Secondo - Connection to Server failed.')\n",
|
|
" break\n",
|
|
" line = line.decode()\n",
|
|
" if line != '<SecondoOk/>\\n':\n",
|
|
" #print(f'Received: {line!r}')\n",
|
|
" break\n",
|
|
" \n",
|
|
" if line == '<SecondoOk/>\\n':\n",
|
|
" #print(f'Received: {line}')\n",
|
|
" #print(message)\n",
|
|
" self.writer.write(message.encode())\n",
|
|
" await self.writer.drain()\n",
|
|
" \n",
|
|
" while True:\n",
|
|
" line = await self.reader.readline()\n",
|
|
" \n",
|
|
" if not line:\n",
|
|
" raise SecondoAPI_Error('An empty line was read from Secondo - Connection to Server failed.')\n",
|
|
" break\n",
|
|
"\n",
|
|
" line = line.decode()\n",
|
|
" if line == '<SecondoIntro>\\n':\n",
|
|
" #print(f'Received: {line!r}')\n",
|
|
" while True:\n",
|
|
" line = await self.reader.readline()\n",
|
|
" \n",
|
|
" if not line:\n",
|
|
" raise SecondoAPI_Error('An empty line was read from Secondo - Connection to Server failed.')\n",
|
|
" line = line.decode()\n",
|
|
" \n",
|
|
" if line == '</SecondoIntro>\\n':\n",
|
|
" #print(f'Received: {line!r}')\n",
|
|
" self.initialized = True\n",
|
|
" print(\"Connection To Secondo Server established...\")\n",
|
|
" break\n",
|
|
" \n",
|
|
" elif line == '<SecondoError>\\n':\n",
|
|
" raise SecondoAPI_Error('Error Tag received from Secondo- Connection to Server failed.')\n",
|
|
" #print(f'Received: {line!r}')\n",
|
|
" #else:\n",
|
|
" #print(f'Received: {line!r}')\n",
|
|
" break\n",
|
|
" break \n",
|
|
" #print(self.initialized)\n",
|
|
" \n",
|
|
" \n",
|
|
" \n",
|
|
" async def optimization_check(self, command):\n",
|
|
" \"\"\"\n",
|
|
" This method checks if the query need to be optimized then returns the optimized command \n",
|
|
" by calling the function opt_comm_exec() otherwise returns the unchanged query.\n",
|
|
"\n",
|
|
" :param command: The command or query to be executed.\n",
|
|
" :return: The optimized query.\n",
|
|
" \"\"\"\n",
|
|
" update_comm = False\n",
|
|
" catalog_comm = False\n",
|
|
" select_comm = True\n",
|
|
" if command.startswith('sql') or command.startswith('sql\\n'):\n",
|
|
" update_comm = True\n",
|
|
" elif \"insert into \" in command:\n",
|
|
" update_comm = True\n",
|
|
" elif \"delete from \" in command:\n",
|
|
" update_comm = True\n",
|
|
" elif \"update \" in command:\n",
|
|
" update_comm = True\n",
|
|
" elif \"create table\" in command:\n",
|
|
" update_comm = True\n",
|
|
" catalog_comm = True\n",
|
|
" select_comm = False\n",
|
|
" elif \"drop\" in command:\n",
|
|
" update_comm = True\n",
|
|
" catalog_comm = True\n",
|
|
" select_comm = False \n",
|
|
" elif \"delete\" in command:\n",
|
|
" update_comm = True\n",
|
|
" catalog_comm = True\n",
|
|
" select_comm = False\n",
|
|
" \n",
|
|
" elif \"select\" in command:\n",
|
|
" update_comm = True\n",
|
|
" \n",
|
|
" if update_comm:\n",
|
|
" if len(self.get_opendb()) == 0:\n",
|
|
" raise SecondoError(\"No open Database.\")\n",
|
|
" \n",
|
|
" if not self.opt.get_opt_conn():\n",
|
|
" raise SecondoAPI_Error('Connection to OptimizerServer reset.')\n",
|
|
" \n",
|
|
" if catalog_comm: \n",
|
|
" opt_res = await opt_comm_exec(self.opt_reader, self.opt_writer, command, self.get_opendb(), True)\n",
|
|
" if opt_res:\n",
|
|
" await self.reopen_db()\n",
|
|
" return None\n",
|
|
" else:\n",
|
|
" raise SecondoError(\"Optimization failed.\")\n",
|
|
" elif select_comm:\n",
|
|
" opt_res = await opt_comm_exec(self.opt_reader, self.opt_writer, command, self.get_opendb(), False)\n",
|
|
" if opt_res:\n",
|
|
" return \"query \" + opt_res\n",
|
|
" else:\n",
|
|
" raise SecondoError(\"Optimization failed.\")\n",
|
|
" \n",
|
|
" \n",
|
|
" else:\n",
|
|
" return command\n",
|
|
" \n",
|
|
"\n",
|
|
" \n",
|
|
" async def reopen_db(self):\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" This method closes the currently open database and opens it again. \n",
|
|
" It is needed after executing some query types like catalog updates.\n",
|
|
"\n",
|
|
" :return: True/ False according to the success of operation.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" if len(self.get_opendb()) == 0:\n",
|
|
" return False\n",
|
|
" db = self.get_opendb()\n",
|
|
" \n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.conn is None:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer reset.')\n",
|
|
" res = await self.command_exec(\"close database\")\n",
|
|
" \n",
|
|
" self.set_opendb('')\n",
|
|
" \n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.conn is None:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer reset.')\n",
|
|
" res = await self.command_exec(\"open database \" + db)\n",
|
|
" \n",
|
|
" self.set_opendb(db)\n",
|
|
" return res[0] == 0\n",
|
|
" \n",
|
|
" \n",
|
|
" async def command_exec(self, command, tupel_source = None):\n",
|
|
" \"\"\"\n",
|
|
" This method executes the command/query in three categories (save, restore, general)\n",
|
|
" by calling relevant functions, sets the attributes result_error_code, \n",
|
|
" result_error_message and result of the Secondo object.\n",
|
|
"\n",
|
|
" :param command: The command or query to be executed.\n",
|
|
" :param tupel_source: the source for producing a stream of tupels, needed by queries like pyreceive\n",
|
|
" which send a stream of tuples to Secondo server.\n",
|
|
" :return: the result of command/ query as a python nested list.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" self.result_error_code = None\n",
|
|
" self.result_error_message = None\n",
|
|
" self.result = []\n",
|
|
" self.stream_result = []\n",
|
|
" \n",
|
|
" if 'open database ' in command.lower() and len(self.opendb) > 0:\n",
|
|
" raise SecondoError('A database is already open, close the database before openning a new one.')\n",
|
|
" if 'close database' in command.lower() and len(self.opendb) == 0: \n",
|
|
" raise SecondoError('No database is open.')\n",
|
|
" \n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.conn is None:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer reset.')\n",
|
|
" \n",
|
|
" if not self.opt.get_opt_initialized():\n",
|
|
" raise SecondoAPI_Error('Connection to OptimizerServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.opt.get_opt_conn() is None:\n",
|
|
" raise SecondoAPI_Error('Connection to OptimizerServer reset.')\n",
|
|
" \n",
|
|
" if self.get_sec_streams() is None:\n",
|
|
" raise SecondoAPI_Error('Connection to Secondo Server reset!')\n",
|
|
" \n",
|
|
" command = await self.optimization_check(command)\n",
|
|
" if command:\n",
|
|
" #handliung restore-command\n",
|
|
" if (((command.lstrip()).lower()).startswith('(restore') or ((command.lstrip()).lower()).startswith('( restore') or ((command.lstrip()).lower()).startswith('restore')):\n",
|
|
" \n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.conn is None:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer reset.')\n",
|
|
" \n",
|
|
" result = await restore_command(self.reader, self.writer, self.get_bin_format(), command)\n",
|
|
" self.result_error_code = result[0]\n",
|
|
" self.result_error_message = result[2]\n",
|
|
" self.result = result[3]\n",
|
|
" if result is None:\n",
|
|
" raise SecondoAPI_Error('Command execution returned an empty list.')\n",
|
|
" \n",
|
|
" if result[0] != 0 :\n",
|
|
" raise SecondoError(secondo_errors[result[0]] + ' Command execution was not successful.')\n",
|
|
" \n",
|
|
" if result[0] == 0 :\n",
|
|
" print('Restore was successful.')\n",
|
|
" return result\n",
|
|
" \n",
|
|
" #handliung save-command\n",
|
|
" if (((command.lstrip()).lower()).startswith('(save') or ((command.lstrip()).lower()).startswith('( save') or ((command.lstrip()).lower()).startswith('save')):\n",
|
|
" \n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.conn == None:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer reset.')\n",
|
|
" \n",
|
|
" result = await save_command(self.reader, self.writer, self.get_bin_format(), command)\n",
|
|
" self.result_error_code = result[0]\n",
|
|
" self.result_error_message = result[2]\n",
|
|
" self.result = result[3]\n",
|
|
" if result is None:\n",
|
|
" raise SecondoAPI_Error('Command execution returned an empty list.')\n",
|
|
" \n",
|
|
" if result[0] != 0 :\n",
|
|
" raise SecondoError(secondo_errors[result[0]] + ' Command execution was not successful.')\n",
|
|
" if result[0] == 0 :\n",
|
|
" print('Save was successful.')\n",
|
|
" \n",
|
|
" return result\n",
|
|
" \n",
|
|
" #handling general-commands\n",
|
|
" \n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer has not been initialised.')\n",
|
|
" \n",
|
|
" if self.conn is None:\n",
|
|
" raise SecondoAPI_Error('Connection to ScondoServer reset.')\n",
|
|
" \n",
|
|
" if 'pysend[' in command.lower():\n",
|
|
" result, self.stream_result = await general_command(self.reader, self.writer, self.get_bin_format(), command)\n",
|
|
" \n",
|
|
" if 'pyreceive[' in command.lower():\n",
|
|
" if tupel_source is None:\n",
|
|
" raise SecondoAPI_Error('No Tupel source has been given.')\n",
|
|
" result = await general_command(self.reader, self.writer, self.get_bin_format(), command, stream_source = tupel_source) \n",
|
|
" \n",
|
|
" if not ('pysend[' in command.lower() or 'pyreceive[' in command.lower()):\n",
|
|
" result = await general_command(self.reader, self.writer, self.get_bin_format(), command)\n",
|
|
" \n",
|
|
" self.result_error_code = result[0]\n",
|
|
" self.result_error_message = result[2]\n",
|
|
" self.result = result[3]\n",
|
|
" \n",
|
|
" if result is None:\n",
|
|
" raise SecondoAPI_Error('Command execution returned an empty list.') \n",
|
|
" \n",
|
|
" if result[0] != 0 :\n",
|
|
" print(self.get_result_error_message())\n",
|
|
" raise SecondoError(secondo_errors[result[0]] + ' Command execution was not successful.')\n",
|
|
" \n",
|
|
" if result[0] == 0 :\n",
|
|
" print('Command execution was successful.')\n",
|
|
" \n",
|
|
" if result[0] == 0 and \"open database \" in command:\n",
|
|
" self.set_opendb(command[14:])\n",
|
|
" \n",
|
|
" if result[0] == 0 and \"close database\" in command.lower():\n",
|
|
" self.opendb = ''\n",
|
|
" return result\n",
|
|
" \n",
|
|
" else:\n",
|
|
" return None\n",
|
|
" \n",
|
|
" \n",
|
|
" def close(self):\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" This method closes the connections to Secondo server and consequently to Optimizer server.\n",
|
|
"\n",
|
|
" \"\"\"\n",
|
|
" if not self.initialized:\n",
|
|
" raise SecondoAPI_Error('The connection to Secondo has not been initialised.')\n",
|
|
" self.initialized = False\n",
|
|
" self.opt.close()\n",
|
|
" if self.writer is not None:\n",
|
|
" self.writer.close()\n",
|
|
" if self.conn is not None:\n",
|
|
" self.conn.close()\n",
|
|
" \n",
|
|
" def get_sec_conn(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the connection attribute of Secondo object.\n",
|
|
"\n",
|
|
" :return: The connection attribute of Secondo object.\n",
|
|
" \"\"\"\n",
|
|
" if self.conn is not None:\n",
|
|
" return self.conn\n",
|
|
" else:\n",
|
|
" raise SecondoAPI_Error('No connection to SecondoServer.')\n",
|
|
" \n",
|
|
" def get_sec_streams(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the stream reader/ writer attributes of Secondo object.\n",
|
|
" \n",
|
|
" :return: The stream reader/ writer attributes of Secondo object.\n",
|
|
" \"\"\"\n",
|
|
" if self.reader is not None and self.writer is not None:\n",
|
|
" return self.reader, self.writer\n",
|
|
" else:\n",
|
|
" raise SecondoAPI_Error(\"Connection Error, no open stream reade/writer!\")\n",
|
|
" \n",
|
|
" \n",
|
|
" def get_server(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the server attributes of Secondo object.\n",
|
|
" \n",
|
|
" :return: The server attributes of Secondo object, which consists of an IP-address eg. 127.0.0.0.\n",
|
|
" \"\"\"\n",
|
|
" return self.server\n",
|
|
" \n",
|
|
" def get_port(self):\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" This method returns the port attributes of Secondo object.\n",
|
|
" :return: The port attributes of Secondo object, which consists of an integer number as port eg. 5678.\n",
|
|
" \"\"\"\n",
|
|
" return self.port\n",
|
|
" \n",
|
|
" def get_user(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the user attributes of secondo object.\n",
|
|
" :return: The user attributes of secondo object needed for authentication in Secondo.\n",
|
|
" \"\"\"\n",
|
|
" return self.user\n",
|
|
" \n",
|
|
" def get_password(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the password attributes of secondo object.\n",
|
|
" :return: The password attributes of secondo object, which is given as\n",
|
|
" plain text and needed for authentication in Secondo.\n",
|
|
" \"\"\"\n",
|
|
" return self.password\n",
|
|
" \n",
|
|
" def get_opendb(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the open database attribute of secondo object.\n",
|
|
" :return: The currently open database in Secondo server as string.\n",
|
|
" \"\"\"\n",
|
|
" return self.opendb\n",
|
|
" \n",
|
|
" def get_bin_format(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the format of returned result of queries.\n",
|
|
" :return: True if the result is a nested list in binary formet/ False if in plain text nested list.\n",
|
|
" \"\"\"\n",
|
|
" return self.bin_format\n",
|
|
" \n",
|
|
" \n",
|
|
" def get_opt(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the opt attribute of secondo object.\n",
|
|
" :return: The opt attribute of secondo represents an optimizer object.\n",
|
|
" \"\"\"\n",
|
|
" return self.opt\n",
|
|
" \n",
|
|
" def fetch_result_type(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the result_type attribute of secondo object.\n",
|
|
" :return: The result_type attribute of secondo represents the datatype\n",
|
|
" of result set e.g. int or nested list.\n",
|
|
" \"\"\"\n",
|
|
" if self.result:\n",
|
|
" return self.result[0]\n",
|
|
" return self.result\n",
|
|
" \n",
|
|
" def fetch_result_rows(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the result attribute of secondo object.\n",
|
|
" :return: The result attribute of secondo represents the result as a list.\n",
|
|
" \"\"\"\n",
|
|
" if self.result:\n",
|
|
" if isinstance(self.result[1], list):\n",
|
|
" return self.result[1]\n",
|
|
" else:\n",
|
|
" res = [self.result[1]]\n",
|
|
" return res\n",
|
|
" return self.result\n",
|
|
" \n",
|
|
" def fetch_relation_header(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the header of the relation in result set of secondo object.\n",
|
|
" :return: The header of the relation in result set as a nested list.\n",
|
|
" \"\"\"\n",
|
|
" return self.fetch_result_type()[1][1]\n",
|
|
" \n",
|
|
" def parse_result_to_secondo_int(self):\n",
|
|
" \"\"\"\n",
|
|
" This method parses the integer result of a query and converts it to a secondo_int type.\n",
|
|
" :return: An object of type secondo_int.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" int_result = secondo_int()\n",
|
|
" int_result.in_from_list(self.fetch_result_rows())\n",
|
|
" print('int object: ')\n",
|
|
" print(int_result.get_value())\n",
|
|
" return int_result\n",
|
|
"\n",
|
|
" def parse_result_to_secondo_real(self):\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" This method parses the float result of a query and converts it to a secondo_real type.\n",
|
|
" :return: An object of type secondo_real.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" real_result = secondo_real()\n",
|
|
" real_result.in_from_list(self.fetch_result_rows())\n",
|
|
" print('real object: ')\n",
|
|
" print(real_result.get_value())\n",
|
|
" return real_result\n",
|
|
"\n",
|
|
" def parse_result_to_relation(self):\n",
|
|
" \"\"\"\n",
|
|
" This method parses the relation result of a query and converts it to a Relation type.\n",
|
|
" :return: An object of type Relation.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" header = []\n",
|
|
" for attrib in self.fetch_relation_header():\n",
|
|
" att = Attribute()\n",
|
|
" att.in_from_list(attrib)\n",
|
|
" header.append(att)\n",
|
|
" rel = []\n",
|
|
" rel.append(header)\n",
|
|
" rel.append(self.fetch_result_rows())\n",
|
|
" relation = Relation()\n",
|
|
" relation.in_from_list(rel)\n",
|
|
" print('header: ') \n",
|
|
" for item in relation.get_header():\n",
|
|
" print (item.get_Identifier() + '-' + item.get_type_name() + '-' + item.get_type_class())\n",
|
|
" print(relation.get_tuples())\n",
|
|
" return relation\n",
|
|
"\n",
|
|
" def fetch_result(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the result attribute of the Secondo object.\n",
|
|
" :return: The result attribute of the Secondo object as list.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" return self.result\n",
|
|
" \n",
|
|
" def fetch_stream_result(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the attribute containing the stream of tupels received from\n",
|
|
" Secondo server when the query contains the operator pysend.\n",
|
|
" :return: The stream of tuples collected in a list of tuples after receiving.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" return self.stream_result\n",
|
|
" \n",
|
|
" \n",
|
|
" def parse_stream_result_to_relation(self):\n",
|
|
" \"\"\"\n",
|
|
" This method parses the stream of tuples received from Secondo server\n",
|
|
" when the query contains the operator pysend and converts them to a relation.\n",
|
|
" :return: A Relation containing the stream of tuples received from Secondo server.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" header = []\n",
|
|
" for attrib in self.stream_result[0]:\n",
|
|
" att = Attribute()\n",
|
|
" att.in_from_list(attrib)\n",
|
|
" header.append(att)\n",
|
|
" rel = []\n",
|
|
" rel.append(header)\n",
|
|
" records = []\n",
|
|
" for i in range(1, len(self.stream_result)):\n",
|
|
" records.append(self.stream_result[i])\n",
|
|
" rel.append(records)\n",
|
|
" relation = Relation()\n",
|
|
" relation.in_from_list(rel)\n",
|
|
" print('header: ') \n",
|
|
" for item in relation.get_header():\n",
|
|
" print (item.get_Identifier() + '-' + item.get_type_name() + '-' + item.get_type_class())\n",
|
|
" print(relation.get_tuples())\n",
|
|
" return relation\n",
|
|
" \n",
|
|
" \n",
|
|
" def get_result_error_code(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the result_error_code attribute of the Secondo object.\n",
|
|
" :return: An integer representing the error code after executing a command/ query.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" return self.result_error_code\n",
|
|
" \n",
|
|
" def get_result_error_message(self):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the result_error_message attribute of the Secondo object.\n",
|
|
" :return: A string representing the error message after executing a command/ query.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" return self.result_error_message\n",
|
|
" \n",
|
|
" def set_opendb(self, db):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the opendb attribute of the Secondo object.\n",
|
|
" :return: A string representing the currently open database.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" self.opendb = db\n",
|
|
" \n",
|
|
" def set_bin_format(self, val):\n",
|
|
" \"\"\"\n",
|
|
" This method returns the bin_format attribute of the Secondo object.\n",
|
|
" :return: A Boolean representing the format of received result from Secondo,\n",
|
|
" when True corresponds to Binary nested list, when False textual nested list.\n",
|
|
" \n",
|
|
" \"\"\"\n",
|
|
" self.bin_format = val\n",
|
|
" \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"#scn = Secondo()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"scrolled": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"#com = 'open database berlintest'\n",
|
|
"#com = 'sql select * from staedte where bev > 250000'\n",
|
|
"#com = 'sql select * from staedte'\n",
|
|
"#com = 'query Staedte feed count'\n",
|
|
"#com = 'query Staedte feed filter[(.Bev > 250000)] count'\n",
|
|
"#com = 'sql select * from plz where plz > 50000 '\n",
|
|
"#com = 'query plz feed head[10] consume'\n",
|
|
"#filter[(.PLZ > 50000)]\n",
|
|
"#com = 'query plz feed filter[(.PLZ > 50000)] count'\n",
|
|
"\n",
|
|
"#com = 'query plz feed head[2000] pysend[30000] consume'\n",
|
|
"#com = 'query plz feed head[16] pysend[30000] count'\n",
|
|
"\n",
|
|
"#com = 'let ReviewsSchema1 = [const rel(tuple([Plz: int, Ort: string])) value ()]'\n",
|
|
"#com = 'let Reviews = ReviewsSchema1 pyreceive[30000] consume'\n",
|
|
"#com = 'query Reviews feed consume'\n",
|
|
"#com = 'sql select * from Reviews'\n",
|
|
"\n",
|
|
"\n",
|
|
"#com = 'query [ const rel(tuple([Plz: int, Ort: string])) value() ] pyreceive[30000] count'\n",
|
|
"#com = 'query [ const rel(tuple([Plz: int, Ort: string])) value() ] pyreceive[30000] consume'\n",
|
|
"\n",
|
|
"#com = 'query plz feed head[10] count'\n",
|
|
"#com = 'query Staedte feed filter[(.Bev > 100000)] count'\n",
|
|
"#com = 'query Staedte feed filter[(.Bev > 250000)] {1} consume'\n",
|
|
"#com = 'list algebras'\n",
|
|
"#com = 'list algebra PyStreamAlgebra'\n",
|
|
"#com = 'restore database berlintest from berlintest'\n",
|
|
"#com = 'close database'\n",
|
|
"\n",
|
|
"\n",
|
|
"#com = 'delete ReviewsSchema1'\n",
|
|
"#com = 'delete Reviews'\n",
|
|
"\n",
|
|
"\n",
|
|
"#com = 'query plz feed head[10] count'\n",
|
|
"#Normal case and pysend\n",
|
|
"#t = time.perf_counter()\n",
|
|
"#t = time.process_time()\n",
|
|
"\n",
|
|
"#result = await scn.command_exec(com)\n",
|
|
"\n",
|
|
"#elapsed_time = time.process_time() - t\n",
|
|
"#elapsed_time = time.perf_counter() - t\n",
|
|
"#print('duration: ')\n",
|
|
"#print(elapsed_time)\n",
|
|
"\n",
|
|
"\n",
|
|
"#pyreceive\n",
|
|
"#com = 'let Reviews = ReviewsSchema1 pyreceive[30000] consume'\n",
|
|
"#com = 'query Reviews feed consume'\n",
|
|
"#com = 'sql select * from Reviews'\n",
|
|
"\n",
|
|
"#tupels = [[1059,\"Dresden\"], [1060,\"Dresden\"], [1001,\"Dresden\"], [1002,\"Dresden\"], [1003,\"Dresden\"],[1004,\"Dresden\"],[1005,\"Dresden\"],[1006,\"Dresden\"],[1007,\"Dresden\"],[1008,\"Dresden\"]]\n",
|
|
"#result = await scn.command_exec(com, tupel_source = tupels)\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#print(result)\n",
|
|
"#print(scn.fetch_result())\n",
|
|
"#print(scn.fetch_result_type())\n",
|
|
"#print(scn.fetch_result_rows())\n",
|
|
"#t1 = time.process_time()\n",
|
|
"#for item in scn.fetch_result_rows():\n",
|
|
" #row = item\n",
|
|
"#elapsed_time1 = time.process_time() - t1\n",
|
|
"#print('iteration duration: ')\n",
|
|
"#print(elapsed_time1)\n",
|
|
"\n",
|
|
"\n",
|
|
"#scn.parse_result_to_secondo_int()\n",
|
|
"#scn.parse_result_to_relation()\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"#pysend\n",
|
|
"#for item in scn.fetch_stream_result():\n",
|
|
" #print(item)\n",
|
|
"#scn.parse_stream_result_to_relation()\n",
|
|
"\n",
|
|
" \n",
|
|
"#scn.close()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"\n",
|
|
"#scn.close()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#import pandas as pd\n",
|
|
"#import ast\n",
|
|
"\n",
|
|
"#import io\n",
|
|
"#stream = io.open(\"berlintest\", \"rb\")\n",
|
|
"#print(stream.read())\n",
|
|
"\n",
|
|
"\n",
|
|
"#finding the index of an item in a list\n",
|
|
"#index(...)\n",
|
|
"#L.index(value, [start, [stop]]) -> integer -- return first index of value\n",
|
|
"\n",
|
|
"#\n",
|
|
"#i = iter(lisst)\n",
|
|
"#first = next(i)\n",
|
|
"#rest = list(i)\n",
|
|
"\n",
|
|
"\n",
|
|
"#recursive approach to itterate a nested list of unknown depth and structure\n",
|
|
"#def traverse(o, tree_types=(list, tuple)):\n",
|
|
"# if isinstance(o, tree_types):\n",
|
|
"# for value in o:\n",
|
|
"# for subvalue in traverse(value, tree_types):\n",
|
|
"# yield subvalue\n",
|
|
"# else:\n",
|
|
"# yield o\n",
|
|
"\n",
|
|
"\n",
|
|
"#a = number of inner lists\n",
|
|
"#lst = [[] for _ in range(a)]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.7.4"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|