From bc4d8d3e02c6d5d772183445b7d14c233fc9dea8 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Fri, 11 Jan 2013 11:17:41 +0100 Subject: [PATCH] Implementation for an Issue #332 --- lib/core/agent.py | 13 ++++++++++- plugins/generic/databases.py | 43 +++++++++++++++++++++++++++--------- xml/queries.xml | 4 ++-- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/lib/core/agent.py b/lib/core/agent.py index 4b1693ee4..15597aa5d 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -376,7 +376,18 @@ class Agent(object): nulledCastedConcatFields = fields else: fields = fields.replace(", ", ',') - fieldsSplitted = fields.split(',') + commas = [0, len(fields)] + depth = 0 + for index in xrange(len(fields)): + char = fields[index] + if char == '(': + depth += 1 + elif char == ')': + depth -= 1 + elif depth == 0 and char == ',': + commas.append(index) + commas = sorted(commas) + fieldsSplitted = [fields[x:y] for (x, y) in zip(commas, commas[1:])] dbmsDelimiter = queries[Backend.getIdentifiedDbms()].delimiter.query nulledCastedFields = [] diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index cfa7ff5c2..7c2fd47df 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -13,6 +13,7 @@ from lib.core.common import getLimitRange from lib.core.common import isInferenceAvailable from lib.core.common import isListLike from lib.core.common import isNoneValue +from lib.core.common import isNullValue from lib.core.common import isNumPosStrValue from lib.core.common import isTechniqueAvailable from lib.core.common import parseSqliteTableSchema @@ -275,7 +276,7 @@ class Databases: values = filter(None, arrayizeValue(values)) if len(values) > 0 and not isListLike(values[0]): - values = ((dbs[0], _) for _ in values) + values = [(dbs[0], _) for _ in values] for db, table in filterPairValues(values): db = safeSQLIdentificatorNaming(db) @@ -524,6 +525,17 @@ class Databases: values = inject.getValue(query, blind=False, time=False) + if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values): + index, values = 1, [] + while True: + query = rootQuery.inband.query2 % (conf.db, tbl, index) + value = unArrayizeValue(inject.getValue(query, blind=False, time=False)) + if isNoneValue(value) or value == " ": + break + else: + values.append((value,)) + index += 1 + if Backend.isDbms(DBMS.SQLITE): parseSqliteTableSchema(unArrayizeValue(values)) elif not isNoneValue(values): @@ -536,7 +548,7 @@ class Databases: if name: if len(columnData) == 1: - columns[name] = "" + columns[name] = None else: columns[name] = columnData[1] @@ -600,17 +612,28 @@ class Databases: count = inject.getValue(query, union=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) - if not isNumPosStrValue(count): - errMsg = "unable to retrieve the number of columns " - errMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl) - errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db) - logger.error(errMsg) - - continue - table = {} columns = {} + if not isNumPosStrValue(count): + if Backend.isDbms(DBMS.MSSQL): + count, index, values = 0, 1, [] + while True: + query = rootQuery.blind.query3 % (conf.db, tbl, index) + value = unArrayizeValue(inject.getValue(query, union=False, error=False)) + if isNoneValue(value) or value == " ": + break + else: + columns[safeSQLIdentificatorNaming(value)] = None + index += 1 + + if not columns: + errMsg = "unable to retrieve the %scolumns " % ("number of " if not Backend.isDbms(DBMS.MSSQL) else "") + errMsg += "for table '%s' " % unsafeSQLIdentificatorNaming(tbl) + errMsg += "in database '%s'" % unsafeSQLIdentificatorNaming(conf.db) + logger.error(errMsg) + continue + for index in getLimitRange(count): if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL): query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db)) diff --git a/xml/queries.xml b/xml/queries.xml index d54616c65..96260ada5 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -194,8 +194,8 @@ - - + +