Extending Jenkins book

My new book, Extending Jenkins by Donald Simpson, has been published!

Extending Jenkins

There is a free sample chapter available here:
Chapter 8 – Testing and Debugging Jenkins Plugins

You can buy the full book in either electronic or paperback format direct from the publishers or through Amazon here in the UK or Amazon in the US

About This Book

  • Find out how to interact with Jenkins from within Eclipse, NetBeans, and IntelliJ IDEA
  • Develop custom solutions that act upon Jenkins information in real time
  • A step-by-step, practical guide to help you learn about extension points in existing plugins and how to build your own plugin

Who This Book Is For

This book is aimed primarily at developers and administrators who are interested in taking their interaction and usage of Jenkins to the next level.

The book assumes you have a working knowledge of Jenkins and programming in general, and an interest in learning about the different approaches to customizing and extending Jenkins so it fits your requirements and your environment perfectly.

Table of Contents

1: Preparatory Steps
2: Automating the Jenkins UI
3: Jenkins and the IDE
4: The API and the CLI
5: Extension Points
6: Developing Your Own Jenkins Plugin
7: Extending Jenkins Plugins
8: Testing and Debugging Jenkins Plugins
9: Putting Things Together

What You Will Learn

  • Retrieve and act upon Jenkins information in real time
  • Find out how to interact with Jenkins through a variety of IDEs
  • Develop your own Form and Input validation and customization
  • Explore how Extension points work, and develop your own Jenkins plugin
  • See how to use the Jenkins API and command-line interface
  • Get to know how to remotely update your Jenkins configuration
  • Design and develop your own Information Radiator
  • Discover how Jenkins customization can help improve quality and reduce costs

In Detail

Jenkins CI is the leading open source continuous integration server. It is written in Java and has a wealth of plugins to support the building and testing of virtually any project. Jenkins supports multiple Software Configuration Management tools such as Git, Subversion, and Mercurial.

This book explores and explains the many extension points and customizations that Jenkins offers its users, and teaches you how to develop your own Jenkins extensions and plugins.

First, you will learn how to adapt Jenkins and leverage its abilities to empower DevOps, Continuous Integration, Continuous Deployment, and Agile projects. Next, you will find out how to reduce the cost of modern software development, increase the quality of deliveries, and thereby reduce the time to market. We will also teach you how to create your own custom plugins using Extension points.

Finally, we will show you how to combine everything you learned over the course of the book into one real-world scenario.

Green Woodturning bowls

Our neighbour let me chop up and use the wood from one of her Beech trees after it fell down in the wind.

I thought I’d try some “green” woodturning for a change and try to make her a bowl from her own tree to say thank you.

Here are some pics of the process.

 

The finished bowls…

IMG_7460

Back to the start – a freshly chainsawed log – one half per bowl:

IMG_7056

Gradually making it round:

IMG_7059

IMG_7067

 

Shaping with a bowl gouge – lots of knots and checks to work around:

IMG_7068

IMG_7074

 

One nearly completed bowl next to its sibling:

IMG_7081

I turned them “extra chunky” so if they warped while drying I could reshape them

IMG_7086

After a few months spent drying out (covered in sawdust under my lathe), I finished turning them and reduced the thickness.

Hopefully they are not going to crack or warp… time will tell!

IMG_7457IMG_7466

The finished bowls – treated with a homemade mix of bees wax & sunflower oil:

IMG_7445

Beginning Docker video course

Blog updates have been scarce recently as I have been busy working on a couple of publications… the first of which has just been released…

https://www.linuxjournal.com/node/1338951

This is a hands-on video course packed with practical examples to get you started with Docker.

Here is the course overview video:

And here is a free sample video from Section 2, “Docker Basics” where we take a look at running containers and the 3 different types of “containerized” commands:

and this final sample video is taken from Section 5 – “Running a Web Application with Docker“.

In this clip we build our own web application using Python, pip and Redis, which we will then “dockerize” and ship to “production”:

About This Video

  • Master Docker commands by creating and publishing a sample web application
  • Build and manage your own custom Docker Containers to set up data sources, filesystems, and networking
  • Build your own personal Heroku PaaS with Dokku

Who This Video Is For

If you’re a developer who wants to learn about Docker, a powerful tool to manage your applications effectively on various platforms, this course is perfect for you! It assumes basic knowledge of Linux but supplies everything you need to know to get your own Docker environment up and running.

What You Will Learn

  • Build new Docker containers and find and manage existing ones
  • Use the Docker Index, and create your own private one by using containers
  • Discover ways to automate Docker, and harness the power of containers!
  • Build your own Docker powered mini-Heroku Paas with Dokku
  • Set up Docker on your environment based on your application’s custom requirements
  • Master Docker patterns and enhancements using the Ambassador and Minimal containers

In Detail

One of the major challenges while creating an application is adapting your application to run smoothly on all of the plethora of operating systems available. Docker is an extremely efficient technology that allows you to wrap all your code along with its supporting files into a single bundle; it also guarantees that your application will behave in the same way on any host powered by Docker. You can also easily reuse existing Docker containers or create and publish your own. Unlike Virtual Machines, Docker containers are lightweight and more efficient.

Beginning Docker starts with the fundamentals of Docker—explaining how it works, how to set it up, and how to get started on leveraging the benefits of this technology. The course goes on to cover more advanced features and shows you how to create and share your own Docker images.

You will learn how to install Docker on your own machine, then how to manage it effectively, and then progress to creating and publishing your very own application. You will then learn a bit more about Docker Containers; built-in features and commands such as volumes, mounts, ports, and linking and constraining containers; before diving into running a web application.

Docker has functionality such as the Docker web API to handle complex automation processes which will be explained in detail. You will also learn how to use the Docker Hub to fetch and share containers, before running through the creation of your own Docker powered mini-Heroku

Beginning Docker covers everything required to get you up and running with Docker, with detailed real-world examples and helpful tips to make sure you get the most from it.

Style and Approach

An easy-to-follow and structured video tutorial with practical examples of Docker to help you get to grips with each and every aspect.

The course will take you on a journey from the basics to the advanced application of Docker containers, and includes several real-world scenarios to learn from.

Cheers,

Don

Installing Minecraft Forge and Pixelmon Mod

Notes on installing Minecraft Forge and setting up & running the Pixelmon Mod on Windows.

 

You need to have Minecraft installed first, then you can install Minecraft Forge which allows you to add-on and manage Minecraft Mods like Pixelmon.

There are 3 things you need:

1. Minecraft: https://minecraft.net/download
 – get the latest/current version and install it, if you haven’t already

2. Pixelmon: http://pixelmonmod.com/downloads.php
  – get the latest Recommended version; I’m going for 3.3.8, which works on Minecraft 1.7.10:

DownloadPixelmon

This should download “Pixelmon-1.7.10-3.3.7-universal.jar” or similar.

3. Minecraft Forge: http://files.minecraftforge.net/
 – open that link and download the “Installer-Win” version that matches the version of the Mod you are wanting to run – I wemt for Pixelmon 1.7.10 above, so I need the same version of Forge to run that – clicking the “*” link just after the “(Installer-Win) link as shown here should give you a direct download to the file you need:

Forgeor try this direct link http://files.minecraftforge.net/maven/net/minecraftforge/forge/1.7.10-10.13.2.1286/forge-1.7.10-10.13.2.1286-installer-win.exe

 

Once that’s downloaded run the exe and you should see a screen like this:

InstallClient_1

Leave the default “Install client” selected and take a note of the directory mentioned here (C:\Users\don\AppData\Roaming\.minecraft in my case) – this is your Minecraft install directory and you will need to know it later.

Install Java if required:

Forge_JRE1.6

If you get the error message “This application requires a Java Runtime environment 1.6.0”, you need to install a Java runtime. Ok’ing the Launch4j message box should open a link to the Oracle website where you can install the latest version of Java (you don’t need 1.6 specifically).

 

If during the Forge installation you get the message “You need to run the version 1.7.10 manually at least once”:

Forge_InstallClient_2_RUNONCE
then start-up Minecraft, click on “Edit Profile” and select “release 1.7.10” from the “Use version:” dialog as shown here:

RunMinecraft1.7.10

This step is needed as Forge creates a modified version of this specific version of Minecraft – running it once will make the Minecraft Launcher program download all of the files that are required for this version to work on your machine, which Forge will then use. Start up a normal Minecraft game using 1.7.10 then exit, and restart the Forge installation – it should work now. If you have played 1.7.10 before you should already have everything already though.

 

Once that’s done you should see a message saying something like “Successfully installed client profile Forge for version…” etc. Ok that and launch Minecraft again. You should now have a new Profile called “Forge” (see the dropdown box in the lower left corner), which you can select and Edit like this:

Forge_InstallClient_FirstPlay

You need to run Minecraft with the Forge profile whenever you want to play with a Mod, but you can select your normal profile to go back playing normal Minecraft.

Again, note that Game Directory location, and open it up in Windows Explorer:

ProfileDir_noMods

There is no “mods” directory there yet – this is created by Forge the first time it runs.
Click “Play” with the Forge Profile selected and Minecraft Forge should start-up and create the directory for you:

ForgeRunningProfileDir_NowWithMods

Now exit Minecraft and all you need to do to install Pixelmon Mod is to copy the Pixelmon-1.7.10-3.3.7-universal.jar file in to the mods directory, restart Minecraft using the Forge profile, and that should be it:

Forge_AllDone

You can see there are now 4 mods loaded, and clicking on the Mods button will show the details – all done!

 

Update: my daughters PixelMon screenshot gallery…

 

Coming soon, a write up on setting up a server running Minecraft Forge with Pixelmon on Ubuntu Linux…

Jenkins and Docker – Part One

This post lists the steps taken to get started with Docker – the basic install and getting a Docker container up and running on Ubuntu.

There’s nothing new or unusual in this section, but it forms the background of the next post(s) where I plan to go in to detail on different approaches to using Docker with Jenkins (and vice versa).

If you’re unfamiliar with Docker here is a good introduction:

and you can try Docker out easily on the docker site: https://www.docker.com/tryit/

 

 

In my case the Ubuntu is a pretty ordinary “ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-35-generic x86_64)” running as a guest VM on my Development VM Ware ESXi Server.

Installing docker on Ubuntu is trivial – here are the commands I found via a quick google, there were no issues…

apt-get -y install docker.io

(FYI it’s called docker.io as there’s a previous/existing package with the name docker)

fix path issues:

ln -sf /usr/bin/docker.io /usr/local/bin/docker
sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io

have docker start up at boot:

update-rc.d docker.io defaults

and that’s that done – all very simple, quick and straightforward, now it’s time to pull down an Ubuntu image…

docker pull ubuntu

once that’s done, you are ready to run a command (bash in the case of this quick test I found suggested elsewhere) in a docker container like so:

docker run -i -t ubuntu /bin/bash

(-i attaches stdin & stdout and -t allocates a terminal)

That’s it for this post – the next will look at dynamic Jenkins Slave provisioning using Docker Containers, Jenkins plugins for Docker and ways to use Docker for a variety of Jenkins build, deployment and test tasks for Continuous Integration, Continuous Build and DevOps purposes.

Cheers,

Don

 

 

 

 

Extracting data from Jenkins

In Part I,  Information Radiators, I covered what they are, what the main benefits are, and the approach I usually use to set them up. This post goes in to more technical detail on how I extract this data from Jenkins.

My usual setup/architecture for Jenkins Information Radiators goes something along these lines:

  • TV screens running Mozilla Firefox or Google Chrome in Kiosk Mode, and Tab Mix Plus set up to rotate tabs (if required)
  • JSP Pages served via Tomcat on Linux server (which also runs the data extracting script described below)
  • MySQL database on Linux server – contains tables with data pulled from Jenkins and other sources, and the config data too (which URL’s to monitor)

And you’ll need some Jenkins instances/jobs to monitor too, obviously 🙂

The Jenkins XML API is very useful for automating tasks like this – if you simply append “/api/xml” to a
Jenkins job URL, it will serve up an XML version – note there is also a JSON API and a CLI and plenty of other options, but I’m using what suits me.

The Jenkins XML API

For example, if you go to one of your Jenkins jobs and add /api/xml like this:

“http://yourjenkinsserver:8080/job/yourjobname/api/xml

you should get back some XML, possibly roughly like this example:

<?xml version="1.0"?>
<freeStyleBuild>
 <action>
 <parameter>
 <name>LOWER_ENV</name>
 <value>dev</value>
 </parameter>
 </action>
 <action>
 <cause>
 <shortDescription>Started by timer</shortDescription>
 </cause>
 </action>
 <building>false</building>
 <duration>61886</duration>
 <fullDisplayName>MyJob #580</fullDisplayName>
 <id>2014-04-01_10-01-50</id>
 <keepLog>false</keepLog>
 <number>580</number>
 <result>SUCCESS</result>
 <timestamp>1396342910088</timestamp>
 <url>http://jenkinsserver:8080/view/MyView/job/MyJob/580/</url>
 <builtOn/>
 <changeSet/>
</freeStyleBuild>

That XML contains loads of very useful information inside handy XML tag descriptions – you just need a way to get at that data and then you can present it as you like…

XPAth queries and the Jenkins XML API

so to automate that, I used to extend that approach a to query Jenkins via the XML API using XPAth queries to bring back just the data I actually wanted, quite like querying a database.

For example, wget’ing this URL would return just the current value of the <building> tag in the above XML:

http://yourjenkinsserver:8080/job/yourjobname/api/xml?xpath=//building/text()

e.g. “true” or “false” – this was very useful and easy to do, but the functionality was removed/disabled in recent versions of Jenkins for security reasons, meaning that my processes that used it needed rewritten 🙁

Extracting the data – Plan B…

So, here’s the new solution I went for – the real scripts/methods do some error handling and cleaning up etc but I’m just highlighting the main functions and the high level logic behind each of them here;

get_url’s method:

query a table in MySQL that contains a list of the job names and URL’s to monitor
for each $JOB_NAME found, it calls the get_file method, passing that the URL as a parameter.

get_file method:

this takes a URL param, and uses curl to fetch and save the XML data from that URL to a temporary file (“xmlfile”):

curl -sL "$1" | xmllint --format - > xmlfile

Note I’m using “xmllint –format” there to nicely format the XML data, which makes processing it later much easier.

get_data method:

this first calls “get_if_building” (see below) to see if the job is currently running or not, then it does:

TRUE_VAR="true"
 if [[ "$IS_BUILDING" == "$TRUE_VAR" ]]; then
 RESULT_TEXT="building..."
 else
 RESULT_TEXT=`grep "result>" xmlfile | awk -F\> '{print $2}' | awk -F\< '{print $1}'`
 fi

get_if_building method:

this simply checks and sets the IS_BUILDING var like so:

IS_BUILDING=`grep building xmlfile | awk -F\> '{print $2}' | awk -F\< '{print $1}'`

Putting it all together

My script then updates the MySQL database with the results from each check: success/failure, date, build number, user, change details etc

I then have JSP pages that read data from that table, and translate things like true/false in to HTML that sets the background colours (Red, Amber, Green), and shows the appropriate blocks and details per job.

If you have a few browsers/TV’s or Monitors showing these strategically placed around the office, developers get rapid feedback on the result of their code changes which speeds up development, increases quality and reduces development time and costs – and they can be fun to watch and set up too 🙂

Cheers,

Don

DIY Information Radiator

 

 

Information Radiators are used to provide people with feedback on the current status of code builds and automated tests in Continuous Integration and Agile development environments.

The basic idea is that when developers commit a code change, they can easily and quickly see that it has been picked up by the automated build process, and then (ideally within 10 minutes) see the result of their change; did the build succeeded and did the automated tests pass?

Martin Fowler’s description goes in to more detail on the ideas behind this approach and the function that Information Radiators serve.

The normal convention for these is to use colour coded blocks per build, using:

  • Green for good/passing jobs
  • Amber for either currently building/running jobs (or sometimes for unstable ones)
  • Red for failed jobs

Generally you want to keep things as clean, simple and uncluttered as possible, but sometimes it is helpful to add in a bit more info.

Details I have occasionally found worth adding include things like;

  • name and/or picture of the user who triggered (or broke!) the build
  • commit message from the code change that triggered the build
  • build number
  • history – number of recent fails or passes
  • date/time last failed and last checked

if you use amber for “unstable” rather than “build in progress”, you may want to add text to say if the job is currently building – I often use the “spinning wheel” icon thingy from jenkins itself :

spinner

Why build your own?

There are tons of readily available plugins that allow you to quickly and easily produce a Radiator or Wall panel from Jenkins, so why go to the bother of making your own?

Plugins are usually linked to one Jenkins instance (the one they are running on) and I have often found that alone to be too restrictive – having too many different radiators all over the place makes things too cluttered and uncertain, and people can easily start to “switch off” from them all – having one screen that people can understand at a glance usually works best.

Changing requirements – developers are constantly wanting/looking to improve processes and often come up with ideas and requests for things to try that may help them do their jobs – adding a bit of information from another source, for example, or changing the colours used to a different shade, or adding curved borders etc etc…

What I have found often works best, is to get all of the data I am interested in inside a database then write my own simple but flexible presentation layer from scratch – this gives me all the flexibility I could want (or may find myself wanting or needing later…) and importantly, it also allows me to leverage additional benefits by combining data from Jenkins with data from elsewhere – this means I can easily produce reports, charts, metrics etc that present a view comprised from multiple data sources throughout an organisation – for example, you can then easily create reports that combine:

  • jenkins – live information on the current state of builds and tests
  • defects – data on bugs and changes pulled from bug tracking apps (usually via jenkins jobs)
  • version control – the actual code change can be extracted from version control and linked to both the developer and bug details – the “svn log” command is useful for this
  • environment monitors – state and health of environments; database and app server health, deployed patch and code levels etc (again, these are usually other Jenkins jobs!)

and you can add in anything else you can get your hands on 🙂

This allows you to track the flow of a change right through the development life cycle – from the initial change/requirement/defect to the change itself at the code/file level, then the testing and building of it and the eventual release. This is far more than you need for a simple Information Radiator, but using this approach means that you can easily reuse much of the work in different ways.

Part II covers the technical approach I use for Extracting data from Jenkins

Minecraft Server Admin/Op commands

Minecraft Server Admin/Op commands are entered into the chat window and are preceded by a “/” when playing in-game, but when entering commands at the server console you need to miss out the preceding “/”.

(This table is copied from http://wiki.multiplay.co.uk/Minecraft/Operators and is here purely for my convenience and laziness)

Command Description Usage
help or ? Shows a list of server commands in the console or in-game. help
kick Removes player from the server with the message “Kicked by admin” kick username
ban Bans player from the server with the message “Banned by admin”, banned players who attempt to connect are presented with the message “You are banned from this server!” ban username
pardon Removes the specified player from banned-players.txt, allowing them to connect to the server again pardon username
ban-ip Bans an IP address from the server, the full IP address must be specified; wildcards are not valid. Players who are banned through this method will see “Your IP address is banned from this server!” when attempting to connect ban-ip ipaddress
pardon-ip Removes the specified IP from banned-ips.txt, allowing players with that IP to connect to the server again pardon-ip ipaddress
op Writes the players name to ops.txt, giving them access to the op commands op player
deop Removes a player from ops.txt, revoking their access to the op commands deop player
tp Moves the first player specified to the location of the second player specified tp player1 player2
give Gives a specified amount of a block, the ids are known as data values give player id amount
stop Gracefully stops the server stop
save-all Forces a server-wide level save save-all
save-off Disables terrain saving (useful for backup scripts) save-off
save-on Re-enables terrain saving. save-on
list Lists all currently connected players list
say Broadcasts a message to all players without a player name being shown and putting message in pink text say message
whitelist Enable or disable whitelisting (i.e. only listed players may join) whitelist on/off
whitelist Add or remove player from the whitelist whitelist add/remove player
whitelist list Lists all currently whitelisted players whitelist list
whitelist reload Reload the whitelist from white-list.txt whitelist reload
time Add to or set the world time. Amount may be a number between 0 and 24000, inclusive, where 0 is dawn and 12000 is dusk time add/set amount

Minecraft Server Admin tips – using the Linux screen command

 

 

Getting started with the Linux “screen” command:

This tip follows on from the the earlier post Minecraft and Minecraft Pocket Edition Servers on Ubuntu Linux

The Linux “screen” command is a very useful tool for managing one or many Minecraft and Minecraft Android/Pocket Edition processes.

First off, check you have screen installed on your Linux server by doing;

don@ubuntuserver:~$ which screen

that  should return something like:

/usr/bin/screen

if it doesn’t, you may need to install it like so:

sudo apt-get install screen

(or whatever works for your platform)

then you can start kicking off your Minecraft processes like this

 screen ./start.sh

when that’s up and running you can disconnect from the screen by doing

Ctrl-a d

This will detach you from the screen/console but leave the server running – meaning you can log off or go and do something else.

To reattach to the running screen (assuming there’s only one) and get back to the console at a later time, you just do this:

screen –r

If there is more than one screen sessions available you’ll be given a list of them, something like this:

There are several suitable screens on:
15772.pts-1.ubuntuserver(06/01/14 22:05:25)     (Detached)
2088.pts-4.ubuntuserver (06/01/14 15:20:59)     (Attached)
2013.pts-3.ubuntuserver (06/01/14 15:20:13)     (Detached)

from which you can then do:

screen -r [pid.]tty.host

using the pid and tty host values from that list, e.g. “screen –r 2013.pts-3.ubuntuserver” or “screen –r 15772.pts-1.ubuntuserver” in my example.

There are loads of other useful screen commands – check out the man page for further info – but the above allows me to manage multiple Minecraft servers easily.

Loading CSV data in to MySQL – random quotations app Part 1

Time for a new PHP and MySQL app – “Who said that?” – a search tool for famous quotations.

I created these two web applications a while back:

UK post code search
crossword solver

and then wrote this page:
Some PHP examples
detailing roughly how they were put together, but this time I wanted to create a searchable database of famous quotations, and focus on the MySQL side of things a bit more too (so that next time I will have a note of how I did it!).

I found a very nice CSV data file on http://thewebminer.com/download for free – I don’t really do Facebook much and don’t have a Twitter account so I thought/hoped they’d settle for a blog post in exchange…

After installing and setting up MySQL, connect to your database…

mysql –user=myuser –password=myusualpassword dev

— or connect without specifying a database/schema and do “show databases;”

mysql> show tables;
 +---------------+
 | Tables_in_dev |
 +---------------+
 | areacodes |
 | dictionary |
 +---------------+
 2 rows in set (0.02 sec)

For this little app, I want to create a new table with fields for each row in the CSV file
plus I’d like an auto_increment field to make fetching random numbers easier

CREATE TABLE quotes (
 id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
 quote varchar(800),
 author varchar(100),
 genre varchar(100)
 );
mysql> show tables;
 +---------------+
 | Tables_in_dev |
 +---------------+
 | areacodes |
 | dictionary |
 | quotes |
 +---------------+
 3 rows in set (0.00 sec)
mysql> describe quotes;
 +--------+--------------+------+-----+---------+----------------+
 | Field | Type | Null | Key | Default | Extra |
 +--------+--------------+------+-----+---------+----------------+
 | id | int(11) | NO | PRI | NULL | auto_increment |
 | quote | varchar(800) | YES | | NULL | |
 | author | varchar(100) | YES | | NULL | |
 | genre | varchar(100) | YES | | NULL | |
 +--------+--------------+------+-----+---------+----------------+
 4 rows in set (0.06 sec)

ok, the table looks good, so I can load the CSV data file – note that I’ve got the “quotes35000.csv” file I downloaded from
http://thewebminer.com/download sitting in the current directory:

mysql> load data local infile 'quotes35000.csv' into table quotes
 -> fields terminated by ';'
 -> lines terminated by 'n'
 -> (quote, author, genre);
 Query OK, 35002 rows affected (1.54 sec)
 Records: 35002 Deleted: 0 Skipped: 0 Warnings: 0

that looks like it went well (“35002 rows affected”), time to check it:

mysql> select count(*) from quotes;
 +----------+
 | count(*) |
 +----------+
 | 35002 |
 +----------+
 1 row in set (0.04 sec)
mysql> select * from quotes where author like '%Einstein' and genre like 'attitude%';
 +------+-----------------------------------------------------+-----------------+-----------+
 | id | quote | author | genre |
 +------+-----------------------------------------------------+-----------------+-----------+
 |4647 | Weakness of attitude becomes weakness of character. | Albert Einstein | attitude
 +------+-----------------------------------------------------+-----------------+-----------+
 1 row in set (0.02 sec)

All looking good, the row count and the returned query match what I’d expect having looked at the contents of the CSV file.

I also want to do a “random quote of the day thing”, so looked in to ways to do this in MySQL – my initial thought was to use something basic like “ORDER BY RAND() LIMIT 0,1;” to bring back one random row, but I guessed there may be better ways.

Google led me to this site which has some good examples and some performance/comparison details too:
http://akinas.com/pages/en/blog/mysql_random_row/

so I tried this…

mysql> SELECT * FROM quotes WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM quotes ) ORDER BY id LIMIT 1;
 +-----+--------------------------------------------------------------------------+-----------------+-------+
 | id | quote | author | genre |
 +-----+--------------------------------------------------------------------------+-----------------+-------+
 |84 | Men are like wine - some turn to vinegar, but the best improve with age. | Pope John XXIII | age
 +-----+--------------------------------------------------------------------------+-----------------+-------+
 1 row in set (1.54 sec)

then this…

mysql> SELECT * FROM quotes ORDER BY RAND() LIMIT 0,1;
 +-------+-------------------------------------------------------------------------------------+----------------+-------+
 | id | quote | author | genre |
 +-------+-------------------------------------------------------------------------------------+----------------+-------+
 |29470 | The good die young, because they see it's no use living if you have got to be good. | John Barrymore | good
 +-------+-------------------------------------------------------------------------------------+----------------+-------+
 1 row in set (0.73 sec)

and found to my surprise that in this case, looking at the timings, the simple approach looks to be faster – probably because of the relatively small table and its simple structure?

Anyway, that’s the database side of things sorted, the next part is to put together some PHP code to allow searching for quotes based on author, partial quote or genre, and to write a simple “random quote” generator kind of thing.

Cheers,

Don

Pin It on Pinterest

%d bloggers like this: