|
|
|
The README Aug 6th, 2015 [viewed 7022 times] |
MVProc is a Model-View-Controller web framework that uses MySQL stored procedures as the controller element. It is implemented as an Apache2 module, mod_mvproc. There are currently no plans to implement this for any other database, as no other database has enough flexibility of functionality in the context of stored routines. (At least as far as I'm aware.) InstallationThe Makefile and #includes section of mvproc.h may need to be edited before compiling, specifically the APACHE_HOME variable and location of apr-1 and apreq2. It will build on Ubuntu, but other distros may have different locations of headers and libs (eg. /usr/lib64 instead of /usr/lib). Required Packages: apache2-dev, libapr1-dev ConfigurationSince mod_mvproc is a module it must be loaded in your apache configuration file. apreq_module is required and must be loaded prior to loading mvproc, like so:
There are thirteen (13) configuration directives for mod_mvproc: mvprocSession (Y or N) - sets session behavior. If sessions are enabled (Y), the module will supply called stored procedures with a user variable @mvp_session, which will contain a 32 character session id. A cookie will be produced and maintained with this id as its value. The procedure may set the @mvp_session value, which will update the value of the cookie. The value is also included in the output of the call in the PROC_OUT section. mvprocDbGroup (yourDBgroup) - this is the group in mysql's my.cnf file which mvproc will use to authenticate and connect to the database. An example: Please refer to the MySQL documentation for my.cnf subtleties. Do consider that my.cnf is accessible. Best practice is to create a user (let's say 'foo'@'localhost') for an MVProc database (let's say `bar`) and grant only minimal access. Most of the time, this would be: mvprocTemplateDir (/your/template/directory) - the location of the templates. This is best placed outside the doc root - in fact, if the template files are in the doc root Apache will get confused, thinking it should serve the file instead of allowing mvproc to handle the transaction. If mvprocTemplateDir is not set, or set with an empty string, templates and layouts will not be used. More on templates later. mvprocDefaultLayout (yourLayoutTemplate - leave off the '.tpl') If set, this will set the @mvp_layout session variable to a default value. It's not required to set this in the configuration, as procedures can set it as well. More on layouts later. mvprocDefaultProc (yourDefaultProc) If set, this will be the procedure that's called when the request uri is '/' or if the uri does not match a procedure. A non-proc uri is allowed so pages can be given interesting urls like http://my.site.org/i-like-cheese Do remember to handle possible non-proc uris in your default proc. In order to force Apache to send '/' to mvproc, use
mvprocCache (Y or N) - Y enables caching of procs AND templates. Set to N during development and Y for production use. mvprocDbPoolSize (number) - The number of connections to pool. If this is not set, or set to zero, a new connection will be established, used, and closed for each request. mvprocOutputStyle (MIXED | PLAIN | JSON | EASY_XML | EASY_JSON) see the Output section below. mvprocErrTemplate - If mvprocTemplateDir is configured, this is the name of the template to render when there's a database error. The error can be accessed as <# status.error #>. mvprocAllowSetContent (Y or N) - provides @mvp_content_type session variable, which allows a procedure to tell Apache how to set the Content-Type header. mvprocAllowHTMLfromDB (Y or N) – default N, Y allows HTML output from the database to be rendered as HTML. By default, MVProc will convert '<' to '<', '&' to '"', etc. mvprocUploadDirectory - Sets the path to a directory where uploaded files are written. It is highly recommended that this path be OUTSIDE the docroot. If the path doesn't exist, MVProc will attempt to create it. Default value is /tmp mvprocUserVars - a comma-delimited set of additional user vars to make available for output from the procs. This is useful when procs CALL each other and SET @mvp_template. Add no whitespace. Example: mvprocUserVars err,inset_include,universal_out RequestsRequests are typical “pretty” web format, like so: http://mysite.com/procname. If the url points to a file that exists, the module will decline handling, which means the file will be served as normal. If the uri is empty (ie. nothing or '/' after the url) or the uri does not match a stored procedure, the procedure specified by the mvprocDefaultProc configuration directive or 'landing' will be looked for. See mvprocDefaultProc config GET and POST requests are supported, as well as file uploads. A file upload will be written to the system's temp directory with a pseudo-random name plus the original file extension. This filename will be reported to the procedure through the uploaded file's variable name. So a file-type input with name="myfile" will send something like '/tmp/87YHF228FA.jpg' into the procedure as the IN or INOUT argument 'myfile', but ONLY IF THE ARGUMENT EXISTS in the procedure's definition. ProceduresAll aspects of MySQL stored procedures are supported. IN, INOUT, OUT parameters and multiple result sets are available to the template parser and are shown in xml output. User variables available to procedures are currently:
Known IssuesReturning multiple result sets with the same table name causes libmysqlclient to seg fault. This includes calculated selects. So if you want to do this: SELECT 'a value' AS one_value; SELECT 'more value' AS too_value; Instead, do this: SELECT 'a value' AS one_value, 'more value' AS too_value; And if you want to return multiple result sets from the same table, use aliases. If libmysqlclient starts to allow multiple result sets from the same table, be cautious about using EASY_XML and EASY_JSON output. The results are, at this point, undefined. OutputXML MIXED is the default output of a request. If no template exists, the module goes with this. Result sets are rendered in xml as a <table> element with child <row> elements. For the MIXED output type, columns whose declared size is 32 or less (for example VARCHAR(24)) are shown as attributes of rows, while blobs and columns of greater size (like VARBINARY(4096) or CHAR(65)) are shown as children of rows with CDATA encapsulated values. The PLAIN output type populates the name attribute of the table tags, but all columns are rendered as CDATA encapsulated child elements. Another option is JSON, which outputs an array of objects named 'table', each of which owns a name value and an array of row objects each of which owns one named value per column. Most ajax libraries support this format. EASY_XML is the PLAIN type, except that instead of <table name=”tableName”> elements, the output is written like <tableName>. This may cause problems if multiple result sets from the same table are output. EASY_JSON is JSON, except that instead of an array of objects named 'table', the output is an object with each result set as an element named for its table. This may cause problems if multiple result sets from the same table are output. All result sets are output, as well as a “table” called PROC_OUT, which holds all INOUT and OUT values as well as mvp_session and mvp_template values. If a table is not declared in a select out (eg. SELECT 'whatever' AS myval) the table will be called “status”. Here's an example of MIXED:
Templates are typically html pages with tags for the parser to use to plug in values, loop through result sets, conditionally show or not show markup, include other templates. Some simple rules:
The template tags are intentionally few in number. It encourages separation of concern. Value - <# [table.]field_name[[row_num]] #> IF - <# IF myvar = 'hello' #> ELSIF - <# ELSIF @.val_is_set #> - Identical parsing and evaluation to IF. ELSE - <# ELSE #> - This functions as anyone would expect. ENDIF - <# ENDIF #> - Again, like anyone would expect. This tag is REQUIRED with IF usage. LOOP - <# LOOP mytable #> ENDLOOP - <# ENDLOOP #> - Closes a loop. This tag is REQUIRED for each LOOP started. INCLUDE - <# INCLUDE another_template #> TEMPLATE - <# TEMPLATE #> - This is essentially an include tag, except that it uses the @mvp_template session variable. Use this convenience tag inside a layout template. SET - <# SET myvar = 'ok' #>
CALL - <# CALL procname([comma-separated args]) [INTO] tablename(s) #>
And that's it. I think. Any questions, bugs, requests - please post on sourceforge.net -Jeff Walter maintainer, MVProc |