kopf.lastig Alles mögliche zu Themen wie Familie, Beruf, Medien etc. …

2014-03-31

Emacs Org Babel SQL with Oracle DB

Filed under: Software-Entwicklung — Schlagwörter: , , — Erik @ 23:04

The outstanding Emacs Org-mode enables you to include source code blocks our text. Org-Babel then enables you to execute that code.
Yesterday I came across the Orgmode cookbook. In a section it shows how to write a SQL statement and execute it agains a postgresql database. Very nice I thought, but what about Oracle DB? Because that what I use at work.

No official support

Oracle DB is not supported as of now. There is a proposed patch. It adds the call to sqlplus, Oracle DBs command line client. But on the mailing list there was no discussion about it. 🙁 One trick it applies is to add the „.sql“ suffix to the input file to sqlplus.
[sourcecode language=“lisp“]
(in-file (org-babel-temp-file „sql-in-“ „.sql“))
[/sourcecode]

So now I got the following code that is an additional branch in the org-babel-execute:sql function:
[sourcecode language=“lisp“]
(‚oracle (format
„sqlplus -s %s“
(cond ( (and dbuser dbhost dbpassword)
(format „%s/%s@%s @%s > %s“
dbuser dbpassword dbhost
(org-babel-process-file-name in-file)
(org-babel-process-file-name out-file)
)
)
;; user specified dbuser, dbpassword, & dbhost
( (or dbuser dbhost dbpassword)
(error (format „Must specify dbuser/dbpassword@dbhost, missing %s %s %s“
(if dbuser „“ „:dbuser“)
(if dbpassword „“ „:dbpassword“)
(if dbhost „“ „:dbhost“)
)
)
) ;; if one specified, they all must be
( t
(format „%s @%s > %s“
(or cmdline „“)
(org-babel-process-file-name in-file)
(org-babel-process-file-name out-file)
)
))))

[/sourcecode]

Formating the result

Now I got the SQL executing against my db. The output was a bit weired. I experimented with sqlplus formatting with mixed results.

I consulted the elisp source. The result is converted into an orgmode table using TAB as a delimiter. In an example that had two rather long columns with short column names, sqlplus used several tabs between the two column names and so screwed the output quite a bit.

I don’t have a good solution for that. My workaround is to use comma as a column seperator (set colsep ',') and let orgmode guess that. For that I had to touch one line:
[sourcecode language=“lisp“]
(org-table-import out-file (if (eq (intern engine) ‚oracle) nil ‚(16)))
[/sourcecode]

Also I deleted the first empty line using an oracle-branch in org-babel-result-cond/with-temp-buffer:
[sourcecode language=“lisp“]
((eq (intern engine) ‚oracle)
(with-temp-buffer
(insert-file-contents out-file)
(goto-char (point-min))
(kill-line)
(write-file out-file)))
[/sourcecode]

Conclusion

In principle, it works. How nice formatted the output it is, depends on your query. When just documenting a query, as an alternative to orgmode I use SQL-Mode and format the result myself.

2014-03-25

JavaMail ignores timeout from POP3 server

Filed under: Java,Software-Entwicklung — Schlagwörter: , — Erik @ 19:37

At work our application reads email from a number of POP3 servers using JavaMail. If you trigger the POP3 server’s timeout the session is closed silently und JavaMail does not complain on session.close. In the result, the message is not deleted and will be processed again on the next turn of the background processing task. To fix this, you need to check the state of the POP3 folder after processing each message. Read on for more details on this issue.

Problem

Some of the mails our application is getting are not only „messages“ meant to be read by humans but contain structured information that is processed. This means DB operations. Processing takes not more than a few seconds – unless the Oracle DB optimizer chooses to take a bad SQL execution plan. At least this is what happened to us last week: the processing of a structured message took like 20 minutes.

The symptom then was that after the application was finished processing the email, it did not deleted the message from the server. It then started processing the mail in the next turn. As we found out the POP3 server (qpopper) has configured a timeout of five minutes. After that it answers with an „-ERR“ status code to the next client command. The code we used to process the mail was roughly this:

[sourcecode language=“java“]
try {
mail = pop3Folder.getMessage(mailIndex + 1);
// … do something with mail …
} finally {
mail.setFlag(Flags.Flag.DELETED, true);
}
folder.close();
[/sourcecode]

When setting the delete flag, JavaMail sends the DELE command. That was answered with „-ERR“ (from POP3 protocol exchange):

C: STAT
S: +OK 1 1866
C: RETR 1
S: ...
C: DELE 1
S: -ERR POP timeout from some.host
C: QUIT
S: +OK Pop server at some.host signing off.

and the session is gone. Using session.close did not complain. So no exception occured. In fact, if an exception had occured we already had an compensation mechanism that would have prevented processing the same mail again. Also it would have pointed us to the problem more directly.

Solution

The solution is to check the protocol state using folder.isOpen after processing a mail.

If that folder is not open, the mails you have so far processed have not been deleted because in POP3, mails are deleted when closing a folder. So open the folder again and delete all messages (messageRead) that you have processed before. Then carry on, i.e. close the folder.

[sourcecode language=“java“]
boolean isOpen = folder.isOpen();
if (!isOpen) {
folder.open(Folder.READ_WRITE);
final int mailCount = folder.getMessageCount();
for(int i = 1; i <= Math.min(messageRead, mailCount); i++) {
Message mail = folder.getMessage(i);
mail.setFlag(Flags.Flag.DELETED, true);
}
}
// folder.close in „normal“ code flow
[/sourcecode]

The folder.isOpen sends a NOOP command and evaluates the response, so the „-ERR“ server code is not gone unnoticed.

Doing it right

POP3 was designed to download mails rather quickly. A better solution is to fetch emails from POP3, store it somewhere and only then process them („offline“).

2014-03-24

Migration von PHPGedView nach Webtrees

Filed under: Ahnenforschung — Schlagwörter: — Erik @ 18:48

Nach dem Upgrade der PHP-Version läuft die hier installierte PHPGedView Version meines Online-Stammbaums nicht mehr korrekt. Ich hatte schon seit einiger Zeit mit dem Umstieg auf webtrees geliebäugelt, weil es im Gegensatz zu PHPGedView aktiv weiterentwickelt wird. Hier ist also die webtrees-Variante meines Online-Stammbaumes. Die Installation und die Übernahme der Daten aus PHPGedView war problemlos.

Die Integration von Google-Maps ist ganz nett, auch wenn ich noch nicht verstehe, wann Orte auf der Karte dargestellt werden, z. B. für Johann Dobrynski, der in die USA ausgewandert ist. Hier wird die Position des westpreußischen Taufortes angegeben (Google kennt also den „alten“ deutschen Namen), aber die US-amerikanischen Orte werden nicht angezeigt.

Ein Privatsphären-Merkmal hat mich zunächst stutzig gemacht. Beispielsweise sieht man bei meinem Großvater Ernst Karl Pischel als anonymer Besucher nicht, ob und mit wem er verheiratet war (z.B. rechte Seitenleiste), auch die „eigene Familie“ (also die mit seiner Frau) wird nicht angezeigt. Dies liegt daran, dass es in der Familie lebende Kinder gibt, schreiben die Entwickler. Sie begründen dieses Verhalten damit, dass bei der einfachen „Verdeckung“ noch lebender Person (z.B. Anzeige als „vertrauliche Person“ o.ä.) doch Rückschlüsse gezogen werden können, z.B. zum Geburtsort, zur Legimität etc. Auch auf Fotos könnten lebende Person abgebildet werden. Das ist konsequent, macht die Präsentation für den Besucher jedoch auch nicht nachvollziehbarer.

2014-03-03

The Oracle „ADD_MONTHS“ pitfall

Filed under: Software-Entwicklung — Schlagwörter: , — Erik @ 17:38

The Oracle DB function „add_months“ adds a given number of months to a given date:

SQL> select add_months(to_date('04.03.14','dd.mm.yy'),1) as result from dual;

RESULT
--------
04.04.14

Nice. But what about 2014-02-28 plus 1 month?

SQL> select add_months(to_date('28.02.14','dd.mm.yy'),1) as result from dual;

RESULT
--------
31.03.14

Ups. It turns out that (quote from documentation)

If date is the last day of the month or if the resulting month has fewer days than the day component of date, then the result is the last day of the resulting month.

The day component of the result can even be greater than the day component of the argument date:

SQL> select add_months(to_date('28.02.14','dd.mm.yy'),120) as result from dual;

RESULT
--------
29.02.24

This was the root cause of defect in a partner system. Of course, there is already a discussion on Stackoverflow over this issue.

As an alternative, you can use interval arithmetic:

SQL> select to_date('28.02.14','dd.mm.yy') + INTERVAL '10' YEAR as result from dual;

RESULT
--------
28.02.24

Nice. But interval arithmetic is not of much help because it does not work with days that does not exist in every month.

SQL> select to_date('28.02.14','dd.mm.yy') + INTERVAL '10' YEAR as result from dual;
select to_date('28.02.14','dd.mm.yy') + INTERVAL '10' YEAR as result from dual
                                      *
ERROR in Zeile 1:
ORA-01839: date not valid for month specified

Date arithmetic is not trivial, I guess.

2014-03-01

Gehirnwäsche für Führungskräfte

Filed under: Software-Entwicklung — Erik @ 22:06

In dem gut besuchten Vortrag „Gehirnwäsche für Führungskräfte“ auf der OOP2014 hob Bernd Oesterreich zunächst darauf ab, dass „heutzutage“ viele Unternehmen eher im „komplex“-Bereich als im „kompliziert“-Bereich des Cynefin-Frameworks agieren, d.h. das „einfaches Ursache-Wirkung-Denken“ nicht mehr weiter hilft. (Das erste Mal habe ich über Cynefin aus der Präsentation „Management Brainfucks“ gelernt – ich kann nur empfehlen, die Folien – inkl. Anmerkungen – durchzublättern. Cynefin beginnt ca. ab Folie 50).

Dann zeigte er die sog. „Taylorwanne“. (ruhig mal nach „Taylorwanne“ googlen, da kommt gar nicht so viel). Die Message auch hier ist, dass die Komplexität im Geschäftsleben im Vergleich zum 20. Jahrhundert zunimmt. Etwas ausführlicher steht es im oose-Blog.

Die „alte“ Führungskraft sei gekennzeichnet als „rationale Entscheidungsinstanz“ und dem Motto „Wissen ist Macht“. Aber „Können“ sei das neue  „Wissen“ und die heutige Mitarbeiter sind viel selbständiger als früher.

Zielvereinbarung (uagh!) sieht Oesterreich als Versuch, das Verhalten der Mitarbeiter zu beeinflußen. „Noch mehr Management“ sei das Problem, nicht die Lösung.

Gefragt sei Management von Stabilität und Management von Instabilität.

Einige Beispiele für neue Managementformen von Bernd Oesterreich, nach der Idee, gemeinsam am und im System zu arbeiten:

  • Führungskraft vs. Führungsarbeit: sie ist Bestandteil der Arbeit eines jeden und wird kontextspezifisch ausgeführt
  • Abteilung vs. Kreis: Führungskreis und Arbeitskreise. Mitarbeiter arbeiten in allen Kreisen mit, in denen es sinnvoll ist. Die Kreise koordinieren die Arbeit untereinander.
  • Pfirsichmodell nach Wohland: Peripherie (alle, die mit den Kunden zu tun haben) und Kern (Mitglieder arbeiten der Peripherie zu)

Schließlich erwähnt er noch den „T-Shaped Employer„, also die neue Sorte Mitarbeiter, die sowohl Wissen in der Breite als auch Wissen in der Tiefe (Spezialwissen) hat.

Da ich selbst bisher immer in Matrix-Organisationen gearbeitet habe, kenne ich die „strenge Führung von oben“ nicht persönlich. Unsere Teammitglieder sind kompetent, daher sehe ich bereits „selbständige Mitarbeiter“, die nicht vieler Anleitung bedürfen. Ob die obigen Vorschläge praxistauglich sind, kann ich jedoch beurteilen. Auf jeden Fall hat der Vortrag zum Denken angeregt.

Powered by WordPress