Friday, April 29, 2011

How do I remember which way round PRIOR should go in CONNECT BY queries

Hi everyone. I've a terrible memory. Whenever I do a CONNECT BY query in Oracle - and I do mean every time - I have to think hard and usually through trial and error work out on which argument the PRIOR should go.

I don't know why I don't remember - but I don't.

Does anyone have a handy memory mnemonic so I always remember ?

For example:

To go down a tree from a node - obviously I had to look this up :) - you do something like:

select
    *
from
    node
connect by
    prior node_id = parent_node_id
start with
    node_id = 1

So - I start with a node_id of 1 (the top of the branch) and the query looks for all nodes where the parent_node_id = 1 and then iterates down to the bottom of the tree.

To go up the tree the prior goes on the parent:

select
    *
from
    node
connect by
    node_id = prior parent_node_id
start with
    node_id = 10

So starting somewhere down a branch (node_id = 10 in this case) Oracle first gets all nodes where the parent_node_id is the same as the one for which node_id is 10.

EDIT: I still get this wrong so thought I'd add a clarifying edit to expand on the accepted answer - here's how I remember it now:

select
    *
from
    node
connect by
    prior node_id = parent_node_id
start with
    node_id = 1

The 'english language' version of this SQL I now read as...

In NODE, starting with the row in which node_id = 1, the next row selected has its parent_node_id equal to node_id from the previous (prior) row.

EDIT: Quassnoi makes a great point - the order you write the SQL makes things a lot easier.

select
    *
from
    node
start with
    node_id = 1
connect by
    parent_node_id = prior node_id

This feels a lot clearer to me - the "start with" gives the first row selected and the "connect by" gives the next row(s) - in this case the children of node_id = 1.

From stackoverflow
  • Think about the order in which the records are going to be selected: the link-back column on each record must match the link-forward column on the PRIOR record selected.

  • I always try to put the expressions in JOIN's in the following order:

    joined.column = leading.column
    

    This query:

    SELECT  t.value, d.name
    FROM    transactions t
    JOIN
            dimensions d
    ON      d.id = t.dimension
    

    can be treated either like "for each transaction, find the corresponding dimension name", or "for each dimension, find all corresponding transaction values".

    So, if I search for a given transaction, I put the expressions in the following order:

    SELECT  t.value, d.name
    FROM    transactions t
    JOIN
            dimensions d
    ON      d.id = t.dimension
    WHERE   t.id = :myid
    

    , and if I search for a dimension, then:

    SELECT  t.value, d.name
    FROM    dimensions d
    JOIN
            transactions t
    ON      t.dimension = d.id
    WHERE   d.id = :otherid
    

    Ther former query will most probably use index scans first on (t.id), then on (d.id), while the latter one will use index scans first on (d.id), then on (t.dimension), and you can easily see it in the query itself: the searched fields are at left.

    The driving and driven tables may be not so obvious in a JOIN, but it's as clear as a bell for a CONNECT BY query: the PRIOR row is driving, the non-PRIOR is driven.

    That's why this query:

    SELECT  *
    FROM    hierarchy
    START WITH
            id = :root
    CONNECT BY
            parent = PRIOR id
    

    means "find all rows whose parent is a given id". This query builds a hierarchy.

    This can be treated like this:

    connect_by(row) {
      add_to_rowset(row);
    
      /* parent = PRIOR id */
      /* PRIOR id is an rvalue */
      index_on_parent.searchKey = row->id;
    
      foreach child_row in index_on_parent.search {
        connect_by(child_row);
      }
    }
    

    And this query:

    SELECT  *
    FROM    hierarchy
    START WITH
            id = :leaf
    CONNECT BY
            id = PRIOR parent
    

    means "find the rows whose id is a given parent". This query builds an ancestry chain.

    Always put PRIOR in the right part of the expression.

    Think of PRIOR column as of a constant all your rows will be searched for.

    Nick Pierpoint : I like "Always put PRIOR in the right part of the expression" - it does make it easier. Also putting "start with" at the start.

What bad habits did you learn from one language that you transferred to another?

I know I've sure transferred a lot of habits between languages. I found that I tried transferring Python style to C# a lot. What sorts of habits did transfer between langugages like this?

From stackoverflow
  • Mixins in C++ use multiple inheritance.. Something that's not available in a lot of modern languages. I used to use this kindof approach a lot.

    I wouldn't say it what as a bad habbit though, I just needed to rethink the way I did things :) (If any Mixin reads this, I still love you. You are my one true love <3 )

  • Assembly Language mind set makes me think every now and then, "yeah, but how many clock cycles is that using"

    David Lehavi : which is not necessarily always bad...
  • Well, using hashes like a normal person without thousands of superfluous and stupid key-existence checks, like one does in, say, Perl, is a bad habit in PHP.

    Though I don't exactly feel like it's the habit that's bad, there.

  • After cutting my teeth as a classic VB desktop programmer in the 90's I'm very used to code-behind and the whole event-driven model of programming. So I easily transitioned to ASP.NET webforms with similar events and code-behind, but many people now say that is bad design and doesn't follow the ways of the web (unlike ASP.NET MVC).

    The "bad" way just seems so natural to me...probably due to my VB6 days.

  • In the D programming language: Using template metaprogramming for everything. I've gotten so spoiled by D's templates that I have no idea how anyone gets anything done in any other statically typed language anymore.

  • returning closures in Lua and Python is very natural and convenient. The same in JavaScript works, but it's a great PITA and requires a bit too much extra typing to be readable.

  • In FORTRAN 77, it's very common to use I, J and K as loop control variables in a DO loop. I still use i, j and k when writing FOR loops in Ada, C, C++ or whatever language I'm coding in, even though I haven't written a single line of FORTRAN for over 10 years.

    People often make comments about it but I refuse to accept that there are better loop control variable names! I also feel the compulsion to rewrite other people's FOR loops to use i, j and k because the code looks too verbose otherwise!

  • I learned to program (truly) with C++, which meant I was stuck with the clunky STL, as I didn't know how to use external libraries at the time. Needless to say, I wound up rolling my own solutions to a number of standard api-solved problems.

    The biggest thing I learned in my transition to Java was to trust pre-existing solutions over my own. The Java API has a wealth of obscure classes that fit extraordinarily well to certain problems, with the added bonus of a defined standard usage.

  • After using Haskell and Lua, it bugs me that I can't write this in C/C++:

    int, int foo() {
        return 2, 3;
    }
    int a, b;
    a, b = foo();
    

How to know when to manage resources in Python

I hope I framed the question right. I am trying to force myself to be a better programmer. By better I mean efficient. I want to write a program to identify the files in a directory and read each file for further processing. After some shuffling I got to this:

for file in os.listdir(dir):
    y=open(dir+'\\'+file,'r').readlines()
    for line in y:
        pass
    y.close()

It should be no surprise that I get an AttributeError since y is a list. I didn't think about that when I wrote the snippet.

I am thinking about this and am afraid that I have five open files (there are five files in the directory specified by dir.

I can fix the code so it runs and I explicitly close the files after opening them. I am curious if I need to or if Python handles closing the file in the next iteration of the loop. If so then I only need to write:

for file in os.listdir(dir):
    y=open(dir+'\\'+file,'r').readlines()
    for line in y:
        pass

I am guessing that it(python) does handle this effortlessly. The reason I think that this might be handled is that I have changed the object/thing that y is referencing. When I start the second iteration there are no more memory references to the file that was opened and read using the readlines method.

From stackoverflow
  • Python will close open files when they get garbage-collected, so generally you can forget about it -- particularly when reading.

    That said, if you want to close explicitely, you could do this:

    for file in os.listdir(dir):
        f = open(dir+'\\'+file,'r')
        y = f.readlines()
        for line in y:
            pass
        f.close()
    

    However, we can immediately improve this, because in python you can iterate over file-like objects directly:

    for file in os.listdir(dir):
        y = open(dir+'\\'+file,'r')
        for line in y:
            pass
        y.close()
    

    Finally, in recent python, there is the 'with' statement:

    for file in os.listdir(dir):
        with open(dir+'\\'+file,'r') as y:
            for line in y:
                pass
    

    When the with block ends, python will close the file for you and clean it up.

    (you also might want to look into os.path for more pythonic tools for manipulating file names and directories)

    PyNEwbie : for file in os.listdir(dir): for line in open(dir+'\\'+file,'r'): pass Your suggestion led to this.
    kquinn : On Python 2.5 or better, I'd prefer the `with` statement forms, which clearly communicate the intent of the code.
    John Fouhy : Yup. Note that you have to do a __future__ import to get it in python 2.5.
    Jarret Hardie : +1 for suggesting os.path
  • Don't worry about it. Python's garbage collector is good, and I've never had a problem with not closing file-pointers (for read operations at least)

    If you did want to explicitly close the file, just store the open() in one variable, then call readlines() on that, for example..

    f = open("thefile.txt")
    all_lines = f.readlines()
    f.close()
    

    Or, you can use the with statement, which was added in Python 2.5 as a from __future__ import, and "properly" added in Python 2.6:

    from __future__ import with_statement # for python 2.5, not required for >2.6
    
    with open("thefile.txt") as f:
        print f.readlines()
    
    # or
    
    the_file = open("thefile.txt")
    with the_file as f:
        print f.readlines()
    

    The file will automatically be closed at the end of the block.

    ..but, there are other more important things to worry about in the snippets you posted, mostly stylistic things.

    Firstly, try to avoid manually constructing paths using string-concatenation. The os.path module contains lots of methods to do this, in a more reliable, cross-platform manner.

    import os
    y = open(os.path.join(dir, file), 'r')
    

    Also, you are using two variable names, dir and file - both of which are built-in functions. Pylint is a good tool to spot things like this, in this case it would give the warning:

    [W0622] Redefining built-in 'file'
    
    PyNEwbie : This was useful thanks. My friends think I am a genious but then I show them how this web site makes it all possible.

C#: How to send keyboard scan codes manually?

I'm working on a project that needs to emulate a keypress of the Windows key. I've tried SendKeys.Send to no avail.

Specifically, the windows key needs to come in concert with a button. That is, I want to send Windows Key and plus / minus.

From stackoverflow
  • Try SendInput or the older keybd_event

  • I think your best bet is using keybd_event keydown (called ExtendedKey) with the LWin value of the System.Windows.Forms.Keys enum, then keydown second character (+), and keyup both keys.

    I do not believe SendKeys works with the Windows key as a modifier.

  • I would add that it is often unlikely for you to find lower level functions like these in the .NET framework. If you were confused as to why the suggestions both pointed to "non C#" functions, then you probably could use some details on P/Invoke.

    Basically there are ways to define C# functions that "tie" them to Windows API functions that do not exist within .NET assemblies (Instead they are typically implemented in C++ and available as a standard DLL). This process is considered to be "(Windows) Platform Invoking" (thus P/Invoke).

    It can be a bit wobbly at first to match up all the data types between C++ and C# style calls, but fortunately, there are others out there that have paved the way.

    The suggested function, SendInput, has a PInvoke wrapper over at PInvoke.net. This wrapper class, when available in your assembly, will allow you to call SendInput as if it were a C# function.

    PInvoke.net is basically a PInvoke wiki for well known API calls in windows, and typically has a C#/VB.NET wrapper of API calls.

  • This may be overkill, but you could try using AutoItX which is a way to use AutoIt as a DLL. I've only written standalone scripts, but I know AutoIt makes it very easy to simulate pressing the Windows key.

    For example, to open the run dialog is just:

    Send("#r") ;Win + R = run

how do I add a class to a CodeIgnitor anchor?

I have the following:

'.anchor('','Home').'

and I want to add the following CSS class to it:

class="top_parent"

so that when its rendered in the browser, the code will look something like

<a href="#" class="top_parent">Home</a>

Thanks in advance. Any help is hugely appreciated.

Tom

From stackoverflow
  • You can specify an associative array of attributes for your Anchor. So, for example:

    anchor('', 'Home', array('class' => 'top_parent'));

  • anchor('#', 'Home', array('class' => 'top_parent'));
    
  • The Codeignitor function is defined as such:

    function anchor($uri = '', $title = '', $attributes = '')
    

    I would try sending an array with a class key and value first.

    These functions are found inside the \system\helpers\ folder.

    NTulip : boy all that time i spend finding the function and two very talented people had answered the question already. Oh well - my answer is here to stay.

server configuration questions...

Please pardon my non-understanding here. I have a local mysql server and I need to be able to access that data over an encrypted channel from a java web application running on a web host. Can anyone recommend the best way to do this?

Thank you! Joshua

From stackoverflow
  • AFAIK MySQL does not support encrypted streams (correct me if I am wrong).

    One solution I can see would be to have an encrypted tunnel running between the MySQL server and the web host, and route connections to the database through it.

  • You'll need to set up an SSH tunnel.

  • MySQL does support SSL connections.

    Check this document for assistance: http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-using-ssl.html

  • SSH Port Forwarding

    In this instance, one could port forward db_server:3306 to web_server:3306. Then it would appear as if there were a MySQL database running locally on the web server listening on port 3306. However, localhost:3306 on the web server is really being securely forwarded to localhost:3306 on the database server.

    To set this up, you'll want a password-less key pair to allow the SSH tunnel to be started automagically. Do the following:

    db_serv$ ssh-keygen -t rsa
    db_serv$ scp .ssh/id_rsa.pub webserver:
    web_serv$ cd ~; mkdir .ssh
    web_serv$ cat id_rsa.pub >> .ssh/authorized_keys2
    web_serv$ chmod -R go-rwx .ssh; rm id_rsa.pub
    db_serv$ ssh webserver
    

    The last command should let you SSH from the database server without providing a password. The keypair does the authentication.

    The command to open an SSH tunnel is:

    db_server$ ssh -f -q -N -R3306:db_server:3306 webserver

    You can then test out local database access on the webserver. You'll need to have the permissions set correctly in the MySQL databse for the user and password you're using.

    web_serv$mysql -h 127.0.0.1 -P 3306 -u user -p db_name

    You'll probably want to add the 'ssh' line above to /etc/rc.d/rc.local (on Red Hat) so that the tunnel gets opened on reboots. Remember if the tunnel goes down, your web app can't access the database.

  • Yes, MySQL supports encrypted connections over SSL.

    You need a version of MySQL Server that has been built with either OpenSSL, or the bundled yaSSL. If your MySQL Server wasn't built with SSL support, the --ssl and related options will give errors.

    You need to start the MySQL Server (mysqld) with the --ssl option and related options to specify the SSL key and certificate. See http://dev.mysql.com/doc/refman/5.1/en/secure-connections.html for more information on enabling MySQL Server to support SSL.

    Your Java client also must support SSL. You need to supply a client certificate when you connect. See http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-using-ssl.html for more information on making secure connections to MySQL from Java.

  • This is basically the same as every other answer here, but here goes anyway. Use a VPN tunnel such as openVPN to encrypt the communication. The best part about it is the transparency. When you're on the VPN, you don't need to think about it any more, just send secure communications. Of course, setting it up is NOT the easy part...

WCF Array Serialization

I am using a WCF OperationContract that takes an array of integers as an argument. It is using basicHttpBinding.

I've noticed that the generated SOAP from a client generated using Visual Studio "Add Web Reference" includes the xmlns thus:

<ids>
  <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">100</string>
  <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">101</string>
  <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">102</string>
   ... etc
</ids>

This will increase the size of the serialized stream with large arrays. Is there any way to eliminate this xmlns attribute?

For a WCF client, the generated SOAP looks more like what I would expect:

<ids xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <a:string>100</a:string>
  <a:string>101</a:string>
  <a:string>102</a:string>
  ... etc..
</ids>
From stackoverflow
  • I'm not too familiar with serialization, but could this be the difference between SOAP 1.1 and 1.2? I'm betting that you can specify either format. Is there a compelling reason to not just use the WCF client?

    Joe : I'm using SOAP 1.1 in both cases (basicHttpBinding). I need so support legacy non-WCF clients (.NET 3.0 is not installed everywhere).
  • That's really a function of the client proxy and not your service, unfortunately. In this example, you are looking at a client using XML Serialization vs. Data Contract Serialization. One is simply better than the other at making the XML more compact.

    You might have better luck with the type generator in WSE 3.0 (link) It is possible there is a set of XML attribute tags you can put on a class to make it serialize better and maybe those were integrated into WSE, but I'm not 100% on that.

    You should let us know what you decide. Very interesting.