From: <fwi...@us...> - 2009-08-11 05:00:19
|
Revision: 6661 http://jython.svn.sourceforge.net/jython/?rev=6661&view=rev Author: fwierzbicki Date: 2009-08-11 05:00:06 +0000 (Tue, 11 Aug 2009) Log Message: ----------- Merged revisions 6525-6539,6543-6550,6552-6558,6566-6568,6570-6571,6575,6580-6623,6626-6659 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython Modified Paths: -------------- branches/indy/.classpath branches/indy/CoreExposed.includes branches/indy/Lib/_rawffi.py branches/indy/Lib/codeop.py branches/indy/Lib/datetime.py branches/indy/Lib/dbexts.py branches/indy/Lib/fileinput.py branches/indy/Lib/isql.py branches/indy/Lib/javapath.py branches/indy/Lib/javashell.py branches/indy/Lib/os.py branches/indy/Lib/pawt/__init__.py branches/indy/Lib/pawt/colors.py branches/indy/Lib/pawt/swing.py branches/indy/Lib/pkgutil.py branches/indy/Lib/posixpath.py branches/indy/Lib/readline.py branches/indy/Lib/signal.py branches/indy/Lib/socket.py branches/indy/Lib/subprocess.py branches/indy/Lib/telnetlib.py branches/indy/Lib/test/Graph.py branches/indy/Lib/test/anygui.py branches/indy/Lib/test/jser2_classes.py branches/indy/Lib/test/regrtest.py branches/indy/Lib/test/test_SimpleXMLRPCServer.py branches/indy/Lib/test/test__rawffi.py branches/indy/Lib/test/test_array_jy.py branches/indy/Lib/test/test_ast_jy.py branches/indy/Lib/test/test_bigmem.py branches/indy/Lib/test/test_builtin.py branches/indy/Lib/test/test_builtin_jy.py branches/indy/Lib/test/test_cmath_jy.py branches/indy/Lib/test/test_codeop.py branches/indy/Lib/test/test_codeop_jy.py branches/indy/Lib/test/test_coerce_jy.py branches/indy/Lib/test/test_compile_jy.py branches/indy/Lib/test/test_concat_jy.py branches/indy/Lib/test/test_descr_jy.py branches/indy/Lib/test/test_dict2java.py branches/indy/Lib/test/test_exceptions_jy.py branches/indy/Lib/test/test_float_jy.py branches/indy/Lib/test/test_func_syntax_jy.py branches/indy/Lib/test/test_grammar_jy.py branches/indy/Lib/test/test_import_jy.py branches/indy/Lib/test/test_importhooks.py branches/indy/Lib/test/test_java_integration.py branches/indy/Lib/test/test_java_list_delegate.py branches/indy/Lib/test/test_java_subclasses.py branches/indy/Lib/test/test_java_visibility.py branches/indy/Lib/test/test_javalist.py branches/indy/Lib/test/test_javashell.py branches/indy/Lib/test/test_jbasic.py branches/indy/Lib/test/test_joverload.py branches/indy/Lib/test/test_jser.py branches/indy/Lib/test/test_jy_generators.py branches/indy/Lib/test/test_jy_internals.py branches/indy/Lib/test/test_list_jy.py branches/indy/Lib/test/test_marshal.py branches/indy/Lib/test/test_metaclass_support/simpleclass.py branches/indy/Lib/test/test_module.py branches/indy/Lib/test/test_pbcvm.py branches/indy/Lib/test/test_pythoninterpreter_jy.py branches/indy/Lib/test/test_random.py branches/indy/Lib/test/test_re.py branches/indy/Lib/test/test_re_jy.py branches/indy/Lib/test/test_sax.py branches/indy/Lib/test/test_sax_jy.py branches/indy/Lib/test/test_set_jy.py branches/indy/Lib/test/test_socket.py branches/indy/Lib/test/test_sort.py branches/indy/Lib/test/test_sort_jy.py branches/indy/Lib/test/test_str2unicode.py branches/indy/Lib/test/test_stringmap.py branches/indy/Lib/test/test_subclasses.py branches/indy/Lib/test/test_subclasses_jy.py branches/indy/Lib/test/test_sys_jy.py branches/indy/Lib/test/test_thread_jy.py branches/indy/Lib/test/test_thread_local.py branches/indy/Lib/test/test_threading.py branches/indy/Lib/test/test_threading_jy.py branches/indy/Lib/test/test_timeit.py branches/indy/Lib/test/test_trace.py branches/indy/Lib/test/test_trace_threaded.py branches/indy/Lib/test/test_tuple.py branches/indy/Lib/test/test_unicode_jy.py branches/indy/Lib/test/test_userdict.py branches/indy/Lib/test/test_weakref.py branches/indy/Lib/test/test_with.py branches/indy/Lib/test/test_xml_etree_jy.py branches/indy/Lib/test/test_zipimport_jy.py branches/indy/Lib/test/whrandom.py branches/indy/Lib/test/zxjdbc/dbextstest.py branches/indy/Lib/test/zxjdbc/jndi.py branches/indy/Lib/test/zxjdbc/runner.py branches/indy/Lib/test/zxjdbc/sptest.py branches/indy/Lib/test/zxjdbc/test_zxjdbc_dbapi20.py branches/indy/Lib/test/zxjdbc/zxtest.py branches/indy/Lib/threading.py branches/indy/Lib/unicodedata.py branches/indy/Lib/xml/Uri.py branches/indy/Lib/xml/dom/minidom.py branches/indy/Lib/xml/dom/pulldom.py branches/indy/Lib/xml/parsers/expat.py branches/indy/Lib/xml/sax/_exceptions.py branches/indy/Lib/xml/sax/drivers2/drv_javasax.py branches/indy/Lib/xml/sax/handler.py branches/indy/Lib/xml/sax/saxutils.py branches/indy/Lib/zlib.py branches/indy/NEWS branches/indy/ast/asdl_antlr.py branches/indy/grammar/Base.g branches/indy/grammar/Python.g branches/indy/grammar/PythonPartial.g branches/indy/src/com/xhaus/modjy/ModjyJServlet.java branches/indy/src/com/ziclix/python/sql/DataHandler.java branches/indy/src/com/ziclix/python/sql/Fetch.java branches/indy/src/com/ziclix/python/sql/JDBC20DataHandler.java branches/indy/src/com/ziclix/python/sql/Jython22DataHandler.java branches/indy/src/com/ziclix/python/sql/PyConnection.java branches/indy/src/com/ziclix/python/sql/PyCursor.java branches/indy/src/com/ziclix/python/sql/PyExtendedCursor.java branches/indy/src/com/ziclix/python/sql/PyStatement.java branches/indy/src/com/ziclix/python/sql/handler/InformixDataHandler.java branches/indy/src/com/ziclix/python/sql/handler/MySQLDataHandler.java branches/indy/src/com/ziclix/python/sql/handler/OracleDataHandler.java branches/indy/src/com/ziclix/python/sql/util/PyArgParser.java branches/indy/src/com/ziclix/python/sql/util/Queue.java branches/indy/src/com/ziclix/python/sql/zxJDBC.java branches/indy/src/org/python/antlr/AST.java branches/indy/src/org/python/antlr/BaseParser.java branches/indy/src/org/python/antlr/GrammarActions.java branches/indy/src/org/python/antlr/ParseException.java branches/indy/src/org/python/antlr/PythonErrorNode.java branches/indy/src/org/python/antlr/PythonTokenSource.java branches/indy/src/org/python/antlr/PythonTree.java branches/indy/src/org/python/antlr/PythonTreeAdaptor.java branches/indy/src/org/python/antlr/adapter/AliasAdapter.java branches/indy/src/org/python/antlr/adapter/AstAdapters.java branches/indy/src/org/python/antlr/adapter/CmpopAdapter.java branches/indy/src/org/python/antlr/adapter/ComprehensionAdapter.java branches/indy/src/org/python/antlr/adapter/ExcepthandlerAdapter.java branches/indy/src/org/python/antlr/adapter/ExprAdapter.java branches/indy/src/org/python/antlr/adapter/IdentifierAdapter.java branches/indy/src/org/python/antlr/adapter/KeywordAdapter.java branches/indy/src/org/python/antlr/adapter/SliceAdapter.java branches/indy/src/org/python/antlr/adapter/StmtAdapter.java branches/indy/src/org/python/antlr/ast/Assert.java branches/indy/src/org/python/antlr/ast/Assign.java branches/indy/src/org/python/antlr/ast/Attribute.java branches/indy/src/org/python/antlr/ast/AugAssign.java branches/indy/src/org/python/antlr/ast/BinOp.java branches/indy/src/org/python/antlr/ast/BoolOp.java branches/indy/src/org/python/antlr/ast/Break.java branches/indy/src/org/python/antlr/ast/Call.java branches/indy/src/org/python/antlr/ast/ClassDef.java branches/indy/src/org/python/antlr/ast/Compare.java branches/indy/src/org/python/antlr/ast/Continue.java branches/indy/src/org/python/antlr/ast/Delete.java branches/indy/src/org/python/antlr/ast/Dict.java branches/indy/src/org/python/antlr/ast/Ellipsis.java branches/indy/src/org/python/antlr/ast/ExceptHandler.java branches/indy/src/org/python/antlr/ast/Exec.java branches/indy/src/org/python/antlr/ast/Expr.java branches/indy/src/org/python/antlr/ast/Expression.java branches/indy/src/org/python/antlr/ast/ExtSlice.java branches/indy/src/org/python/antlr/ast/For.java branches/indy/src/org/python/antlr/ast/FunctionDef.java branches/indy/src/org/python/antlr/ast/GeneratorExp.java branches/indy/src/org/python/antlr/ast/Global.java branches/indy/src/org/python/antlr/ast/If.java branches/indy/src/org/python/antlr/ast/IfExp.java branches/indy/src/org/python/antlr/ast/Import.java branches/indy/src/org/python/antlr/ast/ImportFrom.java branches/indy/src/org/python/antlr/ast/Index.java branches/indy/src/org/python/antlr/ast/Interactive.java branches/indy/src/org/python/antlr/ast/Lambda.java branches/indy/src/org/python/antlr/ast/List.java branches/indy/src/org/python/antlr/ast/ListComp.java branches/indy/src/org/python/antlr/ast/Module.java branches/indy/src/org/python/antlr/ast/Name.java branches/indy/src/org/python/antlr/ast/Num.java branches/indy/src/org/python/antlr/ast/Pass.java branches/indy/src/org/python/antlr/ast/Print.java branches/indy/src/org/python/antlr/ast/Raise.java branches/indy/src/org/python/antlr/ast/Repr.java branches/indy/src/org/python/antlr/ast/Return.java branches/indy/src/org/python/antlr/ast/Slice.java branches/indy/src/org/python/antlr/ast/Str.java branches/indy/src/org/python/antlr/ast/Subscript.java branches/indy/src/org/python/antlr/ast/Suite.java branches/indy/src/org/python/antlr/ast/TryExcept.java branches/indy/src/org/python/antlr/ast/TryFinally.java branches/indy/src/org/python/antlr/ast/Tuple.java branches/indy/src/org/python/antlr/ast/UnaryOp.java branches/indy/src/org/python/antlr/ast/While.java branches/indy/src/org/python/antlr/ast/With.java branches/indy/src/org/python/antlr/ast/Yield.java branches/indy/src/org/python/antlr/ast/alias.java branches/indy/src/org/python/antlr/ast/arguments.java branches/indy/src/org/python/antlr/ast/comprehension.java branches/indy/src/org/python/antlr/ast/keyword.java branches/indy/src/org/python/compiler/AdapterMaker.java branches/indy/src/org/python/compiler/ClassConstants.java branches/indy/src/org/python/compiler/ClassFile.java branches/indy/src/org/python/compiler/Code.java branches/indy/src/org/python/compiler/CodeCompiler.java branches/indy/src/org/python/compiler/IndyTest.java branches/indy/src/org/python/compiler/JavaMaker.java branches/indy/src/org/python/compiler/LineNumberTable.java branches/indy/src/org/python/compiler/Module.java branches/indy/src/org/python/compiler/ProxyMaker.java branches/indy/src/org/python/compiler/ScopeInfo.java branches/indy/src/org/python/compiler/ScopesCompiler.java branches/indy/src/org/python/compiler/SymInfo.java branches/indy/src/org/python/core/ArgParser.java branches/indy/src/org/python/core/MakeProxies.java branches/indy/src/org/python/core/ParserFacade.java branches/indy/src/org/python/core/Py.java branches/indy/src/org/python/core/PyFileWriter.java branches/indy/src/org/python/core/PyFinalizableInstance.java branches/indy/src/org/python/core/PyJavaType.java branches/indy/src/org/python/core/PyList.java branches/indy/src/org/python/core/PyObject.java branches/indy/src/org/python/core/PySystemState.java branches/indy/src/org/python/core/PyTuple.java branches/indy/src/org/python/core/PyType.java branches/indy/src/org/python/core/PythonTraceFunction.java branches/indy/src/org/python/core/StdoutWrapper.java branches/indy/src/org/python/core/__builtin__.java branches/indy/src/org/python/core/codecs.java branches/indy/src/org/python/core/imp.java branches/indy/src/org/python/core/util/StringUtil.java branches/indy/src/org/python/expose/generate/ExposeTask.java branches/indy/src/org/python/modules/Setup.java branches/indy/src/org/python/modules/_collections/Collections.java branches/indy/src/org/python/modules/_collections/PyDeque.java branches/indy/src/org/python/util/GlobMatchingTask.java branches/indy/src/org/python/util/JycompileAntTask.java branches/indy/src/org/python/util/PythonInterpreter.java branches/indy/src/org/python/util/jython.java Added Paths: ----------- branches/indy/Lib/test/import_as_java_class.py branches/indy/Lib/test/static_proxy.py branches/indy/Lib/weakref.py branches/indy/extlibs/livetribe-jsr223-2.0.5.jar branches/indy/src/META-INF/ branches/indy/src/META-INF/services/ branches/indy/src/META-INF/services/javax.script.ScriptEngineFactory branches/indy/src/org/python/core/ContextGuard.java branches/indy/src/org/python/core/ContextManager.java branches/indy/src/org/python/core/PyFileReader.java branches/indy/src/org/python/core/util/PlatformUtil.java branches/indy/src/org/python/jsr223/ branches/indy/src/org/python/jsr223/PyScriptEngine.java branches/indy/src/org/python/jsr223/PyScriptEngineFactory.java branches/indy/src/org/python/jsr223/PyScriptEngineScope.java branches/indy/src/org/python/modules/_threading/ branches/indy/src/org/python/modules/_threading/Condition.java branches/indy/src/org/python/modules/_threading/Lock.java branches/indy/src/org/python/modules/_threading/_threading.java branches/indy/src/org/python/util/CompileProxiesTask.java branches/indy/src/org/python/util/FileNameMatchingTask.java branches/indy/tests/java/org/python/jsr223/ branches/indy/tests/java/org/python/jsr223/ScriptEngineIOTest.java branches/indy/tests/java/org/python/jsr223/ScriptEngineTest.java Removed Paths: ------------- branches/indy/Lib/test/test_bugfixes.py branches/indy/src/META-INF/services/ branches/indy/src/META-INF/services/javax.script.ScriptEngineFactory branches/indy/src/org/python/jsr223/PyScriptEngine.java branches/indy/src/org/python/jsr223/PyScriptEngineFactory.java branches/indy/src/org/python/jsr223/PyScriptEngineScope.java branches/indy/src/org/python/modules/_threading/Condition.java branches/indy/src/org/python/modules/_threading/Lock.java branches/indy/src/org/python/modules/_threading/_threading.java branches/indy/tests/java/org/python/jsr223/ScriptEngineIOTest.java branches/indy/tests/java/org/python/jsr223/ScriptEngineTest.java Property Changed: ---------------- branches/indy/ branches/indy/tests/java/org/python/tests/RedundantInterfaceDeclarations.java Property changes on: branches/indy ___________________________________________________________________ Modified: svnmerge-integrated - /branches/pbcvm:1-6045 /trunk/jython:1-6522 + /branches/pbcvm:1-6045 /trunk/jython:1-6660 Modified: svn:mergeinfo - /branches/newstyle-java-types:5564-5663,5666-5729 + /branches/jsr223:6285-6565 /branches/newstyle-java-types:5564-5663,5666-5729 Modified: branches/indy/.classpath =================================================================== --- branches/indy/.classpath 2009-08-11 03:00:08 UTC (rev 6660) +++ branches/indy/.classpath 2009-08-11 05:00:06 UTC (rev 6661) @@ -20,6 +20,7 @@ <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> <classpathentry kind="lib" path="extlibs/jna-posix.jar"/> <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/jar/jdom.jar"/> - <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar"/> + <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar"/> + <classpathentry kind="lib" path="extlibs/jna.jar"/> <classpathentry kind="output" path="bugtests/classes"/> </classpath> Modified: branches/indy/CoreExposed.includes =================================================================== --- branches/indy/CoreExposed.includes 2009-08-11 03:00:08 UTC (rev 6660) +++ branches/indy/CoreExposed.includes 2009-08-11 05:00:06 UTC (rev 6661) @@ -41,25 +41,28 @@ org/python/core/PyType.class org/python/core/PyUnicode.class org/python/core/PyXRange.class +org/python/modules/PyStruct.class +org/python/modules/PyTeeIterator.class +org/python/jsr223/PyScriptEngineScope.class org/python/modules/_codecs$EncodingMap.class +org/python/modules/_collections/PyDefaultDict.class +org/python/modules/_collections/PyDeque.class org/python/modules/_csv/PyDialect.class org/python/modules/_csv/PyReader.class org/python/modules/_csv/PyWriter.class org/python/modules/_functools/PyPartial.class +org/python/modules/_hashlib$Hash.class +org/python/modules/_threading/Condition.class +org/python/modules/_threading/Lock.class org/python/modules/_weakref/CallableProxyType.class +org/python/modules/_weakref/ProxyType.class org/python/modules/_weakref/ReferenceType.class -org/python/modules/_weakref/ProxyType.class -org/python/modules/_hashlib$Hash.class -org/python/modules/_collections/PyDefaultDict.class -org/python/modules/_collections/PyDeque.class org/python/modules/operator$PyAttrGetter.class org/python/modules/operator$PyItemGetter.class org/python/modules/random/PyRandom.class org/python/modules/thread/PyLocal.class org/python/modules/time/PyTimeTuple.class org/python/modules/zipimport/zipimporter.class -org/python/modules/PyStruct.class -org/python/modules/PyTeeIterator.class org/python/antlr/AST.class org/python/antlr/ast/alias.class org/python/antlr/ast/arguments.class Modified: branches/indy/Lib/_rawffi.py =================================================================== --- branches/indy/Lib/_rawffi.py 2009-08-11 03:00:08 UTC (rev 6660) +++ branches/indy/Lib/_rawffi.py 2009-08-11 05:00:06 UTC (rev 6661) @@ -52,6 +52,3 @@ fnp = FuncPtr(fn, name, argtypes, restype) self.cache[key] = fnp return fnp - - - Modified: branches/indy/Lib/codeop.py =================================================================== --- branches/indy/Lib/codeop.py 2009-08-11 03:00:08 UTC (rev 6660) +++ branches/indy/Lib/codeop.py 2009-08-11 05:00:06 UTC (rev 6661) @@ -132,4 +132,3 @@ raise ValueError,"symbol arg must be either single or eval" symbol = CompileMode.getMode(symbol) return Py.compile_command_flags(source,filename,symbol,self._cflags,0) - Modified: branches/indy/Lib/datetime.py =================================================================== --- branches/indy/Lib/datetime.py 2009-08-11 03:00:08 UTC (rev 6660) +++ branches/indy/Lib/datetime.py 2009-08-11 05:00:06 UTC (rev 6661) @@ -13,7 +13,7 @@ Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm This was originally copied from the sandbox of the CPython CVS repository. -Thanks to Tim Peters for suggesting using it. +Thanks to Tim Peters for suggesting using it. """ import time as _time @@ -599,9 +599,9 @@ def __neg__(self): # for CPython compatibility, we cannot use # our __class__ here, but need a real timedelta - return timedelta(-self.__days, - -self.__seconds, - -self.__microseconds) + return timedelta(-self.__days, + -self.__seconds, + -self.__microseconds) def __pos__(self): return self @@ -1622,7 +1622,7 @@ if L[-1] == 0: del L[-1] if L[-1] == 0: - del L[-1] + del L[-1] s = ", ".join(map(str, L)) s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) if self._tzinfo is not None: @@ -1853,12 +1853,14 @@ calendar.clear() calendar.set(self.year, self.month - 1, self.day, self.hour, self.minute, self.second) - calendar.set(Calendar.MILLISECOND, self.microsecond // 1000) if java_class == Calendar: + calendar.set(Calendar.MILLISECOND, self.microsecond // 1000) return calendar else: - return Timestamp(calendar.getTimeInMillis()) + timestamp = Timestamp(calendar.getTimeInMillis()) + timestamp.setNanos(self.microsecond * 1000) + return timestamp datetime.min = datetime(1, 1, 1) @@ -2074,4 +2076,3 @@ perverse time zone returns a negative dst()). So a breaking case must be pretty bizarre, and a tzinfo subclass can override fromutc() if it is. """ - Modified: branches/indy/Lib/dbexts.py =================================================================== --- branches/indy/Lib/dbexts.py 2009-08-11 03:00:08 UTC (rev 6660) +++ branches/indy/Lib/dbexts.py 2009-08-11 05:00:06 UTC (rev 6661) @@ -56,671 +56,671 @@ choose = lambda bool, a, b: (bool and [a] or [b])[0] def console(rows, headers=()): - """Format the results into a list of strings (one for each row): + """Format the results into a list of strings (one for each row): - <header> - <headersep> - <row1> - <row2> - ... + <header> + <headersep> + <row1> + <row2> + ... - headers may be given as list of strings. + headers may be given as list of strings. - Columns are separated by colsep; the header is separated from - the result set by a line of headersep characters. + Columns are separated by colsep; the header is separated from + the result set by a line of headersep characters. - The function calls stringify to format the value data into a string. - It defaults to calling str() and striping leading and trailing whitespace. + The function calls stringify to format the value data into a string. + It defaults to calling str() and striping leading and trailing whitespace. - - copied and modified from mxODBC - """ + - copied and modified from mxODBC + """ - # Check row entry lengths - output = [] - headers = map(lambda header: header.upper(), list(map(lambda x: x or "", headers))) - collen = map(len,headers) - output.append(headers) - if rows and len(rows) > 0: - for row in rows: - row = map(lambda x: str(x), row) - for i in range(len(row)): - entry = row[i] - if collen[i] < len(entry): - collen[i] = len(entry) - output.append(row) - if len(output) == 1: - affected = "0 rows affected" - elif len(output) == 2: - affected = "1 row affected" - else: - affected = "%d rows affected" % (len(output) - 1) + # Check row entry lengths + output = [] + headers = map(lambda header: header.upper(), list(map(lambda x: x or "", headers))) + collen = map(len,headers) + output.append(headers) + if rows and len(rows) > 0: + for row in rows: + row = map(lambda x: str(x), row) + for i in range(len(row)): + entry = row[i] + if collen[i] < len(entry): + collen[i] = len(entry) + output.append(row) + if len(output) == 1: + affected = "0 rows affected" + elif len(output) == 2: + affected = "1 row affected" + else: + affected = "%d rows affected" % (len(output) - 1) - # Format output - for i in range(len(output)): - row = output[i] - l = [] - for j in range(len(row)): - l.append('%-*s' % (collen[j],row[j])) - output[i] = " | ".join(l) + # Format output + for i in range(len(output)): + row = output[i] + l = [] + for j in range(len(row)): + l.append('%-*s' % (collen[j],row[j])) + output[i] = " | ".join(l) - # Insert header separator - totallen = len(output[0]) - output[1:1] = ["-"*(totallen/len("-"))] - output.append("\n" + affected) - return output + # Insert header separator + totallen = len(output[0]) + output[1:1] = ["-"*(totallen/len("-"))] + output.append("\n" + affected) + return output def html(rows, headers=()): - output = [] - output.append('<table class="results">') - output.append('<tr class="headers">') - headers = map(lambda x: '<td class="header">%s</td>' % (x.upper()), list(headers)) - map(output.append, headers) - output.append('</tr>') - if rows and len(rows) > 0: - for row in rows: - output.append('<tr class="row">') - row = map(lambda x: '<td class="value">%s</td>' % (x), row) - map(output.append, row) - output.append('</tr>') - output.append('</table>') - return output + output = [] + output.append('<table class="results">') + output.append('<tr class="headers">') + headers = map(lambda x: '<td class="header">%s</td>' % (x.upper()), list(headers)) + map(output.append, headers) + output.append('</tr>') + if rows and len(rows) > 0: + for row in rows: + output.append('<tr class="row">') + row = map(lambda x: '<td class="value">%s</td>' % (x), row) + map(output.append, row) + output.append('</tr>') + output.append('</table>') + return output comments = lambda x: re.compile("{.*?}", re.S).sub("", x, 0) class mxODBCProxy: - """Wraps mxODBC to provide proxy support for zxJDBC's additional parameters.""" - def __init__(self, c): - self.c = c - def __getattr__(self, name): - if name == "execute": - return self.execute - elif name == "gettypeinfo": - return self.gettypeinfo - else: - return getattr(self.c, name) - def execute(self, sql, params=None, bindings=None, maxrows=None): - if params: - self.c.execute(sql, params) - else: - self.c.execute(sql) - def gettypeinfo(self, typeid=None): - if typeid: - self.c.gettypeinfo(typeid) + """Wraps mxODBC to provide proxy support for zxJDBC's additional parameters.""" + def __init__(self, c): + self.c = c + def __getattr__(self, name): + if name == "execute": + return self.execute + elif name == "gettypeinfo": + return self.gettypeinfo + else: + return getattr(self.c, name) + def execute(self, sql, params=None, bindings=None, maxrows=None): + if params: + self.c.execute(sql, params) + else: + self.c.execute(sql) + def gettypeinfo(self, typeid=None): + if typeid: + self.c.gettypeinfo(typeid) class executor: - """Handles the insertion of values given dynamic data.""" - def __init__(self, table, cols): - self.cols = cols - self.table = table - if self.cols: - self.sql = "insert into %s (%s) values (%s)" % (table, ",".join(self.cols), ",".join(("?",) * len(self.cols))) - else: - self.sql = "insert into %s values (%%s)" % (table) - def execute(self, db, rows, bindings): - assert rows and len(rows) > 0, "must have at least one row" - if self.cols: - sql = self.sql - else: - sql = self.sql % (",".join(("?",) * len(rows[0]))) - db.raw(sql, rows, bindings) + """Handles the insertion of values given dynamic data.""" + def __init__(self, table, cols): + self.cols = cols + self.table = table + if self.cols: + self.sql = "insert into %s (%s) values (%s)" % (table, ",".join(self.cols), ",".join(("?",) * len(self.cols))) + else: + self.sql = "insert into %s values (%%s)" % (table) + def execute(self, db, rows, bindings): + assert rows and len(rows) > 0, "must have at least one row" + if self.cols: + sql = self.sql + else: + sql = self.sql % (",".join(("?",) * len(rows[0]))) + db.raw(sql, rows, bindings) def connect(dbname): - return dbexts(dbname) + return dbexts(dbname) def lookup(dbname): - return dbexts(jndiname=dbname) + return dbexts(jndiname=dbname) class dbexts: - def __init__(self, dbname=None, cfg=None, formatter=console, autocommit=0, jndiname=None, out=None): - self.verbose = 1 - self.results = [] - self.headers = [] - self.autocommit = autocommit - self.formatter = formatter - self.out = out - self.lastrowid = None - self.updatecount = None + def __init__(self, dbname=None, cfg=None, formatter=console, autocommit=0, jndiname=None, out=None): + self.verbose = 1 + self.results = [] + self.headers = [] + self.autocommit = autocommit + self.formatter = formatter + self.out = out + self.lastrowid = None + self.updatecount = None - if not jndiname: - if cfg == None: - fn = os.path.join(os.path.split(__file__)[0], "dbexts.ini") - if not os.path.exists(fn): - fn = os.path.join(os.environ['HOME'], ".dbexts") - self.dbs = IniParser(fn) - elif isinstance(cfg, IniParser): - self.dbs = cfg - else: - self.dbs = IniParser(cfg) - if dbname == None: dbname = self.dbs[("default", "name")] + if not jndiname: + if cfg == None: + fn = os.path.join(os.path.split(__file__)[0], "dbexts.ini") + if not os.path.exists(fn): + fn = os.path.join(os.environ['HOME'], ".dbexts") + self.dbs = IniParser(fn) + elif isinstance(cfg, IniParser): + self.dbs = cfg + else: + self.dbs = IniParser(cfg) + if dbname == None: dbname = self.dbs[("default", "name")] - if __OS__ == 'java': + if __OS__ == 'java': - from com.ziclix.python.sql import zxJDBC - database = zxJDBC - if not jndiname: - t = self.dbs[("jdbc", dbname)] - self.dburl, dbuser, dbpwd, jdbcdriver = t['url'], t['user'], t['pwd'], t['driver'] - if t.has_key('datahandler'): - self.datahandler = [] - for dh in t['datahandler'].split(','): - classname = dh.split(".")[-1] - datahandlerclass = __import__(dh, globals(), locals(), classname) - self.datahandler.append(datahandlerclass) - keys = [x for x in t.keys() if x not in ['url', 'user', 'pwd', 'driver', 'datahandler', 'name']] - props = {} - for a in keys: - props[a] = t[a] - self.db = apply(database.connect, (self.dburl, dbuser, dbpwd, jdbcdriver), props) - else: - self.db = database.lookup(jndiname) - self.db.autocommit = self.autocommit + from com.ziclix.python.sql import zxJDBC + database = zxJDBC + if not jndiname: + t = self.dbs[("jdbc", dbname)] + self.dburl, dbuser, dbpwd, jdbcdriver = t['url'], t['user'], t['pwd'], t['driver'] + if t.has_key('datahandler'): + self.datahandler = [] + for dh in t['datahandler'].split(','): + classname = dh.split(".")[-1] + datahandlerclass = __import__(dh, globals(), locals(), classname) + self.datahandler.append(datahandlerclass) + keys = [x for x in t.keys() if x not in ['url', 'user', 'pwd', 'driver', 'datahandler', 'name']] + props = {} + for a in keys: + props[a] = t[a] + self.db = apply(database.connect, (self.dburl, dbuser, dbpwd, jdbcdriver), props) + else: + self.db = database.lookup(jndiname) + self.db.autocommit = self.autocommit - elif __OS__ == 'nt': + elif __OS__ == 'nt': - for modname in ["mx.ODBC.Windows", "ODBC.Windows"]: - try: - database = __import__(modname, globals(), locals(), "Windows") - break - except: - continue - else: - raise ImportError("unable to find appropriate mxODBC module") + for modname in ["mx.ODBC.Windows", "ODBC.Windows"]: + try: + database = __import__(modname, globals(), locals(), "Windows") + break + except: + continue + else: + raise ImportError("unable to find appropriate mxODBC module") - t = self.dbs[("odbc", dbname)] - self.dburl, dbuser, dbpwd = t['url'], t['user'], t['pwd'] - self.db = database.Connect(self.dburl, dbuser, dbpwd, clear_auto_commit=1) + t = self.dbs[("odbc", dbname)] + self.dburl, dbuser, dbpwd = t['url'], t['user'], t['pwd'] + self.db = database.Connect(self.dburl, dbuser, dbpwd, clear_auto_commit=1) - self.dbname = dbname - for a in database.sqltype.keys(): - setattr(self, database.sqltype[a], a) - for a in dir(database): - try: - p = getattr(database, a) - if issubclass(p, Exception): - setattr(self, a, p) - except: - continue - del database + self.dbname = dbname + for a in database.sqltype.keys(): + setattr(self, database.sqltype[a], a) + for a in dir(database): + try: + p = getattr(database, a) + if issubclass(p, Exception): + setattr(self, a, p) + except: + continue + del database - def __str__(self): - return self.dburl + def __str__(self): + return self.dburl - def __repr__(self): - return self.dburl + def __repr__(self): + return self.dburl - def __getattr__(self, name): - if "cfg" == name: - return self.dbs.cfg - raise AttributeError("'dbexts' object has no attribute '%s'" % (name)) + def __getattr__(self, name): + if "cfg" == name: + return self.dbs.cfg + raise AttributeError("'dbexts' object has no attribute '%s'" % (name)) - def close(self): - """ close the connection to the database """ - self.db.close() + def close(self): + """ close the connection to the database """ + self.db.close() - def begin(self, style=None): - """ reset ivars and return a new cursor, possibly binding an auxiliary datahandler """ - self.headers, self.results = [], [] - if style: - c = self.db.cursor(style) - else: - c = self.db.cursor() - if __OS__ == 'java': - if hasattr(self, 'datahandler'): - for dh in self.datahandler: - c.datahandler = dh(c.datahandler) - else: - c = mxODBCProxy(c) - return c + def begin(self, style=None): + """ reset ivars and return a new cursor, possibly binding an auxiliary datahandler """ + self.headers, self.results = [], [] + if style: + c = self.db.cursor(style) + else: + c = self.db.cursor() + if __OS__ == 'java': + if hasattr(self, 'datahandler'): + for dh in self.datahandler: + c.datahandler = dh(c.datahandler) + else: + c = mxODBCProxy(c) + return c - def commit(self, cursor=None, close=1): - """ commit the cursor and create the result set """ - if cursor and cursor.description: - self.headers = cursor.description - self.results = cursor.fetchall() - if hasattr(cursor, "nextset"): - s = cursor.nextset() - while s: - self.results += cursor.fetchall() - s = cursor.nextset() - if hasattr(cursor, "lastrowid"): - self.lastrowid = cursor.lastrowid - if hasattr(cursor, "updatecount"): - self.updatecount = cursor.updatecount - if not self.autocommit or cursor is None: - if not self.db.autocommit: - self.db.commit() - if cursor and close: cursor.close() + def commit(self, cursor=None, close=1): + """ commit the cursor and create the result set """ + if cursor and cursor.description: + self.headers = cursor.description + self.results = cursor.fetchall() + if hasattr(cursor, "nextset"): + s = cursor.nextset() + while s: + self.results += cursor.fetchall() + s = cursor.nextset() + if hasattr(cursor, "lastrowid"): + self.lastrowid = cursor.lastrowid + if hasattr(cursor, "updatecount"): + self.updatecount = cursor.updatecount + if not self.autocommit or cursor is None: + if not self.db.autocommit: + self.db.commit() + if cursor and close: cursor.close() - def rollback(self): - """ rollback the cursor """ - self.db.rollback() + def rollback(self): + """ rollback the cursor """ + self.db.rollback() - def prepare(self, sql): - """ prepare the sql statement """ - cur = self.begin() - try: - return cur.prepare(sql) - finally: - self.commit(cur) + def prepare(self, sql): + """ prepare the sql statement """ + cur = self.begin() + try: + return cur.prepare(sql) + finally: + self.commit(cur) - def display(self): - """ using the formatter, display the results """ - if self.formatter and self.verbose > 0: - res = self.results - if res: - print >> self.out, "" - for a in self.formatter(res, map(lambda x: x[0], self.headers)): - print >> self.out, a - print >> self.out, "" + def display(self): + """ using the formatter, display the results """ + if self.formatter and self.verbose > 0: + res = self.results + if res: + print >> self.out, "" + for a in self.formatter(res, map(lambda x: x[0], self.headers)): + print >> self.out, a + print >> self.out, "" - def __execute__(self, sql, params=None, bindings=None, maxrows=None): - """ the primary execution method """ - cur = self.begin() - try: - if bindings: - cur.execute(sql, params, bindings, maxrows=maxrows) - elif params: - cur.execute(sql, params, maxrows=maxrows) - else: - cur.execute(sql, maxrows=maxrows) - finally: - self.commit(cur, close=isinstance(sql, StringType)) + def __execute__(self, sql, params=None, bindings=None, maxrows=None): + """ the primary execution method """ + cur = self.begin() + try: + if bindings: + cur.execute(sql, params, bindings, maxrows=maxrows) + elif params: + cur.execute(sql, params, maxrows=maxrows) + else: + cur.execute(sql, maxrows=maxrows) + finally: + self.commit(cur, close=isinstance(sql, StringType)) - def isql(self, sql, params=None, bindings=None, maxrows=None): - """ execute and display the sql """ - self.raw(sql, params, bindings, maxrows=maxrows) - self.display() + def isql(self, sql, params=None, bindings=None, maxrows=None): + """ execute and display the sql """ + self.raw(sql, params, bindings, maxrows=maxrows) + self.display() - def raw(self, sql, params=None, bindings=None, delim=None, comments=comments, maxrows=None): - """ execute the sql and return a tuple of (headers, results) """ - if delim: - headers = [] - results = [] - if type(sql) == type(StringType): - if comments: sql = comments(sql) - statements = filter(lambda x: len(x) > 0, - map(lambda statement: statement.strip(), sql.split(delim))) - else: - statements = [sql] - for a in statements: - self.__execute__(a, params, bindings, maxrows=maxrows) - headers.append(self.headers) - results.append(self.results) - self.headers = headers - self.results = results - else: - self.__execute__(sql, params, bindings, maxrows=maxrows) - return (self.headers, self.results) + def raw(self, sql, params=None, bindings=None, delim=None, comments=comments, maxrows=None): + """ execute the sql and return a tuple of (headers, results) """ + if delim: + headers = [] + results = [] + if type(sql) == type(StringType): + if comments: sql = comments(sql) + statements = filter(lambda x: len(x) > 0, + map(lambda statement: statement.strip(), sql.split(delim))) + else: + statements = [sql] + for a in statements: + self.__execute__(a, params, bindings, maxrows=maxrows) + headers.append(self.headers) + results.append(self.results) + self.headers = headers + self.results = results + else: + self.__execute__(sql, params, bindings, maxrows=maxrows) + return (self.headers, self.results) - def callproc(self, procname, params=None, bindings=None, maxrows=None): - """ execute a stored procedure """ - cur = self.begin() - try: - cur.callproc(procname, params=params, bindings=bindings, maxrows=maxrows) - finally: - self.commit(cur) - self.display() + def callproc(self, procname, params=None, bindings=None, maxrows=None): + """ execute a stored procedure """ + cur = self.begin() + try: + cur.callproc(procname, params=params, bindings=bindings, maxrows=maxrows) + finally: + self.commit(cur) + self.display() - def pk(self, table, owner=None, schema=None): - """ display the table's primary keys """ - cur = self.begin() - cur.primarykeys(schema, owner, table) - self.commit(cur) - self.display() + def pk(self, table, owner=None, schema=None): + """ display the table's primary keys """ + cur = self.begin() + cur.primarykeys(schema, owner, table) + self.commit(cur) + self.display() - def fk(self, primary_table=None, foreign_table=None, owner=None, schema=None): - """ display the table's foreign keys """ - cur = self.begin() - if primary_table and foreign_table: - cur.foreignkeys(schema, owner, primary_table, schema, owner, foreign_table) - elif primary_table: - cur.foreignkeys(schema, owner, primary_table, schema, owner, None) - elif foreign_table: - cur.foreignkeys(schema, owner, None, schema, owner, foreign_table) - self.commit(cur) - self.display() + def fk(self, primary_table=None, foreign_table=None, owner=None, schema=None): + """ display the table's foreign keys """ + cur = self.begin() + if primary_table and foreign_table: + cur.foreignkeys(schema, owner, primary_table, schema, owner, foreign_table) + elif primary_table: + cur.foreignkeys(schema, owner, primary_table, schema, owner, None) + elif foreign_table: + cur.foreignkeys(schema, owner, None, schema, owner, foreign_table) + self.commit(cur) + self.display() - def table(self, table=None, types=("TABLE",), owner=None, schema=None): - """If no table argument, displays a list of all tables. If a table argument, - displays the columns of the given table.""" - cur = self.begin() - if table: - cur.columns(schema, owner, table, None) - else: - cur.tables(schema, owner, None, types) - self.commit(cur) - self.display() + def table(self, table=None, types=("TABLE",), owner=None, schema=None): + """If no table argument, displays a list of all tables. If a table argument, + displays the columns of the given table.""" + cur = self.begin() + if table: + cur.columns(schema, owner, table, None) + else: + cur.tables(schema, owner, None, types) + self.commit(cur) + self.display() - def proc(self, proc=None, owner=None, schema=None): - """If no proc argument, displays a list of all procedures. If a proc argument, - displays the parameters of the given procedure.""" - cur = self.begin() - if proc: - cur.procedurecolumns(schema, owner, proc, None) - else: - cur.procedures(schema, owner, None) - self.commit(cur) - self.display() + def proc(self, proc=None, owner=None, schema=None): + """If no proc argument, displays a list of all procedures. If a proc argument, + displays the parameters of the given procedure.""" + cur = self.begin() + if proc: + cur.procedurecolumns(schema, owner, proc, None) + else: + cur.procedures(schema, owner, None) + self.commit(cur) + self.display() - def stat(self, table, qualifier=None, owner=None, unique=0, accuracy=0): - """ display the table's indicies """ - cur = self.begin() - cur.statistics(qualifier, owner, table, unique, accuracy) - self.commit(cur) - self.display() + def stat(self, table, qualifier=None, owner=None, unique=0, accuracy=0): + """ display the table's indicies """ + cur = self.begin() + cur.statistics(qualifier, owner, table, unique, accuracy) + self.commit(cur) + self.display() - def typeinfo(self, sqltype=None): - """ display the types available for the database """ - cur = self.begin() - cur.gettypeinfo(sqltype) - self.commit(cur) - self.display() + def typeinfo(self, sqltype=None): + """ display the types available for the database """ + cur = self.begin() + cur.gettypeinfo(sqltype) + self.commit(cur) + self.display() - def tabletypeinfo(self): - """ display the table types available for the database """ - cur = self.begin() - cur.gettabletypeinfo() - self.commit(cur) - self.display() + def tabletypeinfo(self): + """ display the table types available for the database """ + cur = self.begin() + cur.gettabletypeinfo() + self.commit(cur) + self.display() - def schema(self, table, full=0, sort=1, owner=None): - """Displays a Schema object for the table. If full is true, then generates - references to the table in addition to the standard fields. If sort is true, - sort all the items in the schema, else leave them in db dependent order.""" - print >> self.out, str(Schema(self, table, owner, full, sort)) + def schema(self, table, full=0, sort=1, owner=None): + """Displays a Schema object for the table. If full is true, then generates + references to the table in addition to the standard fields. If sort is true, + sort all the items in the schema, else leave them in db dependent order.""" + print >> self.out, str(Schema(self, table, owner, full, sort)) - def bulkcopy(self, dst, table, include=[], exclude=[], autobatch=0, executor=executor): - """Returns a Bulkcopy object using the given table.""" - if type(dst) == type(""): - dst = dbexts(dst, cfg=self.dbs) - bcp = Bulkcopy(dst, table, include=include, exclude=exclude, autobatch=autobatch, executor=executor) - return bcp + def bulkcopy(self, dst, table, include=[], exclude=[], autobatch=0, executor=executor): + """Returns a Bulkcopy object using the given table.""" + if type(dst) == type(""): + dst = dbexts(dst, cfg=self.dbs) + bcp = Bulkcopy(dst, table, include=include, exclude=exclude, autobatch=autobatch, executor=executor) + return bcp - def bcp(self, src, table, where='(1=1)', params=[], include=[], exclude=[], autobatch=0, executor=executor): - """Bulkcopy of rows from a src database to the current database for a given table and where clause.""" - if type(src) == type(""): - src = dbexts(src, cfg=self.dbs) - bcp = self.bulkcopy(self, table, include, exclude, autobatch, executor) - num = bcp.transfer(src, where, params) - return num + def bcp(self, src, table, where='(1=1)', params=[], include=[], exclude=[], autobatch=0, executor=executor): + """Bulkcopy of rows from a src database to the current database for a given table and where clause.""" + if type(src) == type(""): + src = dbexts(src, cfg=self.dbs) + bcp = self.bulkcopy(self, table, include, exclude, autobatch, executor) + num = bcp.transfer(src, where, params) + return num - def unload(self, filename, sql, delimiter=",", includeheaders=1): - """ Unloads the delimited results of the query to the file specified, optionally including headers. """ - u = Unload(self, filename, delimiter, includeheaders) - u.unload(sql) + def unload(self, filename, sql, delimiter=",", includeheaders=1): + """ Unloads the delimited results of the query to the file specified, optionally including headers. """ + u = Unload(self, filename, delimiter, includeheaders) + u.unload(sql) class Bulkcopy: - """The idea for a bcp class came from http://object-craft.com.au/projects/sybase""" - def __init__(self, dst, table, include=[], exclude=[], autobatch=0, executor=executor): - self.dst = dst - self.table = table - self.total = 0 - self.rows = [] - self.autobatch = autobatch - self.bindings = {} + """The idea for a bcp class came from http://object-craft.com.au/projects/sybase""" + def __init__(self, dst, table, include=[], exclude=[], autobatch=0, executor=executor): + self.dst = dst + self.table = table + self.total = 0 + self.rows = [] + self.autobatch = autobatch + self.bindings = {} - include = map(lambda x: x.lower(), include) - exclude = map(lambda x: x.lower(), exclude) + include = map(lambda x: x.lower(), include) + exclude = map(lambda x: x.lower(), exclude) - _verbose = self.dst.verbose - self.dst.verbose = 0 - try: - self.dst.table(self.table) - if self.dst.results: - colmap = {} - for a in self.dst.results: - colmap[a[3].lower()] = a[4] - cols = self.__filter__(colmap.keys(), include, exclude) - for a in zip(range(len(cols)), cols): - self.bindings[a[0]] = colmap[a[1]] - colmap = None - else: - cols = self.__filter__(include, include, exclude) - finally: - self.dst.verbose = _verbose + _verbose = self.dst.verbose + self.dst.verbose = 0 + try: + self.dst.table(self.table) + if self.dst.results: + colmap = {} + for a in self.dst.results: + colmap[a[3].lower()] = a[4] + cols = self.__filter__(colmap.keys(), include, exclude) + for a in zip(range(len(cols)), cols): + self.bindings[a[0]] = colmap[a[1]] + colmap = None + else: + cols = self.__filter__(include, include, exclude) + finally: + self.dst.verbose = _verbose - self.executor = executor(table, cols) + self.executor = executor(table, cols) - def __str__(self): - return "[%s].[%s]" % (self.dst, self.table) + def __str__(self): + return "[%s].[%s]" % (self.dst, self.table) - def __repr__(self): - return "[%s].[%s]" % (self.dst, self.table) + def __repr__(self): + return "[%s].[%s]" % (self.dst, self.table) - def __getattr__(self, name): - if name == 'columns': - return self.executor.cols + def __getattr__(self, name): + if name == 'columns': + return self.executor.cols - def __filter__(self, values, include, exclude): - cols = map(lambda col: col.lower(), values) - if exclude: - cols = filter(lambda x, ex=exclude: x not in ex, cols) - if include: - cols = filter(lambda x, inc=include: x in inc, cols) - return cols + def __filter__(self, values, include, exclude): + cols = map(lambda col: col.lower(), values) + if exclude: + cols = filter(lambda x, ex=exclude: x not in ex, cols) + if include: + cols = filter(lambda x, inc=include: x in inc, cols) + return cols - def format(self, column, type): - self.bindings[column] = type + def format(self, column, type): + self.bindings[column] = type - def done(self): - if len(self.rows) > 0: - return self.batch() - return 0 + def done(self): + if len(self.rows) > 0: + return self.batch() + return 0 - def batch(self): - self.executor.execute(self.dst, self.rows, self.bindings) - cnt = len(self.rows) - self.total += cnt - self.rows = [] - return cnt + def batch(self): + self.executor.execute(self.dst, self.rows, self.bindings) + cnt = len(self.rows) + self.total += cnt + self.rows = [] + return cnt - def rowxfer(self, line): - self.rows.append(line) - if self.autobatch: self.batch() + def rowxfer(self, line): + self.rows.append(line) + if self.autobatch: self.batch() - def transfer(self, src, where="(1=1)", params=[]): - sql = "select %s from %s where %s" % (", ".join(self.columns), self.table, where) - h, d = src.raw(sql, params) - if d: - map(self.rowxfer, d) - return self.done() - return 0 + def transfer(self, src, where="(1=1)", params=[]): + sql = "select %s from %s where %s" % (", ".join(self.columns), self.table, where) + h, d = src.raw(sql, params) + if d: + map(self.rowxfer, d) + return self.done() + return 0 class Unload: - """Unloads a sql statement to a file with optional formatting of each value.""" - def __init__(self, db, filename, delimiter=",", includeheaders=1): - self.db = db - self.filename = filename - self.delimiter = delimiter - self.includeheaders = includeheaders - self.formatters = {} + """Unloads a sql statement to a file with optional formatting of each value.""" + def __init__(self, db, filename, delimiter=",", includeheaders=1): + self.db = db + self.filename = filename + self.delimiter = delimiter + self.includeheaders = includeheaders + self.formatters = {} - def format(self, o): - if not o: - return "" - o = str(o) - if o.find(",") != -1: - o = "\"\"%s\"\"" % (o) - return o + def format(self, o): + if not o: + return "" + o = str(o) + if o.find(",") != -1: + o = "\"\"%s\"\"" % (o) + return o - def unload(self, sql, mode="w"): - headers, results = self.db.raw(sql) - w = open(self.filename, mode) - if self.includeheaders: - w.write("%s\n" % (self.delimiter.join(map(lambda x: x[0], headers)))) - if results: - for a in results: - w.write("%s\n" % (self.delimiter.join(map(self.format, a)))) - w.flush() - ... [truncated message content] |