Exemplo n.º 1
0
class Main:
    """
    Connect to rasserver and run query then return the result to client
    """

    def __init__(self):
        self.validator = Validator()
        self.db_connector = DBConnector(self.validator.server, self.validator.port, self.validator.user, self.validator.passwd)
        self.query_executor = QueryExecutor(self.db_connector)

    def execute(self):
        """
        Execute the query and get the response to client
        """
        # self.query = 'select {33.0, 33.5}'
        # open connection to rasserver
        self.db_connector.open()

        try:
            tmp = self.validator.query.lower().strip()
            if tmp.startswith("select") and "into" not in tmp:
                """ e.g: select c from RAS_COLLECTIONNAMES as c"""
                res = self.query_executor.execute_read(self.validator.query)
            elif self.validator.file:
                # insert or update with file
                """e.g:  rasql -q 'insert into test2 values $1' 
                -f '/home/rasdaman/101.bin' --mdddomain [0:100] --mddtype 'GreyString' --user rasadmin --passwd rasadmin"""
                res = self.query_executor.execute_update_from_file(self.validator.query, self.validator.file,
                                                                   self.validator.mdddomain, self.validator.mddtype)
            else:
                # just normal update query
                """e.g:  rasql -q 'create collection test2 GreySet1' --user rasadmin --passwd rasadmin
                """
                res = self.query_executor.execute_write(self.validator.query)

            res_arr = res

            # Depend on the output (string, file) to write the result from rasserver
            self.__handle_result(res_arr)
        except Exception as e:
            if "error message" in str(e):
                """ e.g: Error executing query 'select stddev_samp(1f)',
                error message 'rasdaman error 353: Execution error 353 in line 1, column 8, near token stddev_samp: Operand.'
                """
                error_message = re.findall(r"([^']*)'?", str(e), re.M)[-2]
                # Write error to stderr
                print_error(error_message)
            else:
                raise
        finally:
            #  Close the connection to rasserver to release rasserver from this client
            self.db_connector.close()
            print("rasql done.")

    def __handle_result(self, res_arr):

        if isinstance(res_arr, QueryResult):
            if res_arr.with_error:
                print_error(res_arr.error_message())
                return

        """
        Handle the result of query from rasserver
        :param list res_arr: list of result which can be MDDArray or scalar values
        :return: it will print output as string if --out string or write to file if --out file
        """
        if self.validator.out == OUTPUT_STRING:
            # Output list of results to console
            self.__handle_result_as_string(res_arr)
        elif self.validator.out == OUTPUT_FILE:
            # Output list of results as files
            self.__handle_result_as_file(res_arr)

    def __handle_result_as_string(self, res_arr):
        """
        When query outputs to string, then create the output for it.
        If query returns scalar, it will look like:
            'select 1' --out string
            Query result collection has 1 element(s):
                Result element 1: 1
        If query returns MDD, it will look like:
            'select encode(c[0:1, 0:2], "csv") from test_mr as c'
            Query result collection has 1 element(s):
                Result object 1: {0,0,0},{0,0,0}
        :param list res_arr: output from rasserver
        """

        output = "Query result collection has {} element(s): \n".format(res_arr.size)
        if res_arr.size > 0:
            for index, res in enumerate(res_arr):
                msg = res_arr.to_string(res) if res_arr.is_object else res
                output += "  Result {} {}: {}\n".format(res_arr.nature, index + 1, msg)
        print(output.strip())

    def __handle_result_as_file(self, res_arr):
        """
        When query outputs to file, then write MDDArray to files
        e.g: rasql -q 'select c[0:1] from test2 as c' --out file with test2 has 5 MDDArray, then it writes to:
        rasql_1.unknown, rasql_2.unknown,...

        NOTE: if it has --outfile PATH_TO_OUTPUT_FILE parameter, then it will write to PATH_TO_OUTPUT_FILE instead
        e.g:  rasql -q 'select c[0:1] from test2 as c'  --out file --outfile /tmp/test1, then it writes to:
        /tmp/test1_1, /tmp/test1_2,...

        :param list res_arr: output from rasserver
        """
        cur_data = self.validator.query.lower()
        if '"png"' in cur_data:
            file_ext = "png"
        elif '"jp2"' in cur_data:
            file_ext = "jp2"
        elif '"jpg"' in cur_data:
            file_ext = "jpg"
        elif '"bmp"' in cur_data:
            file_ext = "bmp"
        elif '"netcdf"' in cur_data:
            file_ext = "nc"
        elif '"json"' in cur_data:
            file_ext = "json"
        elif '"csv"' in cur_data:
            file_ext = "csv"
        elif '"tiff"' in cur_data:
            file_ext = "tif"
        elif '"gtiff"' in cur_data:
            file_ext = "tif"
        else:
            file_ext = "unknown"

        # Only has paramter --out file
        file_name_prefix = "rasql"
        # It has --outfile PATH_TO_FILE parameter
        if self.validator.outfile is not None:
            file_name_prefix = self.validator.outfile

        # Write output results to files
        for i, cur_data in enumerate(res_arr):
            if res_arr.size > 1:
                file_name = file_name_prefix + "_{}.{}".format(i + 1, file_ext)
            else:
                file_name = file_name_prefix + ".{}".format(file_ext)
            if res_arr.is_object:
                with open(file_name, "wb") as binary_file:
                    # If it is MDDArray then write the data inside it
                    binary_file.write(res_arr.to_binary(cur_data))
            else:
                with open(file_name, "w") as text_file:
                    output = "  Result {} {}: {}\n".format(res_arr.nature, i + 1, cur_data)
                    # If it is scalar value then just write it
                    text_file.write(output)
Exemplo n.º 2
0
        query_executor.execute_write("create collection u16s3 UShortSet3")
        q_result = query_executor.execute_query(
            "insert into u16s3 values marray it in [0:0,0:0,0:0] values 0us",
            None)
        if not q_result.error():
            elts = q_result.get_elements()
            oid = elts[0]
            print(f"stored oid :{oid}")
        res = query_executor.execute_read(
            f"select sdom(c) from u16s3 as c where oid(c)={oid}")
        for i in res:
            print(i)
        query_executor.execute_update_from_file(
            f"update u16s3 as c set c[0,*:*,*:*] assign inv_tiff($1) where oid(c)={oid}",
            os.path.join(data_dir, "slice00000.tif"))
        query_executor.execute_update_from_file(
            f"update u16s3 as c set c[1,*:*,*:*] assign inv_tiff($1) where oid(c)={oid}",
            os.path.join(data_dir, "slice00001.tif"))
        res = query_executor.execute_read(
            f"select sdom(c) from u16s3 as c where oid(c)={oid}")
        for i in res:
            print(i)

    query_executor.execute_write("drop collection gs1")
    query_executor.execute_write("drop collection u16s3")
    query_executor.execute_write("drop collection greycube")
    query_executor.execute_write("drop collection mr")
    query_executor.execute_write("drop collection floatcube")

    db_connector.close()