Exemple #1
0
def p_query(t):
    """query : SELECT selector WHERE statement
             | SELECT selector
             | SELECT data_clause WHERE statement
             | DELETE tag_list WHERE statement
             | DELETE WHERE statement
             | SET set_list WHERE statement
             | APPLY apply_statement
             | HELP
             | HELP LVALUE
             """
    if t[1] == 'select': 
        if len(t) == 5:
            t[0] = make_select_rv(t, t[2], t[4].render())
        elif len(t) == 3:
            t[0] = make_select_rv(t, t[2])
        
    elif t[1] == 'delete':
        # a new delete inner statement enforces that we only delete
        # things which we have the key for.
        if t[2] == 'where':
            # delete the whole stream, gone.  this also deletes the
            # data in the backend readingdb.
            t[0] = ext_deletor, \
                """DELETE FROM stream WHERE id IN (
                     SELECT s.id FROM stream s, subscription sub 
                     WHERE (%(restrict)s) AND s.subscription_id = sub.id AND 
                     (%(auth)s)
                   ) RETURNING id, uuid
                """ % { 
                'restrict': t[3].render(),
                'auth': qg.build_authcheck(t.parser.request, forceprivate=True) 
                }
        else:
            # this alters the tags but doesn't touch the data
            del_tags = ', '.join(map(escape_string, t[2]))
            q = "UPDATE stream SET metadata = metadata - ARRAY[" + del_tags + \
                "] WHERE id IN " + \
                "(SELECT s.id FROM stream s, subscription sub " + \
                "WHERE (" + t[4].render() + ") AND s.subscription_id = sub.id AND " + \
                qg.build_authcheck(t.parser.request, forceprivate=True)  + ")"
            t[0] = None, q

    elif t[1] == 'set':
        new_tags = build_setstring(t[2], t[4])
        q = "UPDATE stream SET metadata = metadata || " + new_tags + \
            " WHERE id IN "  + \
            "(SELECT s.id FROM stream s, subscription sub " + \
            "WHERE (" + t[4].render() + ") AND s.subscription_id = sub.id AND " + \
            qg.build_authcheck(t.parser.request, forceprivate=True)  + ")"
        t[0] = None, q

    elif t[1] == 'apply':
        t[0] = t[2]
    elif t[1] == 'help':
        if len(t) == 2:
            t[0] = help.help(), None
        else:
            t[0] = help.help(t[2]), None
Exemple #2
0
def p_query(t):
    """query : SELECT selector WHERE statement
             | SELECT selector
             | SELECT data_clause WHERE statement
             | DELETE tag_list WHERE statement
             | DELETE WHERE statement
             | SET set_list WHERE statement
             | APPLY apply_statement
             | HELP
             | HELP LVALUE
             """
    if t[1] == 'select':
        if len(t) == 5:
            t[0] = make_select_rv(t, t[2], t[4].render())
        elif len(t) == 3:
            t[0] = make_select_rv(t, t[2])

    elif t[1] == 'delete':
        # a new delete inner statement enforces that we only delete
        # things which we have the key for.
        if t[2] == 'where':
            # delete the whole stream, gone.  this also deletes the
            # data in the backend readingdb.
            t[0] = ext_deletor, \
                """DELETE FROM stream WHERE id IN (
                     SELECT s.id FROM stream s, subscription sub 
                     WHERE (%(restrict)s) AND s.subscription_id = sub.id AND 
                     (%(auth)s)
                   ) RETURNING id, uuid
                """ % {
                'restrict': t[3].render(),
                'auth': qg.build_authcheck(t.parser.request, forceprivate=True)
                }
        else:
            # this alters the tags but doesn't touch the data
            del_tags = ', '.join(map(escape_string, t[2]))
            q = "UPDATE stream SET metadata = metadata - ARRAY[" + del_tags + \
                "] WHERE id IN " + \
                "(SELECT s.id FROM stream s, subscription sub " + \
                "WHERE (" + t[4].render() + ") AND s.subscription_id = sub.id AND " + \
                qg.build_authcheck(t.parser.request, forceprivate=True)  + ")"
            t[0] = None, q

    elif t[1] == 'set':
        new_tags = build_setstring(t[2], t[4])
        q = "UPDATE stream SET metadata = metadata || " + new_tags + \
            " WHERE id IN "  + \
            "(SELECT s.id FROM stream s, subscription sub " + \
            "WHERE (" + t[4].render() + ") AND s.subscription_id = sub.id AND " + \
            qg.build_authcheck(t.parser.request, forceprivate=True)  + ")"
        t[0] = None, q

    elif t[1] == 'apply':
        t[0] = t[2]
    elif t[1] == 'help':
        if len(t) == 2:
            t[0] = help.help(), None
        else:
            t[0] = help.help(t[2]), None
Exemple #3
0
def make_delete_rv(t):
    noop = "noop" in t.parser.request.args

    # a new delete inner statement enforces that we only delete
    # things which we have the key for.
    if len(t) > 2 and t[2] == 'where':
        # delete the whole stream, gone.  this also deletes the
        # data in the backend readingdb.
        if not noop:
            statement = "DELETE FROM stream"
            returning = "RETURNING id, uuid"
        else:
            statement = "SELECT uuid FROM stream"
            returning = ""
        return ext_deletor if not noop else ext_default, \
            """%(statement)s WHERE id IN (
                 SELECT s.id FROM stream s, subscription sub 
                 WHERE (%(restrict)s) AND s.subscription_id = sub.id AND 
                 (%(auth)s)
               ) %(returning)s
            """ % {
            'restrict': t[3].render(),
            'auth': qg.build_authcheck(t.parser.request, forceprivate=True),
            'statement': statement,
            'returning': returning
            }
    else:
        # to make the return value right, we need to tweak the
        # where clause.  we want to only select streams where
        # there's actually something to delete, since all of the
        # streams the where-clause hits will get returned.
        tag_clause = ast.Statement(
            ast.Statement.OP_OR,
            *[ast.Statement(ast.Statement.OP_HAS, tag) for tag in t[2]])
        if len(t) > 3:
            where_clause = ast.Statement(ast.Statement.OP_AND, tag_clause,
                                         t[4])
        else:
            # if there's no where clause, we only look at streams
            # with the right tag.
            where_clause = tag_clause
        # this alters the tags but doesn't touch the data
        del_tags = ', '.join(map(escape_string, t[2]))
        if not noop:
            statement = "UPDATE stream SET metadata = metadata - ARRAY[" + \
                del_tags + "]"
            returning = "RETURNING id, uuid"
        else:
            statement = "SELECT id, uuid FROM stream"
            returning = ""

        q = statement + " WHERE id IN " + \
            "(SELECT s.id FROM stream s, subscription sub " + \
            "WHERE (" + where_clause.render() + ") AND s.subscription_id = sub.id AND " + \
            qg.build_authcheck(t.parser.request, forceprivate=True)  + ")" + returning
        return ext_tag_deletor, q
Exemple #4
0
def make_delete_rv(t):
    noop = "noop" in t.parser.request.args

    # a new delete inner statement enforces that we only delete
    # things which we have the key for.
    if len(t) > 2 and t[2] == 'where':
        # delete the whole stream, gone.  this also deletes the
        # data in the backend readingdb.
        if not noop:
            statement = "DELETE FROM stream"
            returning = "RETURNING id, uuid"
        else:
            statement = "SELECT uuid FROM stream"
            returning = ""
        return ext_deletor if not noop else ext_default, \
            """%(statement)s WHERE id IN (
                 SELECT s.id FROM stream s, subscription sub 
                 WHERE (%(restrict)s) AND s.subscription_id = sub.id AND 
                 (%(auth)s)
               ) %(returning)s
            """ % { 
            'restrict': t[3].render(),
            'auth': qg.build_authcheck(t.parser.request, forceprivate=True, action='delete'),
            'statement': statement,
            'returning': returning
            }
    else:
        # to make the return value right, we need to tweak the
        # where clause.  we want to only select streams where
        # there's actually something to delete, since all of the
        # streams the where-clause hits will get returned.
        tag_clause = ast.Statement(ast.Statement.OP_OR,
                                   *[ast.Statement(ast.Statement.OP_HAS, tag) 
                                     for tag in t[2]])
        if len(t) > 3: 
            where_clause = ast.Statement(ast.Statement.OP_AND, tag_clause, t[4])
        else:
            # if there's no where clause, we only look at streams
            # with the right tag.
            where_clause = tag_clause
        # this alters the tags but doesn't touch the data
        del_tags = ', '.join(map(escape_string, t[2]))
        if not noop:
            statement = "UPDATE stream SET metadata = metadata - ARRAY[" + \
                del_tags + "]"
            returning = "RETURNING id, uuid"
        else:
            statement = "SELECT id, uuid FROM stream"
            returning = ""

        q = statement + " WHERE id IN " + \
            "(SELECT s.id FROM stream s, subscription sub " + \
            "WHERE (" + where_clause.render() + ") AND s.subscription_id = sub.id AND " + \
            qg.build_authcheck(t.parser.request, forceprivate=True, action='delete')  + ")" + returning
        return ext_tag_deletor, q
Exemple #5
0
def make_select_rv(t, sel, wherestmt='true'):
    return sel.extract, ("""SELECT %s FROM stream s, subscription sub
              WHERE (%s) AND (%s) AND
              sub.id = s.subscription_id""" % 
                         (sel.select, 
                          wherestmt,
                          qg.build_authcheck(t.parser.request)))
Exemple #6
0
def make_select_rv(t, sel, wherestmt='true'):
    return sel.extract, ("""SELECT %s FROM stream s, subscription sub
              WHERE (%s) AND (%s) AND
              sub.id = s.subscription_id""" % 
                         (sel.select, 
                          wherestmt,
                          qg.build_authcheck(t.parser.request)))
Exemple #7
0
def make_set_rv(t):
    # build the query for a set expression
    if len(t) > 3:
        # if there is a where clause, grab it
        where_clause = t[4]
    else:
        # if no where clause, just do something fast that matches
        # everything
        where_clause = ast.Statement(ast.Statement.OP_UUID)
    noop = "noop" in t.parser.request.args

    # build a list of what tags we're updating, as well as the
    # name of the regex tag.  We're currently not smart enough to
    # deal with more than one regex match in a set statement, due
    # to issues with back references.
    new_tags, regex_tag = build_setstring(t[2], where_clause)
    tag_list = [v[0] for v in t[2]]
    if regex_tag: tag_list.append(regex_tag)

    # if we're in noop mode, we need to tweak the SQL
    if not noop:
        command = "UPDATE stream SET metadata = metadata || "
        from_stmt = ""
    else:
        command = "SELECT uuid, "
        from_stmt = "FROM stream"

    # build the first part of the query that depends on if this is a noop
    q = "%(command)s %(hstore_expression)s %(from_stmt)s WHERE ID IN" % {
        "command": command,
        "hstore_expression": new_tags,
        "from_stmt": from_stmt
    }

    # the where caluse always looks the same
    q += "(SELECT s.id FROM stream s, subscription sub " + \
        "WHERE (" + where_clause.render() + ") AND s.subscription_id = sub.id AND " + \
        qg.build_authcheck(t.parser.request, forceprivate=True)  + ") "

    if not noop:
        # return the list of modifications.  if this was a noop we
        # get this for free.
        q += " RETURNING uuid, slice(metadata, ARRAY[" + \
            ','.join((escape_string(v) for v in tag_list)) + "])"
    return lambda x: ext_set(tag_list, x), q
Exemple #8
0
def make_set_rv(t):
    # build the query for a set expression
    if len(t) > 3:
        # if there is a where clause, grab it
        where_clause = t[4]
    else:
        # if no where clause, just do something fast that matches
        # everything
        where_clause = ast.Statement(ast.Statement.OP_UUID)
    noop = "noop" in t.parser.request.args

    # build a list of what tags we're updating, as well as the
    # name of the regex tag.  We're currently not smart enough to
    # deal with more than one regex match in a set statement, due
    # to issues with back references.
    new_tags, regex_tag = build_setstring(t[2], where_clause)
    tag_list = [v[0] for v in t[2]]
    if regex_tag: tag_list.append(regex_tag)

    # if we're in noop mode, we need to tweak the SQL
    if not noop: 
        command = "UPDATE stream SET metadata = metadata || "
        from_stmt = ""
    else:
        command = "SELECT uuid, "
        from_stmt = "FROM stream"

    # build the first part of the query that depends on if this is a noop
    q = "%(command)s %(hstore_expression)s %(from_stmt)s WHERE ID IN" % {
        "command": command,
        "hstore_expression": new_tags,
        "from_stmt": from_stmt }

    # the where caluse always looks the same
    q += "(SELECT s.id FROM stream s, subscription sub " + \
        "WHERE (" + where_clause.render() + ") AND s.subscription_id = sub.id AND " + \
        qg.build_authcheck(t.parser.request, forceprivate=True, action='set')  + ") " 

    if not noop:
        # return the list of modifications.  if this was a noop we
        # get this for free.
        q += " RETURNING uuid, slice(metadata, ARRAY[" + \
            ','.join((escape_string(v) for v in tag_list)) + "])"
    return lambda x: ext_set(tag_list, x), q