Files
secondo/apis/python2/SecondoAPI/libs_pkg/.ipynb_checkpoints/command_execution-checkpoint.ipynb
2026-01-23 17:03:45 +08:00

325 lines
13 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\"\"\"\n",
"The module command_execution contains three functions to execute three categories of commands and\n",
"return the results by calling other functions in other modules that read and parse the results to\n",
"proper data structures in python.\n",
"\n",
"\"\"\"\n",
"\n",
"import os\n",
"from io import *\n",
"\n",
"import asyncio\n",
"import nest_asyncio\n",
"nest_asyncio.apply()\n",
"import import_ipynb\n",
"from pathlib import Path\n",
"\n",
"from libs_pkg.secondo_results import *\n",
"from libs_pkg.nested_list import *\n",
"from libs_pkg.exception_handler import *\n",
" \n",
"async def restore_command(reader, writer, bin_list, command):\n",
" \"\"\"\n",
" This function executes the commands containing restore keyword and returns the result message.\n",
"\n",
" :param reader: The stream reader of the Secondo object.\n",
" :param writer: The stream writer of the Secondo object.\n",
" :param bin_list: A boolean value for result format of the result list returned from Secondo server.\n",
" :param command: The command to be executed.\n",
" :return: The result received from Secondo by calling the function receive_secondo_response().\n",
" \"\"\"\n",
" \n",
" if reader and writer:\n",
" if not command.startswith('(') :\n",
" command = '(' + command.strip() + ')'\n",
" \n",
" nl_cmd = nl_parse(command, False)\n",
" length = len(nl_cmd)\n",
" if length != 4 and length != 5: \n",
" return None\n",
" if length == 5: #restore database\n",
" if nl_cmd[0] != 'restore' or nl_cmd[1] != 'database' or nl_cmd[3] != 'from':\n",
" return None\n",
" name = nl_cmd[2]\n",
" filename = str(Path.home()) + '/secondo/bin/' + nl_cmd[4]\n",
" database = True\n",
" if length == 4:\n",
" if nl_cmd[0] != 'restore' or nl_cmd[2] != 'from':\n",
" return None\n",
" name = nl_cmd[1]\n",
" filename = str(Path.home()) + '/secondo/bin/' + nl_cmd[3]\n",
" database = False\n",
" \n",
" typ = item_type(filename)\n",
" if not typ in (\"string\", \"symbol\", \"text\"): \n",
" return None\n",
" \n",
" tag = \"DbRestore\" if database else \"ObjectRestore\"\n",
" message = \"<\" + tag + \">\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" \n",
" message = name + \"\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" \n",
" message = \"<FileData>\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" \n",
" with open(filename, \"rb\") as f: \n",
" byte = f.read(1)\n",
" size = 0\n",
" while byte:\n",
" size += 1\n",
" byte = f.read(1)\n",
" \n",
" message = str(size) + \"\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" await writer.drain()\n",
"\n",
" stream = open(filename, 'rb')\n",
" message = stream.read()\n",
" stream.close()\n",
" writer.write(message)\n",
" \n",
" message = \"</FileData>\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" \n",
" message = \"</\" + tag + \">\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" await writer.drain()\n",
"\n",
" try:\n",
" resp = await receive_secondo_response(reader, bin_list)\n",
" except UnexpectedSystemError:\n",
" raise UnexpectedSystemError('Error occured while receiving the result from Secondo.')\n",
"\n",
" if resp[0] == 0:\n",
" print('restore was seccessful!')\n",
" else:\n",
" print(str(resp[0]) + '-' + resp[2])\n",
" raise SecondoError('Error occured during restore.')\n",
" \n",
" return resp\n",
" \n",
" else:\n",
" reader.close()\n",
" writer.close()\n",
" raise SecondoAPI_Error('Connection to Secondo reset.')\n",
" \n",
"\n",
"\n",
"#Command format: save database/<object_name> to <filename> \n",
"async def save_command(reader, writer, bin_list, command):\n",
" \"\"\"\n",
" This function executes the commands containing save keyword and returns the result message.\n",
"\n",
" :param reader: The stream reader of the Secondo object.\n",
" :param writer: The stream writer of the Secondo object.\n",
" :param bin_list: A boolean value for result format of the result list returned from Secondo server.\n",
" :param command: The command to be executed.\n",
" :return: The result received from Secondo by calling the function receive_secondo_response().\n",
" \"\"\"\n",
" \n",
" if reader and writer:\n",
" if not command.startswith('(') :\n",
" command = '(' + command.strip() + ')'\n",
" \n",
" nl_cmd = nl_parse(command, False)\n",
" \n",
" if nl_cmd[0] != 'save' or nl_cmd[2] != 'to':\n",
" print(\"save_command: command wrong\") \n",
" return None\n",
" obj_name = nl_cmd[1]\n",
" filename = nl_cmd[3]\n",
" \n",
" typ = item_type(filename)\n",
" if not typ in (\"string\", \"symbol\", \"text\"):\n",
" print(\"save_command: filename wrong\") \n",
" return None\n",
" \n",
" if obj_name == \"database\":\n",
" writer.write(\"<DbSave/>\\n\".encode())\n",
" else:\n",
" writer.write(\"<ObjectSave>\\n\".encode())\n",
" writer.write((obj_name + \"\\n\").encode())\n",
" writer.write(\"</ObjectSave>\\n\".encode())\n",
" await writer.drain()\n",
" \n",
" try:\n",
" resp = await receive_secondo_response(reader, bin_list)\n",
" except UnexpectedSystemError:\n",
" raise UnexpectedSystemError('Error occured while receiving the result from secondo.')\n",
" if resp:\n",
" if resp[0] == 0:\n",
" stream = open(filename, 'w')\n",
" stream.writelines(resp[3])\n",
" stream.close()\n",
" print('Save Successful!')\n",
" return resp\n",
" \n",
" else:\n",
" raise SecondoAPI_Error('Empty result received from Secondo.')\n",
" \n",
" else:\n",
" reader.close()\n",
" writer.close()\n",
" raise SecondoAPI_Error('Connection to Secondo reset.')\n",
"\n",
"\n",
"async def general_command(reader, writer, bin_list, command, stream_source = None):\n",
" \"\"\"\n",
" This function executes the query-commands and returns the result message.\n",
"\n",
" :param reader: The stream reader of the Secondo object.\n",
" :param writer: The stream writer of the Secondo object.\n",
" :param bin_list: A boolean value for result format of the result list returned from Secondo server.\n",
" :param command: The command to be executed.\n",
" :param stream_source: This is an optional parameter given as a list containning the tuples\n",
" to be sent to Secondo as a stream when the query contains the operator pyreceive[].\n",
" :return: The result received from Secondo by calling the function receive_secondo_response().\n",
" \"\"\"\n",
" \n",
" if reader and writer:\n",
" \n",
" if 'pysend[' in command.lower():\n",
" \n",
" stream = []\n",
" async def handle_Receive_From_Secondo(reader, writer):\n",
" \n",
" count = 0\n",
" while True:\n",
" line = await reader.readline()\n",
" line = line.decode()\n",
" if 'quit' in line:\n",
" break\n",
" \n",
" if line:\n",
" count +=1\n",
" tupel = nl_parse(line, False)\n",
" if count == 1:\n",
" stream.append(tupel[1][1])\n",
" else:\n",
" stream.append(tupel)\n",
" \n",
" print('Stream of {} Tuples received from SecondoServer.'.format(str(count)))\n",
" writer.close()\n",
" \n",
" \n",
" \n",
" idx1 = command.find('pysend[') + 7\n",
" idx2 = command.find(']', int(idx1))\n",
" port = int(command[idx1:idx2])\n",
" \n",
" loop = asyncio.get_event_loop()\n",
" \n",
" try:\n",
" loop.create_task(asyncio.start_server(handle_Receive_From_Secondo, '127.0.0.1', port, reuse_address = True, reuse_port = True))\n",
" except UnexpectedSystemError:\n",
" raise UnexpectedSystemError('Error occured while trying to contact the port to receive stream of tupels.')\n",
" \n",
" if 'pyreceive[' in command.lower():\n",
" \n",
" if stream_source is None:\n",
" raise SecondoAPI_Error('The Tupel source is empty.')\n",
" async def handle_send_to_Secondo(reader, writer, t_source = stream_source):\n",
" \n",
" count = 0\n",
" for tupel in t_source:\n",
" tupel_str = list_to_nl(tupel) + \"\\n\"\n",
" print (tupel_str)\n",
" writer.write(tupel_str.encode())\n",
" await writer.drain()\n",
" count +=1\n",
" \n",
" print('Stream of {} Tuples sent to SecondoServer.'.format(str(count)))\n",
" writer.close()\n",
" \n",
" \n",
" \n",
" idx1 = command.find('pyreceive[') + 10\n",
" idx2 = command.find(']', int(idx1))\n",
" port = int(command[idx1:idx2])\n",
" \n",
" loop = asyncio.get_event_loop()\n",
" \n",
" try:\n",
" #loop.create_task(asyncio.start_server(lambda r, w: handle_send_to_Secondo(r, w, stream_source), '127.0.0.1', port, reuse_address = True, reuse_port = True))\n",
" loop.create_task(asyncio.start_server(handle_send_to_Secondo, '127.0.0.1', port, reuse_address = True, reuse_port = True))\n",
" except UnexpectedSystemError:\n",
" raise UnexpectedSystemError('Error occured while trying to contact the port to send stream of tupels.')\n",
" \n",
" cmd_level = str(0 if ((command.lstrip()).lower()).startswith('(') else 1)\n",
" \n",
" message = \"<Secondo>\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" \n",
" cmd_level += \"\\n\"\n",
" message = cmd_level.encode()\n",
" writer.write(message)\n",
" \n",
" message = command\n",
" message = message.encode()\n",
" writer.write(message)\n",
"\n",
" message = \"\\n</Secondo>\\n\"\n",
" message = message.encode()\n",
" writer.write(message)\n",
" await writer.drain()\n",
" \n",
" \n",
" try:\n",
" result = await receive_secondo_response(reader, bin_list)\n",
" except UnexpectedSystemError:\n",
" raise UnexpectedSystemError('Error occured while receiving the result from Secondo .')\n",
" \n",
" if result and 'pysend[' in command.lower():\n",
" return result, stream\n",
" elif result:\n",
" return result\n",
" else: \n",
" raise SecondoAPI_ERROR('No response received from Secondo.')\n",
" else:\n",
" reader.close()\n",
" writer.close()\n",
" raise SecondoAPI_ERROR('Connection to Secondo reset.')\n",
" \n"
]
}
],
"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
}