The basic task I wish to accomplish is relatively simple. I want to execute a database command line UPDATE bugs_fulltext SET comments = $newtext WHERE comments = $oldtext. My instinctive approach was to use placeholders. The problem I am hitting is that the new and old text may contain line breaks. I can't use an index on the table as the table is part of BugZilla and the definition has no index, hence the WHERE comments = $oldtext clause (I have other clauses to deal with duplicate comments, but that's not relevant to my problem). Unfortunately, the database may deliver line breaks as 0D or 0D0A but insists that they be entered as \n so that it can enter them in the local format. The problem is that Perl, of course, has its own setting for \n that need not be the same. Indeed, Perl's \n and the database's \n are different "\n"s. So what I need to do is to replace either 0D or 0D0A with \n.

Doing this in a simple regex seems to work. Unfortunately, the text could legitimately contain xkcd://Bobby Tables, so I still need to pass it through the placeholder. This converts my \n to \\n, which means that the WHERE clause does not match. Bind does the same thing. I then tried using split on the string to get an array of individual lines, intending to pass each line separately through db->quote and join them with \ns. Unfortunately, the regex that worked for s///g did not work in split (the exact regex was chr(13)chr(10)?). However, db->quote, getting a single line, converted the 0D0A sequences to \r\n, which might give me some leverage. If I pass the text through db->quote and then s/\\r\\n/\\n/g, I think I will get what I want. Unless, of course, the character before the R is an escaped backslash, i.e. the character group is \\r\n, when I don't want to substitute. Unless THAT is preceded by ANOTHER backslash, when I DO want to substitute. Unless (repeat ad infinitum).

So, I have two questions. Is there a better approach, given that I don't know what the localisation of Perl(\n) and database(\n) will be? Is there a way of writing s/\\r\\n/\\n/g unless preceded by an even number of backslashes, excluding the one given?

Regards,

John Davies


In reply to Line separators when passing multi-line fields to a database by davies

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.