# HG changeset patch # User jbe/bsw # Date 1261738800 -3600 # Node ID 5e32ef998acf882301f9ff3f872b413a1b7984ee # Parent 795b764629ca6028de007a6f45a5acada912c4b7 Version 1.0.4 ui.link{...} with POST target can now be parameterized with BOTH content and text to allow HTML content for JavaScript browsers and a text-only version for accessiblity Changes related to database selectors: - Support for row-based locking - New method :count(), caching and returning the number of rows, which WOULD have been returned by :exec() - Bugfix: WHERE and HAVING expressions are now enclosed in parenthesis to avoid problems with operator precedence ui.script{...} now supports external .js files Changes in langtool.lua to cope with escaped new-line chars (\n) diff -r 795b764629ca -r 5e32ef998acf doc/autodoc-header.htmlpart --- a/doc/autodoc-header.htmlpart Thu Dec 10 12:00:00 2009 +0100 +++ b/doc/autodoc-header.htmlpart Fri Dec 25 12:00:00 2009 +0100 @@ -55,10 +55,10 @@ color: #505050; } - WebMCP 1.0.3 Documentation + WebMCP 1.0.4 Documentation -

WebMCP 1.0.3 Documentation

+

WebMCP 1.0.4 Documentation

WebMCP is a completely new web development framework, and has not been extensively tested yet. The API might change at any time, but in future releases there will be a list of all changes, which break downward compatibility.

diff -r 795b764629ca -r 5e32ef998acf framework/bin/langtool.lua --- a/framework/bin/langtool.lua Thu Dec 10 12:00:00 2009 +0100 +++ b/framework/bin/langtool.lua Fri Dec 25 12:00:00 2009 +0100 @@ -94,6 +94,7 @@ (not string.find(key, "^%s*%.%.[^%.]")) and (not string.find(key, "^%s*,[^,]")) then + local key = key:gsub("\\n", "\n") translations[key] = false end end @@ -103,6 +104,7 @@ (not string.find(key, "^%s*%.%.[^%.]")) and (not string.find(key, "^%s*,[^,]")) then + local key = key:gsub("\\n", "\n") translations[key] = false end end @@ -178,9 +180,9 @@ for num, key in ipairs(translation_keys) do local value = translations[key] if value then - file:write(string.format("[%q] = %q;\n", key, value)) + file:write((string.format("[%q] = %q;\n", key, value):gsub("\\\n", "\\n"))) -- double () important to hide second result of gsub else - file:write(string.format("[%q] = false;\n", key)) + file:write((string.format("[%q] = false;\n", key):gsub("\\\n", "\\n"))) -- double () important to hide second result of gsub end end file:write("}\n") diff -r 795b764629ca -r 5e32ef998acf framework/cgi-bin/webmcp.lua --- a/framework/cgi-bin/webmcp.lua Thu Dec 10 12:00:00 2009 +0100 +++ b/framework/cgi-bin/webmcp.lua Fri Dec 25 12:00:00 2009 +0100 @@ -1,6 +1,6 @@ #!/usr/bin/env lua -_WEBMCP_VERSION = "1.0.3" +_WEBMCP_VERSION = "1.0.4" -- include "../lib/" in search path for libraries do diff -r 795b764629ca -r 5e32ef998acf framework/env/ui/link.lua --- a/framework/env/ui/link.lua Thu Dec 10 12:00:00 2009 +0100 +++ b/framework/env/ui/link.lua Fri Dec 25 12:00:00 2009 +0100 @@ -9,7 +9,7 @@ params = params, -- optional parameters to be passed to the view or action routing = routing, -- optional routing information for action links, as described for ui.form{...} text = text, -- link text - content = content -- alternative name for 'text' option, preferred for functions + content = content -- link content (overrides link text, except for submit buttons for action calls without JavaScript) } This function inserts a link into the active slot. It may be either an internal application link ('module' given and 'view' or 'action' given), or a link to an external web page ('external' given), or a link to a file in the static file directory of the application ('static' given). @@ -18,7 +18,7 @@ function ui.link(args) local args = args or {} - local content = args.text or args.content -- TODO: decide which argument name to use + local content = args.content or args.text assert(content, "ui.link{...} needs a text.") local function wrapped_content() -- TODO: icon/image diff -r 795b764629ca -r 5e32ef998acf framework/env/ui/script.lua --- a/framework/env/ui/script.lua Thu Dec 10 12:00:00 2009 +0100 +++ b/framework/env/ui/script.lua Fri Dec 25 12:00:00 2009 +0100 @@ -26,10 +26,17 @@ slot.put(args.script) end end + if args.external then + attr.src = encode.url{ external = args.external } + elseif args.static then + attr.src = encode.url{ static = args.static } + end if noscript then ui.tag{ tag = "noscript", attr = attr, content = noscript } end - if script then + if attr.src then + ui.tag{ tag = "script", attr = attr, content = "" } + elseif script then ui.tag{ tag = "script", attr = attr, content = script } end end diff -r 795b764629ca -r 5e32ef998acf libraries/mondelefant/mondelefant.lua --- a/libraries/mondelefant/mondelefant.lua Thu Dec 10 12:00:00 2009 +0100 +++ b/libraries/mondelefant/mondelefant.lua Fri Dec 25 12:00:00 2009 +0100 @@ -62,17 +62,15 @@ self._distinct = false self._distinct_on = {sep = ", ", expression} self._from = { sep = " " } - self._where = { sep = " AND " } + self._where = { sep = ") AND (" } self._group_by = { sep = ", " } - self._having = { sep = " AND " } + self._having = { sep = ") AND (" } self._combine = { sep = " " } self._order_by = { sep = ", " } self._limit = nil self._offset = nil - --[[ - self._lock = nil - self._lock_tables = { sep = ", " } - --]] + self._read_lock = { sep = ", " } + self._write_lock = { sep = ", " } self._class = nil self._attach = nil return self @@ -193,6 +191,26 @@ return self end +function selector_prototype:for_share() + self._read_lock.all = true + return self +end + +function selector_prototype:for_share_of(expression) + add(self._read_lock, expression) + return self +end + +function selector_prototype:for_update() + self._write_lock.all = true + return self +end + +function selector_prototype:for_update_of(expression) + add(self._write_lock, expression) + return self +end + function selector_prototype:reset_fields() for idx in ipairs(self._fields) do self._fields[idx] = nil @@ -324,13 +342,13 @@ if #self._mode == "empty_list" then add(parts, "WHERE FALSE") elseif #self._where > 0 then - add(parts, {"WHERE $", self._where}) + add(parts, {"WHERE ($)", self._where}) end if #self._group_by > 0 then add(parts, {"GROUP BY $", self._group_by}) end if #self._having > 0 then - add(parts, {"HAVING $", self._having}) + add(parts, {"HAVING ($)", self._having}) end for i, v in ipairs(self._combine) do add(parts, v) @@ -348,6 +366,18 @@ if self._offset then add(parts, "OFFSET " .. self._offset) end + if self._write_lock.all then + add(parts, "FOR UPDATE") + else + if self._read_lock.all then + add(parts, "FOR SHARE") + elseif #self._read_lock > 0 then + add(parts, {"FOR SHARE OF $", self._read_lock}) + end + if #self._write_lock > 0 then + add(parts, {"FOR UPDATE OF $", self._write_lock}) + end + end return self._db_conn:assemble_command{"$", parts} end @@ -390,6 +420,18 @@ end end +-- NOTE: This function caches the result! +function selector_prototype:count() + if not self._count then + local count_selector = self:get_db_conn():new_selector() + count_selector:add_field('count(1)') + count_selector:add_from(self) + count_selector:single_object_mode() + self._count = count_selector:exec().count + end + return self._count +end + -----------------