void frmPasteObject::GetLastResultError(pgConn *conn, PGresult *res, const wxString &msg) { lastResultError.severity = wxString(PQresultErrorField(res, PG_DIAG_SEVERITY), *conn->GetConv()); lastResultError.sql_state = wxString(PQresultErrorField(res, PG_DIAG_SQLSTATE), *conn->GetConv()); lastResultError.msg_primary = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY), *conn->GetConv()); lastResultError.msg_detail = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL), *conn->GetConv()); lastResultError.msg_hint = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_HINT), *conn->GetConv()); lastResultError.statement_pos = wxString(PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION), *conn->GetConv()); lastResultError.internal_pos = wxString(PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION), *conn->GetConv()); lastResultError.internal_query = wxString(PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY), *conn->GetConv()); lastResultError.context = wxString(PQresultErrorField(res, PG_DIAG_CONTEXT), *conn->GetConv()); lastResultError.source_file = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_FILE), *conn->GetConv()); lastResultError.source_line = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_LINE), *conn->GetConv()); lastResultError.source_function = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION), *conn->GetConv()); if (msg.IsEmpty()) lastResultError.msg_primary = conn->GetLastError(); if (!lastResultError.sql_state.IsEmpty()) if (!errMsg.EndsWith(wxT("\n"))) if (!lastResultError.msg_detail.IsEmpty()) if (!errMsg.EndsWith(wxT("\n"))) if (!lastResultError.msg_hint.IsEmpty()) if (!errMsg.EndsWith(wxT("\n"))) if (!lastResultError.statement_pos.IsEmpty()) if (!errMsg.EndsWith(wxT("\n"))) if (!lastResultError.context.IsEmpty()) if (!errMsg.EndsWith(wxT("\n"))) } void frmPasteObject::handleCopyOut(pgConn *conn, wxFile & copystream) { ret = PQgetCopyData(conn->connection(), &buf, 0); int n = copystream.Write(wxString(buf, wxConvUTF8)); if (OK && !copystream.Flush()) res = PQgetResult(conn->connection()); if (PQresultStatus(res) != PGRES_COMMAND_OK) GetLastResultError(conn, res); PQclear(res); } void frmPasteObject::handleCopyIn(pgConn *conn, wxFile & copystream, bool isbinary) { buflen = copystream.Read(buf, 1); if (PQputCopyData(conn->connection(), buf, buflen) <= 0) wxFileInputStream input(copystream); wxTextInputStream textfile(input); while (input.CanRead()) /* for each bufferload in line ... */ wxString buf1 = textfile.ReadLine() + wxT("\n"); const wxCharBuffer wc = buf1.ToUTF8(); const char *tmp = wc.data(); int lenc = strlen(tmp); if (PQputCopyData(conn->connection(), tmp, lenc) <= 0) if (PQputCopyEnd(conn->connection(), OK ? NULL : errmsg) <= 0) res = PQgetResult(conn->connection()); if (PQresultStatus(res) != PGRES_COMMAND_OK) GetLastResultError(conn, res); PQclear(res); } void frmPasteObject::do_copy(pgConn *conn, wxString & sql, wxFile & copystream) { result = conn->ExecuteOptionalResult(sql); switch (PQresultStatus(result)) handleCopyOut(conn, copystream); handleCopyIn(conn, copystream, PQbinaryTuples(result)); lastResultError.formatted_msg.Format(_("copy error: %s\n%s\n"), PQerrorMessage(conn->connection()), sql.c_str()); lastResultError.formatted_msg.Format( _("copy error: unexpected response (%d)\n%s\n"), PQresultStatus(result), sql.c_str()); PQclear(result); while ((result = PQgetResult(conn->connection())) != NULL) lastResultError.formatted_msg.Format(_("copy: unexpected response (%d)\n"), PQresultStatus(result)); if (PQresultStatus(result) == PGRES_COPY_IN) PQputCopyEnd(conn->connection(), (const char *)_("trying to exit copy mode")); PQclear(result); } void frmPasteObject::myLogNotice(const wxChar *szFormat, ...) { va_start(argptr, szFormat); wxVLogNotice(szFormat, argptr); va_end(argptr); } void frmPasteObject::copyTable(struct transfer_tag *transfer) { myLogNotice(wxT("CopyPaste=\"\n%s\""), transfer->createsql.c_str()); rc = transfer->targetconn->ExecuteVoid(transfer->createsql, false); lastResultError = transfer->targetconn->GetLastResultError(); if (!transfer->searchPath.IsEmpty()) rc = transfer->targetconn->ExecuteVoid(wxT("SET search_path=") + transfer->searchPath, false); lastResultError = transfer->targetconn->GetLastResultError(); if (transfer->sourceconn->GetDbname() == transfer->targetconn->GetDbname() && transfer->sourceconn->GetHost() == transfer->targetconn->GetHost() && transfer->sourceconn->GetPort() == transfer->targetconn->GetPort()) wxString tablenamenew = transfer->table->Getsrctable()->GetQuotedIdentifier(); if (transfer->srcschema->GetId() == transfer->targetschema->GetId()) if (tablenamenew.StartsWith(wxT("\""))) tablenamenew = tablenamenew.Mid(1, tablenamenew.length() - 1) + transfer->table->copysuffix; wxString copysql = wxT("\nINSERT INTO ") + transfer->targetschema->GetQuotedPrefix() + tablenamenew + wxT(" (SELECT * FROM ") + transfer->srcschema->GetQuotedPrefix() + transfer->table->Getsrctable()->GetQuotedIdentifier() + wxT(")\n\n"); rc = transfer->targetconn->ExecuteVoid(copysql, false); lastResultError = transfer->targetconn->GetLastResultError(); lastResultError.formatted_msg = pastemsg + wxT("\n") + lastResultError.formatted_msg; tmpFilename = wxFileName::CreateTempFileName(wxT("copytable")); tmpFile.Open(tmpFilename.c_str(), wxFile::write); if (!tmpFile.IsOpened()) lastResultError.formatted_msg = _("Can't create temporary file: ") + tmpFilename; wxString copysql = wxT("COPY ") + transfer->srcschema->GetQuotedPrefix() + transfer->table->Getsrctable()->GetQuotedIdentifier() + wxT(" TO STDOUT"); do_copy(transfer->sourceconn, copysql, tmpFile); if (lastResultError.formatted_msg.IsEmpty()) tmpFile.Close(); tmpFile.Open(tmpFilename.c_str(), wxFile::read); if (!tmpFile.IsOpened()) wxRemoveFile(tmpFilename); copysql = wxT("COPY ") + transfer->targetschema->GetQuotedPrefix() + transfer->table->Getsrctable()->GetQuotedIdentifier() + wxT(" FROM STDIN"); do_copy(transfer->targetconn, copysql, tmpFile); tmpFile.Close(); wxRemoveFile(tmpFilename); }