예제 #1
0
  def create_table(self, data, table_name, error_if_exists = False, **kwargs):
    'Create a table based on the data, but don\'t insert anything.'

    converted_data = convert(data)
    if len(converted_data) == 0 or converted_data[0] == []:
      raise ValueError(u'You passed no sample values, or all the values you passed were null.')
    else:
      startdata = OrderedDict(converted_data[0])

    # Select a non-null item
    for k, v in startdata.items():
      if v != None:
        break
    else:
      v = None

    if_not_exists = u'' if error_if_exists else u'IF NOT EXISTS'

    # Do nothing if all items are null.
    if v != None:
      try:
        # This is vulnerable to injection.
        sql = u'''
          CREATE TABLE %s %s (
            %s %s
          );''' % (if_not_exists, quote(table_name), quote(k), get_column_type(startdata[k]))
        self.execute(sql, commit = False)
      except:
        raise
      else:
        self.commit()
 
      for row in converted_data:
        self.__check_and_add_columns(table_name, row)
예제 #2
0
  def save_var(self, key, value, **kwargs):
    'Save one variable to the database.'

    # Check whether Highwall's variables table exists
    self.__check_or_create_vars_table()

    column_type = get_column_type(value)
    tmp = quote(self.__vars_table_tmp)

    self.execute(u'DROP TABLE IF EXISTS %s' % tmp, commit = False)

    # This is vulnerable to injection
    self.execute(u'CREATE TABLE %s (`value` %s)' % (tmp, column_type), commit = False)

    # This is ugly
    self.execute(u'INSERT INTO %s (`value`) VALUES (?)' % tmp, [value], commit = False)
    table = (quote(self.__vars_table), tmp)
    params = [key, column_type]
    self.execute(u'''
INSERT OR REPLACE INTO %s (`key`, `type`, `value`)
  SELECT
    ? AS key,
    ? AS type,
    value
  FROM %s
''' % table, params)
    self.execute(u'DROP TABLE %s' % tmp, commit = False)

    self.__commit_if_necessary(kwargs)
예제 #3
0
  def __check_or_create_vars_table(self):
    self.create_table(
      {'key': '', 'type': ''},
      quote(self.__vars_table),
      commit = False
    )
    sql = u'ALTER TABLE %s ADD COLUMN value BLOB' % quote(self.__vars_table)
    self.execute(sql, commit = False)

    self.commit()

    table_info = self.execute(u'PRAGMA table_info(%s)' % quote(self.__vars_table))
    column_names_observed = set([column['name'] for column in table_info])
    column_names_expected = {'key', 'type', 'value'}
    assert column_names_observed == column_names_expected, table_info
예제 #4
0
  def column_names(self, table):
      """An iterable of column names, for a particular table or
      view."""

      table_info = self.execute(
        u'PRAGMA table_info(%s)' % quote(table))
      return (column['name'] for column in table_info)
예제 #5
0
  def insert(self, data, table_name = 'dumptruck', **kwargs):
    try:
      self.create_table(data, table_name)
    except:
      raise

    # Turn it into a list of zips.
    converted_data = convert(data)

    for row in converted_data:
      self.__check_and_add_columns(table_name, row)
    
    # .keys() and .items() are in the same order
    # http://www.python.org/dev/peps/pep-3106/
    for row in converted_data:
      keys = [pair[0] for pair in row]
      values = [pair[1] for pair in row]

      question_marks = ','.join('?'*len(keys))

      # This is vulnerable to injection.
      sql = u'INSERT OR REPLACE INTO %s (%s) VALUES (%s);' % (
        quote(table_name), ','.join(keys), question_marks)
      self.execute(sql, values, commit=False)

    self.__commit_if_necessary(kwargs)
예제 #6
0
  def __check_or_create_vars_table(self):
    sql = u"CREATE TABLE IF NOT EXISTS %s (`key` text PRIMARY KEY, `value` blob, `type` text)" % quote(self.__vars_table)
    self.execute(sql, commit = False)

    self.commit()

    table_info = self.execute(u'PRAGMA table_info(%s)' % quote(self.__vars_table))
    column_names_observed = set([column['name'] for column in table_info])
    column_names_expected = {'key', 'type', 'value'}
    assert column_names_observed == column_names_expected, table_info
예제 #7
0
  def create_table(self, data, table_name, error_if_exists = False, **kwargs):
    'Create a table based on the data, but don\'t insert anything.'
    converted_data = convert(data)
    startdata = dict(converted_data[0])

    # Select a non-null item
    for k, v in startdata.items():
      if v != None:
        break

    try:
      # This is vulnerable to injection.
      self.execute(u'''
        CREATE TABLE %s (
          %s %s
        );''' % (quote(table_name), quote(k), get_column_type(startdata[k])), commit = False)
    except sqlite3.OperationalError, msg:
      if (not re.match(r'^table.+already exists$', str(msg))) or (error_if_exists == True):
        raise
예제 #8
0
  def get_var(self, key):
    'Retrieve one saved variable from the database.'
    vt = quote(self.__vars_table)
    data = self.execute(u'SELECT * FROM %s WHERE `key` = ?' % vt, [key], commit = False)
    if data == []:
      raise NameError(u'The DumpTruck variables table doesn\'t have a value for %s.' % key)
    else:
      tmp = quote(self.__vars_table_tmp)
      row = data[0]

      self.execute(u'DROP TABLE IF EXISTS %s' % tmp, commit = False)

      # This is vulnerable to injection
      self.execute(u'CREATE TEMPORARY TABLE %s (`value` %s)' % (tmp, row['type']), commit = False)

      # This is ugly
      self.execute(u'INSERT INTO %s (`value`) VALUES (?)' % tmp, [row['value']], commit = False)
      value = self.dump(tmp)[0]['value']
      self.execute(u'DROP TABLE %s' % tmp, commit = False)

      return value
예제 #9
0
  def create_index(self, columns, table_name, if_not_exists = True, unique = False, **kwargs):
    'Create a unique index on the column(s) passed.'
    index_name = simplify(table_name) + u'_' + u'_'.join(map(simplify, columns))
    if unique:
      sql = u'CREATE UNIQUE INDEX %s ON %s (%s)'
    else:
      sql = u'CREATE INDEX %s ON %s (%s)'

    first_param = u'IF NOT EXISTS ' + index_name if if_not_exists else index_name

    params = (first_param, quote(table_name), ','.join(map(quote, columns)))
    self.execute(sql % params, **kwargs)
예제 #10
0
 def __check_and_add_columns(self, table_name, converted_data_row):
   column_types = self.__column_types(table_name)
   for key,value in converted_data_row:
     try:
       column_type = get_column_type(value)
       params = (quote(table_name), key, column_type)
       sql = u'ALTER TABLE %s ADD COLUMN %s %s ' % params
       self.execute(sql, commit = True)
     except self.sqlite3.OperationalError, msg:
       if str(msg).split(':')[0] == u'duplicate column name':
         # The column is already there.
         pass
       else:
         raise
예제 #11
0
 def dump(self, table_name = 'dumptruck'):
   'Dump a table.'
   return self.execute(u'SELECT * FROM %s;' % quote(table_name))
예제 #12
0
 def drop(self, table_name = 'dumptruck', if_exists = False, **kwargs):
   'Drop a table.'
   return self.execute(u'DROP TABLE %s %s;' % ('IF EXISTS' if if_exists else '', quote(table_name)), **kwargs)
예제 #13
0
 def __column_types(self, table_name):
   # This is vulnerable to injection.
   self.cursor.execute(u'PRAGMA table_info(%s)' % quote(table_name))
   return {column[1]:column[2] for column in self.cursor.fetchall()}
예제 #14
0
    for row in converted_data:
      self.__check_and_add_columns(table_name, row)
    
    # .keys() and .items() are in the same order
    # http://www.python.org/dev/peps/pep-3106/

    # rowid of inserted rows
    rowids = []
    for row in converted_data:
      keys = [pair[0] for pair in row]
      values = [pair[1] for pair in row]

      # This is vulnerable to injection.
      if len(keys) > 0:
        question_marks = ','.join('?'*len(keys))
        sql = u'INSERT %s INTO %s (%s) VALUES (%s);' % (upserttext, quote(table_name), ','.join(keys), question_marks)
        self.execute(sql, values, commit=False)

      else:
        sql = u'INSERT %s INTO %s DEFAULT VALUES;' % (upserttext, quote(table_name)) 
        self.execute(sql, commit=False)

      rowids.append(self.execute('SELECT last_insert_rowid()', commit=False)[0]['last_insert_rowid()'])

    self.__commit_if_necessary(kwargs)

    # Return rowids as a list?
    if hasattr(data, 'keys'):
      return rowids[0]
    else:
      return rowids
예제 #15
0
    for row in converted_data:
      self.__check_and_add_columns(table_name, row)
    
    # .keys() and .items() are in the same order
    # http://www.python.org/dev/peps/pep-3106/

    # rowid of inserted rows
    rowids = []
    for row in converted_data:
      keys = [pair[0] for pair in row]
      values = [pair[1] for pair in row]

      # This is vulnerable to injection.
      if len(keys) > 0:
        question_marks = ','.join('?'*len(keys))
        sql = u'INSERT INTO %s (%s) VALUES (%s);' % (quote(table_name), ','.join(keys), question_marks)
        self.execute(sql, values, commit=False)

      else:
        sql = u'INSERT INTO %s DEFAULT VALUES;' % quote(table_name) 
        self.execute(sql, commit=False)

      rowids.append(self.execute('SELECT last_insert_rowid()')[0]['last_insert_rowid()'])

    self.__commit_if_necessary(kwargs)

    # Return rowids as a list?
    if hasattr(data, 'keys'):
      return rowids[0]
    else:
      return rowids