Exemple #1
0
def _execute_sql(node: Node, output: Repository) -> ProvenanceLine:
    # Calculate the hash of the layer we are trying to create.
    # Since we handle the "input" hashing in the import step, we don't need to care about the sources here.
    # Later on, we could enhance the caching and base the hash of the command on the hashes of objects that
    # definitely go there as sources.
    if node.expr_name == "sql_file":
        node_contents = extract_nodes(node, ["non_newline"])[0].text
        logging.info("Loading the SQL commands from %s" % node_contents)
        with open(node_contents, "r") as file:
            # Possibly use a different method to calculate the image hash for commands originating from
            # SQL files instead?
            # Don't "canonicalize" it here to get rid of whitespace, just hash the whole file.
            sql_command = file.read()
    else:
        # Support singleline and multiple SQL commands between braces
        nodes = extract_nodes(node, ["non_newline"])
        if not nodes:
            nodes = extract_nodes(node, ["non_curly_brace"])
        sql_command = nodes[0].text.replace("\\{",
                                            "{").replace("\\}", "}").replace(
                                                "\\\\", "\\")

    # Prepare the SQL by rewriting outside image references into LQ schemas
    # Canonicalize the SQL command by formatting it.
    image_mapper = ImageMapper(output.object_engine)
    sql_rewritten, sql_canonical = prepare_splitfile_sql(
        sql_command, image_mapper)

    output_head = output.head_strict.image_hash
    target_hash = _combine_hashes(
        [output_head,
         sha256(sql_canonical.encode("utf-8")).hexdigest()])

    def _calc():
        logging.info("Executing SQL...")
        try:
            image_mapper.setup_lq_mounts()
            output.object_engine.commit()
            sql_to_run = get_singleton(CONFIG, "SG_LQ_TUNING") + sql_rewritten
            logging.debug("Running rewritten SQL %s against %s", sql_to_run,
                          output)
            output.run_sql(sql_to_run)
        finally:
            image_mapper.teardown_lq_mounts()
        output.commit(target_hash, comment=sql_command)

    _checkout_or_calculate_layer(output, target_hash, _calc)
    provenance: ProvenanceLine = {"type": "SQL", "sql": sql_canonical}
    provenance.update(image_mapper.get_provenance_data())
    return provenance
def test_rewrite(source, rewritten, canonical):
    assert prepare_splitfile_sql(source, _mapper) == (rewritten, canonical)
def fails_on_both(sql):
    with pytest.raises(UnsupportedSQLError) as e:
        prepare_splitfile_sql(sql, dummy_mapper)
    with pytest.raises(UnsupportedSQLError) as e:
        validate_import_sql(sql)
def succeeds_on_sql_fails_on_import(sql):
    prepare_splitfile_sql(sql, dummy_mapper)
    with pytest.raises(UnsupportedSQLError) as e:
        validate_import_sql(sql)
def succeeds_on_both(sql):
    prepare_splitfile_sql(sql, dummy_mapper)
    validate_import_sql(sql)