rave-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfrank...@apache.org
Subject svn commit: r1095733 [2/2] - in /incubator/rave/trunk: ./ rave-portal/ rave-portal/src/main/db/ rave-portal/src/main/db/data/ rave-portal/src/main/db/sequences/ rave-portal/src/main/db/tables/ rave-portal/src/main/java/org/apache/rave/portal/model/ rav...
Date Thu, 21 Apr 2011 14:43:12 GMT
Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/PrePopulatedDataSourceFactory.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/PrePopulatedDataSourceFactory.java?rev=1095733&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/PrePopulatedDataSourceFactory.java
(added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/PrePopulatedDataSourceFactory.java
Thu Apr 21 14:43:10 2011
@@ -0,0 +1,300 @@
+package org.apache.rave.datasource;
+
+import org.apache.rave.datasource.util.SqlFileParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.core.io.Resource;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+
+/**
+ * {@inheritDoc}
+ * <p/>
+ * <p/>
+ * Creates a {@link javax.sql.DataSource} that is fully initialized with the schema and data
referenced in the
+ * application context.
+ * <p/>
+ * <p/>
+ * Usage:
+ * <code>
+ *  <bean id="dataSource" class="org.apache.rave.datasource.PrePopulatedDataSourceFactory">
+ *      <property name="jdbcUrl" value="jdbc://h2:mem:dbname" />
+ *      <property name="driver"  value="org.h2.Driver" />
+ *      <property name="user"    value="username" />
+ *      <property name="password" value="password" />
+ *      <property name="executeScriptQuery" value="SELECT * FROM widgets" />
+ *      <property name="scriptLocations" >
+ *          <list>
+ *              <value>file:db/sequences/create_all_seq.sql</value>
+ *              <value>file:db/tables/create_all_tables.sql</value>
+ *              <value>classpath:test-data.sql</value>
+ *          </list>
+ *      </property>
+ *  </bean>
+ * </code>
+ * <p/>
+ */
+public class PrePopulatedDataSourceFactory implements FactoryBean {
+
+    private static Logger logger = LoggerFactory.getLogger(PrePopulatedDataSourceFactory.class);
+
+    protected String jdbcUrl;
+    protected String driver;
+    protected String user;
+    protected String password;
+    protected String executeScriptQuery;
+    protected List<Resource> scriptLocations;
+
+    /**
+     * The DataSource singleton returned by the factory.
+     */
+    protected DataSource dataSource;
+
+    /**
+     * Creates a new factory with no initial values for required properties.
+     * <p/>
+     * NOTE: If the factory is initialized using the default constructor, the required properties
must be set prior to use
+     */
+    public PrePopulatedDataSourceFactory() {
+    }
+
+    /**
+     * Creates a new factory and sets teh properties to the passed in parameters
+     *
+     * @param scriptLocations    {@see setScriptLocations}
+     * @param jdbcUrl            {@see setJdbcUrl}
+     * @param driver             {@see setDriver}
+     * @param user               {@see setUser}
+     * @param password           {@see setPassword}
+     * @param executeScriptQuery {@see setExecuteScriptQuery}
+     */
+    public PrePopulatedDataSourceFactory(List<Resource> scriptLocations, String jdbcUrl,
String driver, String user, String password, String executeScriptQuery) {
+        setJdbcUrl(jdbcUrl);
+        setDriver(driver);
+        setUser(user);
+        setPassword(password);
+        setScriptLocations(scriptLocations);
+        setExecuteScriptQuery(executeScriptQuery);
+    }
+
+
+    /**
+     * Optional Property
+     * <p/>
+     * Set the query used to determine whether or not to execute the scripts on initialization
+     *
+     * @param executeScriptQuery the query to execute.  If there are no results of the query,
the scripts referenced
+     *                           in setScriptLocations will be executed.  The statement must
be a select statement.
+     */
+    public void setExecuteScriptQuery(String executeScriptQuery) {
+        this.executeScriptQuery = executeScriptQuery;
+    }
+
+    /**
+     * Optional Property
+     * <p/>
+     * Set the user to use for the JDBC Connection
+     *
+     * @param user the username to use for authentication
+     */
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    /**
+     * Optional Property
+     * <p/>
+     * Set the password to use for the JDBC Connection
+     *
+     * @param password the password to use for authentication
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * Required Property
+     * <p/>
+     * The JDBC url of the database to connect to (or instantiate for in-memory)
+     *
+     * @param jdbcUrl valid JDBC URL
+     */
+    public void setJdbcUrl(String jdbcUrl) {
+        this.jdbcUrl = jdbcUrl;
+    }
+
+    /**
+     * Required Property
+     * <p/>
+     * The JDBC driver to use for the DataSource
+     * <p/>
+     * NOTE: The driver must be in the classpath
+     *
+     * @param driver The fully qualified classname
+     */
+    public void setDriver(String driver) {
+        this.driver = driver;
+    }
+
+    /**
+     * Required Property
+     * <p/>
+     * Sets the locations of the files containing DDL to be executed against the database
+     * <p/>
+     * NOTE: Files are executed in order
+     *
+     * @param scriptLocations list of {@link Resource} compatible location strings
+     */
+    public void setScriptLocations(List<Resource> scriptLocations) {
+        this.scriptLocations = scriptLocations;
+    }
+
+    @PostConstruct
+    public void initializeFactory() {
+        validateProperties();
+    }
+
+    public Object getObject() throws Exception {
+        return getDataSource();
+    }
+
+    public Class getObjectType() {
+        return DataSource.class;
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+    /**
+     * Gets the singleton DataSource if created. Initializes if not already created.
+     *
+     * @return the DataSource
+     */
+    public DataSource getDataSource() {
+        if (dataSource == null) {
+            initializeDataSource();
+        }
+        return dataSource;
+    }
+
+    /*
+      Helper methods
+    */
+    protected void validateProperties() {
+        if (scriptLocations == null) {
+            throw new IllegalArgumentException("The path to the database schema DDL is required");
+        }
+        if (jdbcUrl == null) {
+            throw new IllegalArgumentException("The JDBC URL of the database is required");
+        }
+        if (driver == null) {
+            throw new IllegalArgumentException("The JDBC driver of the database connection
is required");
+        }
+        if (user == null) {
+            user = "sa";
+        }
+        if (password == null) {
+            user = "";
+        }
+    }
+
+    protected void initializeDataSource() {
+        this.dataSource = createDataSource();
+        populateDataSourceIfNecessary();
+    }
+
+    protected DataSource createDataSource() {
+        DriverManagerDataSource ds = new DriverManagerDataSource();
+        ds.setDriverClassName(driver);
+        ds.setUrl(jdbcUrl);
+        ds.setUsername(user);
+        ds.setPassword(password);
+        logger.debug("Created dataSource: " + ds.toString());
+        return ds;
+    }
+
+    protected String getConnectionString() {
+        return jdbcUrl;
+    }
+
+    protected void populateDataSourceIfNecessary() {
+        Connection conn = null;
+        try {
+            conn = dataSource.getConnection();
+            if (testExecuteScriptQuery(conn, executeScriptQuery)) {
+                logger.debug("Database is empty.  Loading script files");
+                executeScripts(conn, scriptLocations);
+            }
+        } catch (SQLException e) {
+            logger.error("Error querying or populating database", e);
+            throw new RuntimeException(e);
+        } finally {
+            closeConnection(conn);
+        }
+    }
+
+    /*
+      Static Helper methods
+    */
+    protected static void executeScripts(Connection connection, List<Resource> resources)
{
+        for (Resource script : resources) {
+            try {
+                String sql = new SqlFileParser(script).getSQL();
+                logger.debug("Executing sql:\n" + sql);
+                executeSql(sql, connection);
+                logger.debug("Successfully executed statement");
+
+            } catch (IOException e) {
+                throw new RuntimeException("File IO Exception while loading " + script.getFilename(),
e);
+            } catch (SQLException e) {
+                throw new RuntimeException("SQL exception occurred loading data from " +
script.getFilename(), e);
+            }
+        }
+    }
+
+    protected static boolean testExecuteScriptQuery(Connection conn, String executeScriptQuery)
{
+        boolean result;
+        try {
+            //If the ResultSet has any rows, the first method will return true
+            result = !executeQuery(conn, executeScriptQuery).first();
+        } catch (SQLException e) {
+            //Only return true if the execption we got is that the table was not found
+            result = e.getMessage().toLowerCase().matches("table \".*\" not found.*\n*.*");
+        }
+        logger.debug("Executed query " + executeScriptQuery + " with result " + result);
+        return result;
+    }
+
+    protected static void closeConnection(Connection conn) {
+        if (conn != null) {
+            try {
+                conn.close();
+            } catch (SQLException e) {
+                logger.error("Error closing connection to database", e);
+            }
+        }
+    }
+
+    protected static ResultSet executeQuery(Connection conn, String executeScriptQuery) throws
SQLException {
+        Statement statement = conn.createStatement();
+        return statement.executeQuery(executeScriptQuery);
+    }
+
+
+    protected static void executeSql(String sql, Connection connection) throws SQLException
{
+        Statement statement = connection.createStatement();
+        statement.execute(sql);
+    }
+
+
+}
\ No newline at end of file

Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/util/SqlFileParser.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/util/SqlFileParser.java?rev=1095733&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/util/SqlFileParser.java
(added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/datasource/util/SqlFileParser.java
Thu Apr 21 14:43:10 2011
@@ -0,0 +1,131 @@
+package org.apache.rave.datasource.util;
+
+import org.springframework.core.io.Resource;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Parses a file looking for create, alter, insert, update, delete or drop commands and appends
them to an output
+ * string or follows @@ syntax to read child scripts.
+ */
+public class SqlFileParser {
+    private static final Pattern WORD_PATTERN = Pattern.compile("^([a-zA-Z]*)[ ;]");
+    private static final String CHILD_SCRIPT_INDICATOR = "@@";
+    private static final Set<String> commandSet;
+
+    static {
+        commandSet = new HashSet<String>();
+        commandSet.add("create");
+        commandSet.add("alter");
+        commandSet.add("insert");
+        commandSet.add("update");
+        commandSet.add("drop");
+        commandSet.add("delete");
+        commandSet.add("commit");
+        commandSet.add("set");
+        commandSet.add("truncate");
+        commandSet.add("rollback");
+    }
+
+    private enum State {
+        INIT,
+        READFILE,
+        READSQL
+    }
+
+    private Stack<State> stateStack;
+    private Resource resource;
+
+    /**
+     * Constructor takes a Spring {@link Resource}
+     *
+     * @param resource the initial file to parse
+     */
+    public SqlFileParser(Resource resource) {
+        stateStack = new Stack<State>();
+        this.resource = resource;
+    }
+
+    /**
+     * Gets the executable SQL statements from the resource passed to the constructor and
its children
+     *
+     * @return a valid executable string containing SQL statements
+     * @throws IOException if the resource or its children are not found
+     */
+    public String getSQL() throws IOException {
+        return processResource(resource);
+    }
+
+    private String processResource(Resource res) throws IOException {
+        StringBuilder sql = new StringBuilder();
+        File resourceFile = res.getFile();
+        stateStack.push(State.INIT);
+        processFile(resourceFile, sql);
+        stateStack.pop();
+        return sql.toString();
+    }
+
+    private void processFile(File file, StringBuilder sql) throws IOException {
+        BufferedReader fileReader = new BufferedReader(new FileReader(file.getAbsoluteFile()));
+        String line = null;
+        while ((line = fileReader.readLine()) != null) {
+            processLine(sql, line);
+        }
+    }
+
+    private void processLine(StringBuilder sql, String line) throws IOException {
+        String lowerLine = line.toLowerCase().trim();
+        switch (stateStack.peek()) {
+            case INIT: {
+                if (lowerLine.startsWith(CHILD_SCRIPT_INDICATOR)) {
+                    //replace the current element in the stack with the new state
+                    stateStack.pop();
+                    stateStack.push(State.READFILE);
+                    processLine(sql, line);
+                } else if (commandSet.contains(getFirstWord(lowerLine))) {
+
+                    //replace the current element in the stack with the new state
+                    stateStack.pop();
+                    stateStack.push(State.READSQL);
+                    processLine(sql, line);
+                }
+                break;
+            }
+            case READFILE: {
+                stateStack.push(State.INIT);
+                Resource child = resource.createRelative(line.replace(CHILD_SCRIPT_INDICATOR,
""));
+                sql.append(processResource(child));
+                //Read File lines do not have a terminal character but are by definition
only one line long
+                stateStack.pop();
+                stateStack.push(State.INIT);
+                break;
+            }
+            case READSQL: {
+                sql.append(line);
+                //add a space to accommodate line breaks.  Not a big deal if extraneous spaces
are added
+                sql.append(" ");
+                if (lowerLine.endsWith(";")) {
+                    stateStack.pop();
+                    stateStack.push(State.INIT);
+                }
+                break;
+            }
+            default: {
+                throw new RuntimeException("Invalid State");
+            }
+        }
+    }
+
+    private static String getFirstWord(String line) {
+        Matcher match = WORD_PATTERN.matcher(line);
+        return match.find() ? match.group(1) : null;
+    }
+}

Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/JpaPageRepositoryTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/JpaPageRepositoryTest.java?rev=1095733&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/JpaPageRepositoryTest.java
(added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/JpaPageRepositoryTest.java
Thu Apr 21 14:43:10 2011
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.portal.repository;
+
+import org.apache.rave.portal.model.Page;
+import org.hamcrest.CoreMatchers;
+import org.junit.Test;
+import org.junit.Ignore;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.List;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author mfranklin
+ *         Date: 4/19/11
+ *         Time: 9:13 AM
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations={"classpath:test-context.xml", "file:src/main/webapp/WEB-INF/applicationContext.xml"})
+public class JpaPageRepositoryTest {
+
+    private static final String USER_ID = "canonical";
+    private static final String INVALID_USER = "BadUserId";
+    private static final String WIDGET_URL = "http://www.google.com/ig/modules/wikipedia.xml";
+
+    @Autowired
+    private PageRepository repository;
+
+    @Test
+    public void getAllPages_validUser_validPageSet() {
+        List<Page> pages = repository.getAllPages(USER_ID);
+        assertThat(pages, CoreMatchers.notNullValue());
+        assertThat(pages.size(), CoreMatchers.equalTo(1));
+        assertThat(pages.get(0).getRegions().size(), CoreMatchers.equalTo(2));
+        assertThat(pages.get(0).getRegions().get(0).getRegionWidgets().size(), CoreMatchers.equalTo(2));
+        assertThat(pages.get(0).getRegions().get(0).getRegionWidgets().get(0).getWidget().getUrl(),
CoreMatchers.equalTo(WIDGET_URL));
+    }
+    @Test
+    public void getAllPages_invalidUser_emptySet() {
+        List<Page> pages = repository.getAllPages(INVALID_USER);
+        assertThat(pages.isEmpty(), CoreMatchers.is(true));
+    }
+    @Test
+    public void getAllPages_nullUser_emptySet() {
+        List<Page> pages = repository.getAllPages(null);
+        assertThat(pages.isEmpty(), CoreMatchers.is(true));
+    }
+}

Added: incubator/rave/trunk/rave-portal/src/test/resources/log4j.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/resources/log4j.xml?rev=1095733&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/resources/log4j.xml (added)
+++ incubator/rave/trunk/rave-portal/src/test/resources/log4j.xml Thu Apr 21 14:43:10 2011
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  
+  $Id: log4j.xml 1090921 2011-04-11 01:34:00Z ate $
+-->
+<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER" "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+  <!-- Appenders -->
+  <appender name="console" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.out" />
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%-5p: %c - %m%n" />
+    </layout>
+  </appender>
+
+  <!-- Springframework logger -->
+  <logger name="org.springframework">
+    <level value="info" />
+    <appender-ref ref="console" />
+  </logger>
+
+  <!-- Rave logger -->
+  <logger name="org.apache.rave">
+    <level value="debug" />
+    <appender-ref ref="console" />
+  </logger>
+  
+  <!-- Root Logger -->
+  <root>
+    <priority value="warn" />
+    <appender-ref ref="console" />
+  </root>
+    
+</log4j:configuration>
\ No newline at end of file

Added: incubator/rave/trunk/rave-portal/src/test/resources/test-context.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/resources/test-context.xml?rev=1095733&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/resources/test-context.xml (added)
+++ incubator/rave/trunk/rave-portal/src/test/resources/test-context.xml Thu Apr 21 14:43:10
2011
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+        <bean id="dataSource" class="org.apache.rave.datasource.PrePopulatedDataSourceFactory">
+            <property name="jdbcUrl" value="jdbc:h2:mem:portal;DB_CLOSE_DELAY=-1"/>
+            <property name="driver" value="org.h2.Driver" />
+            <property name="user" value="sa" />
+            <property name="password" value="local" />
+            <property name="executeScriptQuery" value="SELECT * FROM widgets" />
+            <property name="scriptLocations" >
+                <list>
+                    <value>file:src/main/db/sequences/create_all_seq.sql</value>
+                    <value>file:src/main/db/tables/create_all_tables.sql</value>
+                    <value>file:src/main/db/data/initial_data.sql</value>
+                    <value>classpath:test-data.sql</value>
+                </list>
+            </property>
+        </bean>
+
+</beans>

Added: incubator/rave/trunk/rave-portal/src/test/resources/test-data.sql
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/resources/test-data.sql?rev=1095733&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/resources/test-data.sql (added)
+++ incubator/rave/trunk/rave-portal/src/test/resources/test-data.sql Thu Apr 21 14:43:10
2011
@@ -0,0 +1,10 @@
+INSERT INTO page (id, name, owner_id, render_sequence, page_layout_id) values (set(@page_1_id,
next value for page_id_seq), 'main', @user_id_1, 1, @two_col_id);
+
+INSERT INTO region(id, page_id) values (set(@page_1_region_1, next value for region_id_seq),
@page_1_id);
+INSERT INTO region(id, page_id) values (set(@page_1_region_2, next value for region_id_seq),
@page_1_id);
+
+INSERT INTO region_widget(id, widget_id, region_id, render_position, collapsed) values (next
value for region_widget_id_seq, @wikipedia_widget_id, @page_1_region_1, 1, 'N');
+INSERT INTO region_widget(id, widget_id, region_id, render_position, collapsed) values (next
value for region_widget_id_seq, @translate_widget_id, @page_1_region_1, 2, 'N');
+
+INSERT INTO region_widget(id, widget_id, region_id, render_position, collapsed) values (next
value for region_widget_id_seq, @nyt_widget_id, @page_1_region_2, 1, 'N');
+INSERT INTO region_widget(id, widget_id, region_id, render_position, collapsed) values (next
value for region_widget_id_seq, @tabnews_widget_id, @page_1_region_2, 2, 'N');
\ No newline at end of file



Mime
View raw message