Wednesday

Creating simple, extendible CRUD, using Zend Framework


The Form

Creating a nice, easy to maintain form, starts with a form class. Creating your forms procedurally in your controller/actions is horrid. please don’t do it.
To start with creating your form classes, you need your own namespace in your library. If you don’t have this, register one. This can be done by adding an _initAutoloading method to your Bootstrap. below is a short example. its not comprehensive (you can also do this in your ini i believe, but I use php configuration files similar to DASPRiD‘s, and i’m not trying to show how to set up autoloading here.)
class Bootstrap extends Zend_Application_Bootstrap
{
    //...
    /**
    * Initilise autoloader and library namespaces
    */
    public function _initAutoloading()
    {
        $loader = Zend_Loader_Autoloader::getInstance();
        $loader->registerNamespace('My_');
    }
    //...
}
Your next task, create a form. This is pretty simple. I will demonstrate using just a few fields. Create a file in your library called My/Form.php
class My_Form extends Zend_Form
{
    /**
    * Set up form fields, filtering and validation
    */
    public function init()
    {
        $this->setMethod(Zend_Form::METHOD_POST);
        //Username
        $this->addElement($uname = new Zend_Form_Element_Text('username'));
        $uname->setLabel('Username')
              ->addValidator('Db_NoRecordExists', false, array('table' => 'users',
                                                               'field' => 'username'))
              ->addValidator('Alnum', false, array('allowWhiteSpace' => true));
        //Email
        $this->addElement($email = new Zend_Form_Element_Text('email'));
        $email->setLabel('Email')
              ->addValidator('Db_NoRecordExists', false, array('table' => 'users',
                                                               'field' => 'email'))
              ->addValidator('EmailAddress', false);
        //First name
        $this->addElement($firstname = new Zend_Form_Element_Text('firstname'));
        $firstname->setLabel('First name');
        //Last name
        $this->addElement($lastname = new Zend_Form_Element_Text('lastname'));
        $lastname->setLabel('Last name');
    }
}
Now that your basic form is created, you need to add a method to perform your CRUD. I’m not actually going to cover the D (delete) as thats realy simple, and doesn’t require the form, which is the focus of this post.
This method should take an array for the post data, and a Zend_Db_Table_Row to provide the save functionality. In this example the DB columns have the same names as the form fields, this means we can set values with less code. As we are using Zend_Db, there should be no injection problems with this method, as everything is automagically quoted.
    //...
    public function process (array $post, Zend_Db_Table_Row  $row)
    {
        $this->setDefaults($row->toArray());
        // If the id (primary key) is null then this is a new row, else it is an existing record
        if (null !== $row->id) {
            // Record already exists, exclude it from db record validation.
            $this->getElement('username')
            ->addValidator('Db_NoRecordExists',
                                 false,
                                 array('table'    => 'users',
                                          'field'     => 'username',
                                          'exclude' => array ('field' => 'id',
                                                                      'value' => $row->id)));
            $this->getElement('email')
            ->addValidator('Db_NoRecordExists',
                                 false,
                                 array('table'    => 'users',
                                         'field'     => 'email',
                                         'exclude' => array ('field' => 'id',
                                                                    'value' => $row->id)));
        }
        if (sizeof($post) && $this->isValid($post)) {
            try {
                $row->setFromArray($this->getValues());
                $row->save();
                return true;
            } catch (Exception $e) {
                $this->addDescription('There was an error saving your details');
                return $this;
            }
        }
        return $this;
    }

The Controller / Action

Now that we have created our nice form (which is capable of CR and U)  now we need to use it from within out controller and model to perform the update or insert and interact with the user.
For this, you need 3 actions in your controller, Create, update, and delete (the delete I will not cover for the before mentioned reasons).
class UserController extends Zend_Controller_Action
{
 
    public function newAction ()
    {
        $this->_helper->ViewRenderer->setScriptAction('userform');
        $users = My_Users();
        $user = $users->getNewUserForm($this->getRequest()->getPost());
        if (true === $user) {
            $this->_helper->flashMessenger()->addMessage('New User Created');
            $this->_helper->redirector->gotoUrlAndExit(/** confirmation url here **/);
        }
        $this->view->form = $user;
    }
 
    public function editAction()
    {
        $this->_helper->ViewRenderer->setScriptAction('userform');
        if (false === ($id = $this->_getParam('id', false))) {
            throw new Exception ('Tampered URI');
        }
        $users = My_Users();
        $user = $users->getEditUserForm($this->getRequest()->getPost());
        if (true === $user) {
            $this->_helper->flashMessenger()->addMessage('Details Saved');
            $this->_helper->redirector->gotoUrlAndExit('user/edit/' . $id);
        }
        $this->view->form = $user;
    }
}
To explain what all this is about, Both actions do pretty similar things (infact this can be consolidated into a single action, but for clarity and ease of replication, I am using two).
There are two things which are pretty important in this, one is the use of the redirector, and the other is the checking of the ID before it is used. In my opinion when an id is passed in a url which is invalid, then a 404 should be raised. So in my error controllers i look for a variety of exception types so that i can debug, but only output a 404 for these in production.
Now looking more closely at the action code, we have calls to getxxxxUserForm() on our models. The return value of this is what we wish to inspect, as you could see in the process method we created earlier, we return boolean true, only when the record saves correctly.  So we do a strict check for this boolean value, and if it is true, we know that we can safely redirect our user. The redirect is an important step, it stops the browser trying to post the data again if the user clicks refresh after their record is created / updated. And the final note is that the flashMessenger is used to pass a message to inform that user that their action was completed on.
Also worth noting is that i have set both actions to use the same action name in the viewRenderer. This allows you to consolidate this common script into one. (repeat after me, Dont Repeat Yourself!). The view script for this is pretty simple.
foreach(Zend_Controller_Action_HelperBroker::getStaticHelper('flashMessenger') ->getMessages() as $message) : ?> echo $this->escape($message);?>
endforeach; </div> echo $this->form;?>

The Model

In the model, we now need two simple methods to tie the lot together. Now some people might (read: Will) argue that the model should be performing validation, I would argue that with this method, the Model *is* performing the validation, you are simply making use of a library class to perform this function, much in the same way you use Zend_Db_Row. Feel free to flame about this below, but I’m sticking with this, and it provides clean easy seperation, and provides a good clean mechanism to provide user feedback.
class My_Users
{
    /**
    * @var Zend_Db_Table_Abstract
    */
    protected $_table;
    //....
 
    /**
    * Retrieves a new user record, and processes a form against it.
    *
    * @param array $post
    * @return boolean|Zend_Form Boolean true if a save successfully occurs, a populated form on all other conditions
    */
    public function getNewUserForm(array $post)
    {
        $form = new My_Form();
        return $form->process($post, $this->_table->createRow());
    }
 
    /**
    * Retrieves a user record, and processes a form against it.
    *
    * @param array $post
    * @return boolean|Zend_Form Boolean true if a save successfully occurs, a populated form on all other conditions
    */
    public function getEditUserForm(array $post, $id)
    {
        $row = $this->_table->fetchRow($table->select()->where('id = ?', $id));
        $form = new My_Form();
        return $form->process($post, $row);
    }
}
Well, this really doesn’t need much explanation. this simply provides glue between the parts above. You can make these a little more complex, and infact you probably should (I do!) by sanitizing your input from the controller in the form of the user id, $id, in the edit method.

curtsy: ryan's blog

Tuesday

jQuery webcam plugin


The jQuery webcam plugin is a transparent layer to communicate with a camera directly in JavaScript.

Overview

This plugin provides three different modes to access a webcam through a small API directly with JavaScript - or more precisely jQuery. Thus, it is possible to bring the image on a Canvas (callback mode), to store the image on the server (save mode) and to stream the live image of the Flash element on a Canvas (stream mode). If you just want to download the plugin, click here:

jQuery webcam example

jQuery

Available Cameras

  • HP Webcam [2 MP Fixed] (V4L2)
If you activate the filter with the button on the right side of the picture, methods of my already published jQuery plugin xcolor will be used to distort the colors of the Canvas.

General information about the interface

The following snippet describes the interface of the webcam API:
$("#camera").webcam({
 width: 320,
 height: 240,
 mode: "callback",
 swffile: "/download/jscam_canvas_only.swf",
 onTick: function() {},
 onSave: function() {},
 onCapture: function() {},
 debug: function() {},
 onLoad: function() {}
});

Config Parameter

width
The width of the flash movie.
height
The height of the flash movie. Both parameters have to be changed in the Flash file as well. Follow the instructions below to recompile the swf after the size change.
mode
The storage mode can be one of the following: callback, save, stream. Details about the usage of each parameter can be found under the according heading below.
swffile
Points to the swf file of the Flash movie, which provides the webcam API. There are two swf files provided via the download archive: jscam.swf, which provides the full API and jscam_canvas_only.swf which have no embedded JPEG library (I embedded an adjusted JPGEncoder of the AS 3 corelib). Thereby, the file is only one third as large as the original.
onTick, onSave, onCapture
These callbacks are described in detail below, since they change with each mode.
onLoad
The onLoad callback is called as soon as the registration of the interface is done. In the example above, I use the callback to get a list of all cameras available:
onLoad: function() {

    var cams = webcam.getCameraList();
    for(var i in cams) {
        jQuery("#cams").append("
  • "
  • + cams[i] + "
    "); } } Once the onLoad callback is called, a global object window.webcam is available, which provides the following methods:
    • capture([delay])
      Captures an image internally.
    • save([file])
      Saves the captured image accordingly to the storage mode.
    • getCameraList()
      Get's an array of available cameras. If no camera is installed, an error is thrown and an empty array is returned.
    • setCamera([index])
      Switches to a different camera. The parameter is the index of the element in the resulting array of getCameraList()
    debug
    The debug callback is called whenever there is a note or an error you should be notified. In the example above, I just replace the html content of the output container:
    debug: function (type, string) {
     $("#status").html(type + ": " + string);
    }

    Callback Interface

    The callback mode is used to get the raw data via a callback method to write it on a canvas element for example. The example above uses the callback mode.
    As for the processing, one can imagine how it works as follows: Once the user has completely loaded the entire page and has accepted the security setting of Flash, she should be able to see herself. Then, the user triggers the method window.capture(). This may optionally receive a parameter that specifies the time to wait until the image is shot. To view the passage of time, the method onTick() is called after every second. The received parameter of this method is the amount of seconds remaining. In the example above, I simply change the status message like this:
    onTick: function(remain) {
    
        if (0 == remain) {
            jQuery("#status").text("Cheese!");
        } else {
            jQuery("#status").text(remain + " seconds remaining...");
        }
    }
    Is copying finished, the onCapture callback is called, which in the example of above immediately calls the method webcam.save() to ultimately write the image to the canvas. The sample code also contains a small gimmick to simulate a flash using a lightbox and jQuery's fadeOut() fx method.
    onCapture: function () {
    
     jQuery("#flash").css("display", "block");
     jQuery("#flash").fadeOut("fast", function () {
      jQuery("#flash").css("opacity", 1);
     });
    
     webcam.save();
    }
    In callback mode, for every line the callback onSave() is invoked, which gets an integer CSV of color values (separator is the semicolon). To write the data on the canvas, I use the following method in the example above:
    onSave: function(data) {
    
        var col = data.split(";");
        var img = image;
    
        for(var i = 0; i < 320; i++) {
            var tmp = parseInt(col[i]);
            img.data[pos + 0] = (tmp >> 16) & 0xff;
            img.data[pos + 1] = (tmp >> 8) & 0xff;
            img.data[pos + 2] = tmp & 0xff;
            img.data[pos + 3] = 0xff;
            pos+= 4;
        }
    
        if (pos >= 4 * 320 * 240) {
            ctx.putImageData(img, 0, 0);
            pos = 0;
        }
    }

    Save Interface

    From the view of processing, the save mode is almost identical to the callback mode. The only difference is that the webcam.save() method get's the file name passed as parameter. Then the shot photo is sent via HTTP_RAW_POST_DATA to the server and can be read for example with the following snippet to store or further process it in any way (Warning, input validation is not considered here!).
    webcam.save('/upload.php');
    And on the server side, you get the image like this:
    php
    
    $str = file_get_contents("php://input");
    file_put_contents("/tmp/upload.jpg", pack("H*", $str));
    
    ?>

    Alternative method to the upload via Flash

    The Flash method has several problems. The implementation can lock the entire Flash movie and in the worst case the whole browser until the picture was uploaded sucessfully. A better approach is Ajax to upload the image asynchronously. Take a look at this example. It uploads a simple picture CSV if canvas elements are not implemented in the browser and sends a data url formatted string otherwise:
    $(function() {
    
     var pos = 0, ctx = null, saveCB, image = [];
    
     var canvas = document.createElement("canvas");
     canvas.setAttribute('width', 320);
     canvas.setAttribute('height', 240);
     
     if (canvas.toDataURL) {
    
      ctx = canvas.getContext("2d");
      
      image = ctx.getImageData(0, 0, 320, 240);
     
      saveCB = function(data) {
       
       var col = data.split(";");
       var img = image;
    
       for(var i = 0; i < 320; i++) {
        var tmp = parseInt(col[i]);
        img.data[pos + 0] = (tmp >> 16) & 0xff;
        img.data[pos + 1] = (tmp >> 8) & 0xff;
        img.data[pos + 2] = tmp & 0xff;
        img.data[pos + 3] = 0xff;
        pos+= 4;
       }
    
       if (pos >= 4 * 320 * 240) {
        ctx.putImageData(img, 0, 0);
        $.post("/upload.php", {type: "data", image: canvas.toDataURL("image/png")});
        pos = 0;
       }
      };
    
     } else {
    
      saveCB = function(data) {
       image.push(data);
       
       pos+= 4 * 320;
       
       if (pos >= 4 * 320 * 240) {
        $.post("/upload.php", {type: "pixel", image: image.join('|')});
        pos = 0;
       }
      };
     }
    
     $("#webcam").webcam({
    
      width: 320,
      height: 240,
      mode: "callback",
      swffile: "/download/jscam_canvas_only.swf",
    
      onSave: saveCB,
    
      onCapture: function () {
       webcam.save();
      },
    
      debug: function (type, string) {
       console.log(type + ": " + string);
      }
     });
    
    });
    The server could then do something like this:
    php
    
    if ($_POST['type'] == "pixel") {
     // input is in format 1,2,3...|1,2,3...|...
     $im = imagecreatetruecolor(320, 240);
    
     foreach (explode("|", $_POST['image']) as $y => $csv) {
      foreach (explode(";", $csv) as $x => $color) {
       imagesetpixel($im, $x, $y, $color);
      }
     }
    } else {
     // input is in format: data:image/png;base64,...
     $im = imagecreatefrompng($_POST['image']);
    }
    
    // do something with $im
    
    ?>

    Stream interface

    The stream mode is also quite the same procedure as the callback mode, with the difference that the onSave callback is called non-stop. The streaming starts with the method webcam.capture(). The webcam.save() method has no further effect.

    Recompile the Flash binary

    If you've made changes to the code or did just adjust the size of the video in the XML specification file, you can easily recompile the swf file from Linux console with the provided Makefile. You are required to install the two open source projects swfmill and mtasc that can be easily installed using apt-get under Debian/Ubuntu:
    apt-get install swfmill mtasc
    vim src/jscam.xml
    make

    Hint about empty screens after recompilation

    There is a bug in the current version of swfmill. Please try to downgrade swfmill to 2.0.12, which fixes the issue!

    Thursday

    Very useful HTML5 APIs


    Element.classList

    The classList API provides the basic CSS controls our JavaScript libraries have been giving us for years:
    // Add a class to an element
    myElement.classList.add("newClass");
    
    // Remove a class to an element
    myElement.classList.remove("existingClass");
    
    // Check for existence
    myElement.classList.contains("oneClass");
    
    // Toggle a class
    myElement.classList.toggle("anotherClass");
    The epitome of a great API addition: simple and intelligent.

    ContextMenu API

    The new ContextMenu API is excellent:  instead of overriding the browser context menu, the new ContextMenu API allows you to simply add items to the browser's context menu:
    contextmenu="mymenu"> type="context" id="mymenu"> label="Refresh Post" onclick="window.location.reload();" icon="/images/refresh-icon.png"> label="Share on..." icon="/images/share_icon.gif"> label="Twitter" icon="/images/twitter_icon.gif" onclick="goTo('//twitter.com/intent/tweet?text=' + document.title + ': ' + window.location.href);"> label="Facebook" icon="/images/facebook_icon16x16.gif" onclick="goTo('//facebook.com/sharer/sharer.php?u=' + window.location.href);">
    Note that it's best to create your menu markup with JavaScript since JS is required to make item actions work, and you wouldn't want the HTML in the page if JS is turned off.

    Element.dataset

    The dataset API allows developers to get and set data- attribute values:
    /*  Assuming element:
    
      
    */
    // Get the element var element = document.getElementById("myDiv"); // Get the id var id = element.dataset.id; // Retrieves "data-my-custom-key" var customKey = element.dataset.myCustomKey; // Sets the value to something else element.dataset.myCustomKey = "Some other value"; // Element becomes: //
    Not much more to say; just like classList, simple and effective.

    window.postMessage API

    The postMessage API, which has even been supported in IE8 for years, allows for message sending between windows and IFRAME elements:
    // From window or frame on domain 1, send a message to the iframe which hosts another domain
    var iframeWindow = document.getElementById("iframe").contentWindow;
    iframeWindow.postMessage("Hello from the first window!");
    
    // From inside the iframe on different host, receive message
    window.addEventListener("message", function(event) {
      // Make sure we trust the sending domain
      if(event.origin == "http://davidwalsh.name") {
        // Log out the message
        console.log(event.data);
    
        // Send a message back
        event.source.postMessage("Hello back!");
      }
    ]);
    Messages may only be strings, but you could always use JSON.stringify and JSON.parse for more meaningful data!

    autofocus Attribute

    The autofocus attribute ensures that a given BUTTON, INPUT, or TEXTAREA element is focused on when the page is ready:
     autofocus="autofocus" />
    
    
    Admittedly the autofocus attribute is disorienting for the visually impaired, but on simple search pages, it's the perfect addition.


    Fullscreen API

    The awesome Fullscreen API allows developers to programmatically launch the browser into fullscreen mode, pending user approval:
    // Find the right method, call on correct element
    function launchFullScreen(element) {
      if(element.requestFullScreen) {
        element.requestFullScreen();
      } else if(element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
      } else if(element.webkitRequestFullScreen) {
        element.webkitRequestFullScreen();
      }
    }
    
    // Launch fullscreen for browsers that support it!
    launchFullScreen(document.documentElement); // the whole page
    launchFullScreen(document.getElementById("videoElement")); // any individual element
    Any element can be pushed to fullscreen, and there's even a CSS pseudo-class to allow some control over the screen while in fullscreen mode.  This API is especially useful for JavaScript game development;

    Page Visibility API

    The Page Visibility API provides developers an event to listen in on, telling developers when the user focuses on a page's tab, and also when the user moves to another tab or window:
    // Adapted slightly from Sam Dutton
    // Set name of hidden property and visibility change event
    // since some browsers only offer vendor-prefixed support
    var hidden, state, visibilityChange; 
    if (typeof document.hidden !== "undefined") {
      hidden = "hidden";
      visibilityChange = "visibilitychange";
      state = "visibilityState";
    } else if (typeof document.mozHidden !== "undefined") {
      hidden = "mozHidden";
      visibilityChange = "mozvisibilitychange";
      state = "mozVisibilityState";
    } else if (typeof document.msHidden !== "undefined") {
      hidden = "msHidden";
      visibilityChange = "msvisibilitychange";
      state = "msVisibilityState";
    } else if (typeof document.webkitHidden !== "undefined") {
      hidden = "webkitHidden";
      visibilityChange = "webkitvisibilitychange";
      state = "webkitVisibilityState";
    }
    
    // Add a listener that constantly changes the title
    document.addEventListener(visibilityChange, function(e) {
      // Start or stop processing depending on state
    
    }, false);
    When used properly, a developer can avoid expensive tasks (like AJAX polling or animating) when the tab isn't in focus.

    getUserMedia API

    The getUserMedia API is incredibly interesting;  this API provides access to device media, like your MacBook's camera!  Using this API, the
    // Put event listeners into place
    window.addEventListener("DOMContentLoaded", function() {
      // Grab elements, create settings, etc.
      var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        video = document.getElementById("video"),
        videoObj = { "video": true },
        errBack = function(error) {
          console.log("Video capture error: ", error.code); 
        };
    
      // Put video listeners into place
      if(navigator.getUserMedia) { // Standard
        navigator.getUserMedia(videoObj, function(stream) {
          video.src = stream;
          video.play();
        }, errBack);
      } else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
        navigator.webkitGetUserMedia(videoObj, function(stream){
          video.src = window.webkitURL.createObjectURL(stream);
          video.play();
        }, errBack);
      }
    }, false);
    Look forward to using this API quite a bit in the future -- interactivity within the browser will be the norm a year from now!

    Battery API

    The Battery API is obviously a mobile-targeted API providing insight into the device's battery level and status:
    // Get the battery!
    var battery = navigator.battery || navigator.webkitBattery || navigator.mozBattery;
    
    // A few useful battery properties
    console.warn("Battery charging: ", battery.charging); // true
    console.warn("Battery level: ", battery.level); // 0.58
    console.warn("Battery discharging time: ", battery.dischargingTime);
    
    // Add a few event listeners
    battery.addEventListener("chargingchange", function(e) {
      console.warn("Battery charge change: ", battery.charging);
    }, false);
    Knowing battery API and status can signal to the web application not to use battery-intensive processes and the like.  Not a groundbreaking API but surely a helpful one.

    Link Prefetching

    Link prefetching allows developers to silently preload site contents to project a more fluid, seamless web experience:
    
     rel="prefetch" href="http://davidwalsh.name/css-enhancements-user-experience" />
    
    
     rel="prefetch" href="http://davidwalsh.name/wp-content/themes/walshbook3/images/sprite.png" />


    Browser support for each API differs, so use feature detection before using each API.  Take a few moments to read the detailed posts on each feature above -- you'll learn a lot and hopefully get a chance to tinker with each API!

    Read PDF and Word DOC Files Using PHP



    Reading PDF Files

    To read PDF files, you will need to install the XPDF package, which includes "pdftotext." Once you have XPDF/pdftotext installed, you run the following PHP statement to get the PDF text:
    $content = shell_exec('/usr/local/bin/pdftotext '.$filename.' -'); //dash at the end to output content

    Reading DOC Files

    Like the PDF example above, you'll need to download another package. This package is called Antiword. Here's the code to grab the Word DOC content:
    $content = shell_exec('/usr/local/bin/antiword '.$filename);
    The above code does NOT read DOCX files and does not (and purposely so) preserve formatting. There are other libraries that will preserve formatting but in our case, we just want to get at the text.

    Tuesday

    Html5 data access from sqllite






    SQL Storage
         
     

       

         
         First name:
         Last name:
         Phone:
         
         
         
           
         

       
     
     
       

    How to Install SQLite3 from Source on Linux (With a Sample Database)


    SQLite3 is an extremely lightweight SQL database engine that is self-contained and serverless.
    There is absolutely no configuration that you need to do to get it working. All you need to do is–install it, and start using it.
    Since this is serverless, it is used in lot of the famous software that you are using, and you probably didn’t even know those software were using it. View this list to see all the big name companies who are using SQLite. PHP programming language has SQLite database built in.
    If you’ve never used SQLite, follow the steps mentioned in this article to install it on Linux, and create a sample database.

    Download SQLite3 Source

    Go to the SQLite Download page, and click on “sqlite-autoconf-3070603.tar.gz” (Under Source Code section), and download it to your system. Or, use the wget to directly download it to your server as shown below.
    wget http://www.sqlite.org/sqlite-autoconf-3070603.tar.gz

    Install SQLite3 from Source

    Uncompress the tar.gz file and install SQLite3 as shown below.
    tar xvfz sqlite-autoconf-3070603.tar.gz
    cd sqlite-autoconf-3070603
    ./configure
    make
    make install
    make install command will displays the following output indicating that it is installing sqlite3 binaries under /usr/local/bin
    test -z "/usr/local/bin" || mkdir -p -- "/usr/local/bin"
      ./libtool --mode=install /usr/bin/install -c sqlite3 /usr/local/bin/sqlite3
    /usr/bin/install -c .libs/sqlite3 /usr/local/bin/sqlite3
    test -z "/usr/local/include" || mkdir -p -- "/usr/local/include"
     /usr/bin/install -c -m 644 'sqlite3.h' '/usr/local/include/sqlite3.h'
     /usr/bin/install -c -m 644 'sqlite3ext.h' '/usr/local/include/sqlite3ext.h'
    test -z "/usr/local/share/man/man1" || mkdir -p -- "/usr/local/share/man/man1"
     /usr/bin/install -c -m 644 './sqlite3.1' '/usr/local/share/man/man1/sqlite3.1'
    test -z "/usr/local/lib/pkgconfig" || mkdir -p -- "/usr/local/lib/pkgconfig"
     /usr/bin/install -c -m 644 'sqlite3.pc' '/usr/local/lib/pkgconfig/sqlite3.pc'
    Note: If you are interested in installing MySQL database on your system, you can either useyum groupinstall mysql, or install mysql from rpm.

    Create a sample SQLite database

    The example shown below does the following:
    • Create a new SQLite database called “company.db”.
    • Create “employee” table with three fields 1) Employee Id 2) Name and 3) Title
    • Insert 5 records into the employee tables.
    • Verify the records
    • Exit SQLite3
    $ sqlite3 company.db
    SQLite version 3.7.6.3
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";"
    
    sqlite> create table employee(id integer,name varchar(20),title varchar(10));
    
    sqlite> insert into employee values(101,'John Smith','CEO');
    sqlite> insert into employee values(102,'Raj Reddy','Sysadmin');
    sqlite> insert into employee values(103,'Jason Bourne','Developer');
    sqlite> insert into employee values(104,'Jane Smith','Sale Manager');
    sqlite> insert into employee values(104,'Rita Patel','DBA');
    
    sqlite> select * from employee;
    101|John Smith|CEO
    102|Raj Reddy|Sysadmin
    103|Jason Bourne|Developer
    104|Jane Smith|Sale Manager
    104|Rita Patel|DBA
    
    sqlite>[Press Ctrl-D to exit]

    Access the SQLite Database

    When you create a database, it is nothing but a file. If you do “ls”, you’ll see the “company.db” file as shown below.
    $ ls -l company.db
    -rw-r--r--. 1 ramesh ramesh 2048 Jun 18 21:27 company.db
    To access an existing database and query the records, do the following. i.e When you do “sqlite3 company.db”, if the database doesn’t exist it’ll create it. If it already exists, it’ll open it.
    $ sqlite3 company.db
    SQLite version 3.7.6.3
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";"
    
    sqlite> select * from employee;
    101|John Smith|CEO
    102|Raj Reddy|Sysadmin
    103|Jason Bourne|Developer
    104|Jane Smith|Sale Manager
    104|Rita Patel|DBA
    
    sqlite>[Press Ctrl-D to exit]
    This is just a jumpstart guide for you to get started on SQLite3. In our future articles about SQLite3, we’ll be discussing about several SQLite3 commands, how to access the SQLite3 database from various programming languages, and several tips and tricks on SQLite3.
    curtsy:RAMESH NATARAJAN 

    Sunday

    Open source software requirement and user documentation tool - MediaWiki

    You probably know Wikipedia, the free encyclopedia, and may possibly be a little bit confused by similar, but different, words such as Wiki, Wikimedia or MediaWiki.
    To avoid a possible confusion between the words you may first want to read the article about the names where the differences are explained.

    MediaWiki is free server-based software which is licensed under the GNU General Public License (GPL). It's designed to be run on a large server farm for a website that gets millions of hits per day. MediaWiki is an extremely powerful, scalable software and a feature-rich wiki implementation, that uses PHP to process and display data stored in a database, such as MySQL.
    Pages use MediaWiki's wikitext format, so that users without knowledge of XHTML or CSS can edit them easily.
    When a user submits an edit to a page, MediaWiki writes it to the database, but without deleting the previous versions of the page, thus allowing easy reverts in case of vandalism or spamming. MediaWiki can manage image and multimedia files, too, which are stored in the filesystem. For large wikis with lots of users, MediaWiki supports caching and can be easily coupled with Squid proxy server software.

    What MediaWiki is...

    MediaWiki is wiki software.
    If you don't know what a wiki is, then read this Wikipedia article before going any further!
    MediaWiki is server software.
    As with any software that you expose to the internet, there may be bugs or security problems. Do not install MediaWiki unless you intend to keep up with security upgrades (please subscribe to receive announcements of security updates).
    MediaWiki is geared towards the needs of the Wikimedia Foundation.
    The program is primarily developed to run on a large server farm for Wikipedia and its sister projects. Features, performance, configurability, ease-of-use, etc are designed in this light; if your needs are radically different the software might not be appropriate for you.
    MediaWiki is free software.
    No guarantee or warranty of any kind is provided.

     

    Beyond Spot-Checking: Why LLM Applications Require Specialized Evaluation

      images generated by meta ai Building applications with Large Language Models (LLMs) feels deceptively fast at first. A single engineer can...