<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>Mike&#039;s Blog &#187; bluehost</title>
	<atom:link href="http://www.brintech.net/tag/bluehost/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.brintech.net</link>
	<description>Gospel study notes and technical journal</description>
	<lastBuildDate>Sun, 01 Aug 2010 00:06:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Triggers on mySQL 5 without SUPER privilege</title>
		<link>http://www.brintech.net/triggers-on-mysql-5-without-super-privilege/</link>
		<comments>http://www.brintech.net/triggers-on-mysql-5-without-super-privilege/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 21:37:48 +0000</pubDate>
		<dc:creator>Mike</dc:creator>
				<category><![CDATA[Technical Journal]]></category>
		<category><![CDATA[Technology Recipes]]></category>
		<category><![CDATA[bluehost]]></category>
		<category><![CDATA[fat free crm]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[trigger]]></category>

		<guid isPermaLink="false">http://www.brintech.net/?p=438</guid>
		<description><![CDATA[As people should know, MySQL 5.0 introduced several new features, with triggers among them. However, creating triggers require a user with SUPER privilege, which is not something the database administrator is willing to spread easily.
The full story of how I came to this solution and how it works can be found in my blog (off [...]]]></description>
			<content:encoded><![CDATA[<p>As people should know, MySQL 5.0 introduced several new features, with triggers among them. However, creating triggers require a user with SUPER privilege, which is not something the database administrator is willing to spread easily.</p>
<p>The full story of how I came to this solution and how it works can be found in my blog (off site). The gist of it is that a normal user can request a trigger creation or removal by filling a table record, and this program, running as a cron job, will check if the request is appropriate and if so it will comply with the user&#8217;s request.</p>
<p>The source code follows.</p>
<pre><code>
#!/usr/bin/perl

# addtriggers
#
# Device to add triggers on demand in databases assigned
# to users without SUPER privilege.
#
# It is intended to be run as a cron job from a user with
# SUPER privileges and full access to all the concerned databases.
#
# Set username and password for this user in a ~/.my.cnf file
# under the label [trigger_creator]
#
# See the docs at http://datacharmer.blogspot.com/

package main;
use strict;
use warnings;
use English qw( -no_match_vars );
use Data::Dumper;
use DBI;
use Carp;

our $VERSION    = '0.2';
our $DEBUG      = $ENV{DEBUG};

my $dbh=DBI->connect('dbi:mysql:stardata1;host=localhost'
            . ";mysql_read_default_file=$ENV{HOME}/.my.cnf"
            . ';mysql_read_default_group=trigger_creator',
                undef,
                undef,
                {RaiseError => 1, PrintError=> 0})
         or die "Can't connect: $DBI::errstr\n";

my $database_list_query = qq{
    SELECT DISTINCT
        table_schema
    FROM
        information_schema.tables
    WHERE
        table_name ='trigger_request'};

my $databases = safe_selectcol_arrayref($dbh, $database_list_query,und
+ef);

for my $db (@$databases) {
    use_db($dbh,$db);
    #
    # no need to check anymore: the initial query ensures that
    # only databases with a trigger_request tables are inspected
    #
    # my ($trigger_request) = $dbh->selectrow_array(
    #    qq{SHOW TABLES LIKE 'trigger_request'});
    # next unless $trigger_request;

    #
    # create the trigger_answer table
    #
    safe_do(
            $dbh,
            qq{create table if not exists trigger_answer
                (trigger_name varchar(50) not null primary key,
                TS timestamp, result text) }
            );

    #
    # collects the list of triggers to be created
    #
    my $triggers = safe_selectall_arrayref(
            $dbh,
            qq{select trigger_name, coalesce(trigger_body, '') as trig
+ger_body
                from trigger_request where done = 0},
            {Slice => {}}
            );

    #
    # collects the list of existing triggers, so we know which
    # ones we need to drop before creation
    #

    my $existing_triggers_list = safe_selectcol_arrayref(
            $dbh,
            qq{select trigger_name
               from information_schema.triggers
               where trigger_schema = ?},
            undef, $db);

    my %existing_triggers = map { $_, 1 } @$existing_triggers_list;

    #
    # trigger creation loop
    #
    TRIGGERS:
    for my $trig (@$triggers)
    {
        if ($DEBUG) {
            print "DB: $db\n", Data::Dumper->Dump([$trig],['trig']);
        }
        last TRIGGERS unless exists $trig->{trigger_name};
        last TRIGGERS unless exists $trig->{trigger_body};
        my $result = undef;
        #
        # removing trailing spaces from trigger definition
        #
        $trig->{trigger_body} =~ s/^\s+//x;
        $trig->{trigger_body} =~ s/\s+$//x;
        #
        # sanitizing check. We are going to execute only queries that
+are
        # trigger creations, without any database specification
        #
        if ( ( $trig->{trigger_body} eq q{} ) # = only drop trigger re
+quest
                                              # Notice that the query
+will convert
                                              # any NULL trigger body
+to ''
              or
              ($trig->{trigger_body} =~ /^\s* create \s+ trigger \s+ $
+trig->{trigger_name}/xi) )
        {

            #
            # more sanitizing checks
            #

            if (my ($tdb,$ttable) = $trig->{trigger_body} =~ /(\w+|`[^
+`]+`)\.(\w+|`[^`]+`)/xi)
            {
                if ($tdb ne $db)
                {
                    set_result(
                        $dbh,
                        $trig->{trigger_name},
                        "REJECTED: Attempt at using database $tdb from
+ database $db");
                    next TRIGGERS;
                }
            }

            #
            # The requested trigger will be dropped first, if exists.
            #
            if (exists $existing_triggers{$trig->{trigger_name}}) {
                eval {
                    $dbh->do(qq[drop trigger $trig->{trigger_name}] )
+;
                } ;
                if ($EVAL_ERROR) {
                    set_result(
                        $dbh,
                        $trig->{trigger_name},
                        $EVAL_ERROR);
                    next TRIGGERS;
                }
                else {
                    $result = 'OK';
                }
            }
            if ( $trig->{trigger_body} ne q{} )  { # if the body is em
+pty, skip the creation
                #
                # for future versions of MySQL. Starting 5.0.17 a DEFI
+NER clause
                # can be used.
                #
                $trig->{trigger_body} =~ s{^\s* create}{CREATE /*!5001
+7 DEFINER=CURRENT_USER*/ }xi;

                #
                # This is the main point. The trigger is created here
                #
                eval {
                    $dbh->do($trig->{trigger_body});
                };
                if ($EVAL_ERROR) {
                    $result = $EVAL_ERROR;
                }
                else {
                    $result = 'OK';
                }
            }
        }
        #
        # if the initial check failed, we report that such query was
        # not accepted
        #
        else {
            $result = 'SQL command not recognized as a CREATE TRIGGER'
+;
        }
        #
        # finally, we report the results
        # to the trigger_answer table
        set_result( $dbh, $trig->{trigger_name}, $result);
    }
}

sub set_result {
    my ($dbh,$trigger_name, $result) = @_;
    $result =~ s/^ .* do failed: \s* //x;
    $result =~ s/at \s+ line \s+ \d+ \s+ at \s+ \S+ \s+ line \s+ \d+ \
+W*$//x;
    safe_do(
        $dbh,
        qq{insert into trigger_answer (trigger_name, result) values (?
+, ?)
           on duplicate key update result = ?},
        undef,
        $trigger_name, $result, $result);

    safe_do(
        $dbh,
        qq{update trigger_request set done = 1 where trigger_name = ?}
+,
        undef ,
        $trigger_name);
    if ($DEBUG) {
        print "RESULT: $result\n";
    }
}

sub use_db {
    my ($dbh,$db) = @_;
    # prepared statements do not support "use database_name"
    my $save_prepare_option = $dbh->{mysql_emulated_prepare};
    $dbh->{mysql_emulated_prepare}=1;
    eval { $dbh->do(qq{use $db}) };
    if ($EVAL_ERROR) {
        croak "unable to change to database $db\n";
    }
    $dbh->{mysql_emulated_prepare}= $save_prepare_option;
}

sub safe_selectcol_arrayref {
    my ($dbh, $query, $options, @params) = @_;
    my $result;
    # This should be the normal call
    # my $result = $dbh->selectcol_arrayref($query);
    #
    # the following ugly hack is a workaround for a bug in
    # DBD::mysql 3.0002_4 (http://bugs.mysql.com/bug.php?id=15546)
    #
    eval {
        if (@params) {
            $result = $dbh->selectall_arrayref($query, $options, @para
+ms);
        }
        else {
            $result = $dbh->selectall_arrayref($query, $options);
        }
    };
    if ($EVAL_ERROR) {
        croak "error executing query: $query\n$EVAL_ERROR\n";
    }
    return [ map {$_->[0] } @$result ];
}

sub safe_do {
    my ($dbh, $query, $options, @params) = @_;
    my $result;
    eval {
        if (@params) {
            $result = $dbh->do($query,$options,@params);
        }
        else {
            $result = $dbh->do($query,$options);
        }
        if ($EVAL_ERROR) {
            croak "error executing query: $query\n$EVAL_ERROR\n";
        }
    };
    return $result;
}

sub safe_selectall_arrayref {
    my ($dbh, $query, $options, @params) = @_;
    my $result;
    eval {
        if (@params) {
            $result = $dbh->selectall_arrayref($query,$options,@params
+);
        }
        else {
            $result = $dbh->selectall_arrayref($query,$options);
        }
        if ($EVAL_ERROR) {
            croak "error executing query: $query\n$EVAL_ERROR\n";
        }
    };
    return $result;
}
</code></pre>
<p>via <a href="http://www.perlmonks.org/?node_id=515527">http://www.perlmonks.org/?node_id=515527</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.brintech.net/triggers-on-mysql-5-without-super-privilege/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing GIT on bluehost</title>
		<link>http://www.brintech.net/installing-git-on-bluehost/</link>
		<comments>http://www.brintech.net/installing-git-on-bluehost/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 18:19:46 +0000</pubDate>
		<dc:creator>mbrinson</dc:creator>
				<category><![CDATA[Technical Journal]]></category>
		<category><![CDATA[bluehost]]></category>

		<guid isPermaLink="false">http://www.brintech.net/?p=432</guid>
		<description><![CDATA[Background
It seems that Bluehost by default does not support nor tell you how to install Git. I also tried posting a query on Bluehost’s forums to see if anybody has done it before but with no luck.  So I decided to just go ahead and try this out myself.  Also note that you will need [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Background</strong></p>
<p>It seems that Bluehost by default does not support nor tell you how to install <strong>Git</strong>. I also tried posting a query on Bluehost’s forums to see if anybody has done it before but with no luck.  So I decided to just go ahead and try this out myself.  Also note that you will need to enable the SSH access on your bluehost account to do this. You can easily enable SSH on your account by sending a request to Bluehost Tech support.</p>
<p>Here are my specs from the bluehost account:</p>
<p><code>myuser@koolwal.net [~]# cat /proc/version</code></p>
<p>Output:<br />
 <code>Linux version 2.6.28-9.16.intel.BHsmp (kernel@bluehost.com) (gcc version 3.4.6 20060404 (Red Hat 3.4.6-10)) #1 SMP Sat Apr 18 11:41:59 MDT 2009<br />
 myuser@koolwal.net [~]#</code></p>
<p>Basically it is a Red Hat Linux system with 2.6.28 Linux kernel running. So now we have all the information that we need let’s get started…</p>
<p><span style="color: #008000;"><span style="text-decoration: underline;"><strong>Step 1: Download git tarball</strong></span></span></p>
<p>Log into your Bluehost account and give the following command:</p>
<p><code># wget http://kernel.org/pub/software/scm/git/git-1.6.3.3.tar.bz2</code></p>
<p><span style="text-decoration: underline;"><strong>Note:</strong></span> <em>The latest stable release version might have changed since this posting, so you need to substitute in the above command the latest git version that you would like to install or else you can continue with the git version that I ended up installing. You can checkout the latest stable release version of git <a title="git stable release" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://git-scm.com/');" href="http://git-scm.com/" target="_blank">here</a>.</em></p>
<p><span style="color: #008000;"><span style="text-decoration: underline;"><strong>Step </strong><strong>2: Extract the tarball</strong></span></span></p>
<p>Now just extract the tarball installation file in your home directory</p>
<p><code># tar -xjvf git-1.6.3.3.tar.bz2</code></p>
<p>Step 3: Compile the git program</p>
<p><code># cd git-1.6.3.3<br />
 # make</code></p>
<p>Now mostly after a while you will get the following error message and your make command will fail:</p>
<p><code>make[2]: true: Command not found<br />
 make[2]: *** [blibdirs] Error 127<br />
 make[1]: *** [all] Error 2<br />
 make: *** [all] Error 2</code></p>
<p>It seems that the true command is not installed on the bluehost servers but you type in the command true it seems that it exits:</p>
<p><code>myuser@koolwal.net [~]# true<br />
 myuser@koolwal.net [~]#</code></p>
<p>This probably means that the git make command is not able to locate the directory in which the true command sits.</p>
<p>Step 4: Fix “true”: Command not found error</p>
<p>The simplest way to fix this error is to create an empty script file called true with just the following line:</p>
<p><code>#!/bin/sh</code></p>
<p>Save and exit the file and copy it in your local bin directory after making it executable:</p>
<p><code># cd;<br />
 # chmod 755 true<br />
 # mkdir bin (if the directory does not exits)<br />
 # cp true bin/true</code></p>
<p>and now you can re-issue the make command:</p>
<p><code># cd git-1.6.3.3<br />
 # make clean<br />
 # make</code></p>
<p>and now after a while you should see the the “make” command finishes without any error.</p>
<p>Step 5: Install the git program</p>
<p>Finally you can install the git software by issuing the following command:</p>
<p><code># make install</code></p>
<p>and you should be able to execute the “git” command on your Bluehost account.</p>
<p>Step 6: Test git</p>
<p>Now it is time to test if the “git” program installed successfully or not.</p>
<p><code># mkdir test_project<br />
 # cd test_project<br />
 # git</code></p>
<p>Output:</p>
<p><code>Initialized empty Git repository in /home1/myuser/test_project/.git/</code></p>
<p>Congratulations the above output means that your “git” is working just fine and now you can use it for your project that you have been planning.</p>
<p>via <a href="http://blogs.koolwal.net/2009/07/20/howto-installing-git-on-bluehost-domain-hosted-websites/">http://blogs.koolwal.net/2009/07/20/howto-installing-git-on-bluehost-domain-hosted-websites/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.brintech.net/installing-git-on-bluehost/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
