diff --git a/VERSION b/VERSION index 71e0c806..ca03c054 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Version 2.4.1-alpha.2+timestamp.2013.01.13.10.43.10 +Version 2.4.1-alpha.2+timestamp.2013.01.13.13.07.43 diff --git a/gluon/dal.py b/gluon/dal.py index 0d7ecfef..0f8b3967 100644 --- a/gluon/dal.py +++ b/gluon/dal.py @@ -6689,32 +6689,87 @@ class Row(object): del d[k] return d - def as_json(self, default=None, **kwargs): + def as_xml(self, row_name="row", colnames=None, indent=' '): + def f(row,field,indent=' '): + if isinstance(row,Row): + spc = indent+' \n' + items = [f(row[x],x,indent+' ') for x in row] + return '%s<%s>\n%s\n%s' % ( + indent, + field, + spc.join(item for item in items if item), + indent, + field) + elif not callable(row): + if REGEX_ALPHANUMERIC.match(field): + return '%s<%s>%s' % (indent,field,row,field) + else: + return '%s%s' % \ + (indent,field,row) + else: + return None + return f(self, row_name, indent=indent) + + def as_json(self, mode="object", default=None, colnames=None, + serialize=True, **kwargs): """ serializes the table to a JSON list of objects kwargs are passed to .as_dict method - only "object" mode supported + only "object" mode supported for single row + + serialize = False used by Rows.as_json TODO: return array mode with query column order """ + + def inner_loop(record, col): + (t, f) = col.split('.') + res = None + if not REGEX_TABLE_DOT_FIELD.match(col): + key = col + res = record._extra[col] + else: + key = f + if isinstance(record.get(t, None), Row): + res = record[t][f] + else: + res = record[f] + if mode == 'object': + return (key, res) + else: + return res + multi = any([isinstance(v, self.__class__) for v in self.values()]) - item = dict() + mode = mode.lower() + if not mode in ['object', 'array']: + raise SyntaxError('Invalid JSON serialization mode: %s' % mode) - if multi: - for v in self.as_dict(**kwargs).values(): - item.update(v) + if mode=='object' and colnames: + item = dict([inner_loop(self, col) for col in colnames]) + elif colnames: + item = [inner_loop(self, col) for col in colnames] else: - item = self.as_dict(**kwargs) + if not mode == 'object': + raise SyntaxError('Invalid JSON serialization mode: %s' % mode) - if have_serializers: - return serializers.json(item, - default=default or - serializers.custom_json) + if multi: + item = dict() + [item.update(**v.as_dict(**kwargs)) for v in self.values()] + else: + item = self.as_dict(**kwargs) + + if serialize: + if have_serializers: + return serializers.json(item, + default=default or + serializers.custom_json) + else: + try: + import json as simplejson + except ImportError: + import gluon.contrib.simplejson as simplejson + return simplejson.dumps(item) else: - try: - import json as simplejson - except ImportError: - import gluon.contrib.simplejson as simplejson - return simplejson.dumps(item) + return item ################################################################################ @@ -9592,30 +9647,14 @@ class Rows(object): """ serializes the table using sqlhtml.SQLTABLE (if present) """ + if strict: ncols = len(self.colnames) - def f(row,field,indent=' '): - if isinstance(row,Row): - spc = indent+' \n' - items = [f(row[x],x,indent+' ') for x in row] - return '%s<%s>\n%s\n%s' % ( - indent, - field, - spc.join(item for item in items if item), - indent, - field) - elif not callable(row): - if REGEX_ALPHANUMERIC.match(field): - return '%s<%s>%s' % (indent,field,row,field) - else: - return '%s%s' % \ - (indent,field,row) - else: - return None - return '<%s>\n%s\n' % ( - rows_name, - '\n'.join(f(row,row_name) for row in self), - rows_name) + return '<%s>\n%s\n' % (rows_name, + '\n'.join(row.as_xml(row_name=row_name, + colnames=self.colnames) for + row in self), rows_name) + import sqlhtml return sqlhtml.SQLTABLE(self).xml() @@ -9626,33 +9665,12 @@ class Rows(object): """ serializes the table to a JSON list of objects """ - mode = mode.lower() - if not mode in ['object', 'array']: - raise SyntaxError('Invalid JSON serialization mode: %s' % mode) - def inner_loop(record, col): - (t, f) = col.split('.') - res = None - if not REGEX_TABLE_DOT_FIELD.match(col): - key = col - res = record._extra[col] - else: - key = f - if isinstance(record.get(t, None), Row): - res = record[t][f] - else: - res = record[f] - if mode == 'object': - return (key, res) - else: - return res + items = [record.as_json(mode=mode, default=default, + serialize=False, + colnames=self.colnames) for + record in self] - if mode == 'object': - items = [dict([inner_loop(record, col) for col in - self.colnames]) for record in self] - else: - items = [[inner_loop(record, col) for col in self.colnames] - for record in self] if have_serializers: return serializers.json(items, default=default or @@ -9664,6 +9682,8 @@ class Rows(object): import gluon.contrib.simplejson as simplejson return simplejson.dumps(items) + # for consistent naming yet backwards compatible + as_csv = __str__ json = as_json ################################################################################