Search code examples
phing

Phing: Reprompt after invalid database connection details


I'm writing a Phing task that needs to connect to a database using details supplied by the user.

I am able to prompt the user for the host/user/password/database and test the details using the PDOSQLExecTask.

What I don't know how to do is re-prompt the user to re-supply the details if they are found to be invalid, and keep re-prompting until they get it right.

The following block was my attempt, but it errors because Phing doesn't like when a task calls itself.

<target name="prompt-and-test-database-connection">
    <trycatch>
        <try>
            <input propertyName="db.host" message="Database host" promptChar=":" />
            <input propertyName="db.user" message="Database user" promptChar=":" />
            <input propertyName="db.pass" message="Database password" promptChar=":" />
            <input propertyName="db.name" message="Database name" promptChar=":" />
            <echo message="Testing connection..." />
            <pdosqlexec url="mysql:host=${db.host};dbname=${db.name}" userid="${db.user}" password="${db.pass}" onerror="continue">
                USE `${db.name}`;
            </pdosqlexec>
        </try>
        <catch>
            <echo level="error">Invalid database connection details.  Please try again.</echo>
            <phingcall target="prompt-and-test-database-connection" />
        </catch>
    </trycatch>
</target>

Solution

  • You can use <retry> task. Since <retry> only accepts one nested task I extracted the connection in another task. The following works for me:

    <target name="try-connection">
        <retry retryCount="3">
            <phingcall target="connection"/>
        </retry>
    </target>
    
    <target name="connection">
        <input propertyName="db.host" message="Database host" promptChar=":"/>
        <input propertyName="db.user" message="Database user" promptChar=":"/>
        <input propertyName="db.pass" message="Database password" promptChar=":"/>
        <input propertyName="db.name" message="Database name" promptChar=":"/>
        <echo message="Testing connection..."/>
        <pdosqlexec url="mysql:host=${db.host};dbname=${db.name}"
                    userid="${db.user}"
                    password="${db.pass}"
                    onerror="continue">
            USE `${db.name}`;
        </pdosqlexec>
    </target>