text:
// Copyright (C) 2017 Meituan
// All rights reserved
package com.myframe.test.boot;

import com.google.common.collect.Maps;
import com.myframe.dao.util.Cnd;
import com.myframe.dao.util.UpdateChain;
import com.myframe.test.mapper.PriceMapper;
import com.myframe.test.mapper.UserMapper;
import com.myframe.test.pojo.TestPrice;
import com.myframe.test.pojo.User;
import org.apache.ibatis.session.RowBounds;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author wuyuzhen
 * @version 1.0
 * @created 17/2/2 22:23
 */
@SpringBootApplication(scanBasePackages = {
        "com.sankuai.ia.mapper.test.boot",
        "com.sankuai.ia.mapper.springboot"
})
public class MapperTest implements CommandLineRunner {

    //@Autowired
    // private BaseMapper<User> userMapper; // 无自定义接口可直接使用该方式
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private PriceMapper priceMapper;
    private static final String dynamicSuffix = "20170207";

    @Override
    public void run(String... strings) throws Exception {
        testGet();
        testUpdate();
        testInsert();
        testDelete();
        testCustom();
        Cnd.registerDynamicTableNameSuffix(MapperTest::getSuffix);
        testPriceGet();
        Cnd.unregisterDynamicTableNameSuffix();
        testPriceUpdate();
        testPriceInsert();
        testPriceDelete();

        testInsertList();
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(MapperTest.class, args);
    }

    public void testGet() {
        User user = userMapper.getById(1L);
        Assert.assertNotNull(user);

        user = userMapper.get(Cnd.whereEQ("id", 1L).excludes("createTime", "birthday"));
        Assert.assertNotNull(user);

        List<User> users = userMapper.getList(Cnd.whereLike("userName", "%user%")
                .andLT("age", 31).includes("id", "userName").desc("age"));
        Assert.assertNotNull(users);
        Assert.assertEquals(10, users.size());

        users = userMapper.getAll();
        Assert.assertNotNull(users);
        Assert.assertEquals(58, users.size());

        users = userMapper.getPageList(Cnd.where().excludes("createTime"), new RowBounds(1, 10));
        Assert.assertNotNull(users);
        Assert.assertEquals(10, users.size());

        Integer count = userMapper.getAllCount();
        Assert.assertEquals(58, count.intValue());

        count = userMapper.getCount(Cnd.whereEQ("id", 2L));
        Assert.assertEquals(1, count.intValue());
    }

    public void testUpdate() {
        User user = userMapper.getById(1L);
        Assert.assertNotNull(user);
        user.setAge(1);
        userMapper.updateById(user);
        user = userMapper.getById(1L);
        Assert.assertEquals(1, user.getAge().intValue());

        userMapper.updateByChain(UpdateChain.make("age", 3)
                .set("userName", "user_mapperUpdate")
                .where(Cnd.whereEQ("id", 1L)));
        user = userMapper.getById(1L);
        Assert.assertEquals(3, user.getAge().intValue());
        Assert.assertEquals("user_mapperUpdate", user.getUserName());

        userMapper.updateByChain(UpdateChain.make("userName", "user_mapperUpdate")
                .plus("age", 2).where(Cnd.whereEQ("id", 1L)));

        user = userMapper.getById(1L);
        Assert.assertEquals(5, user.getAge().intValue());
        Assert.assertEquals("user_mapperUpdate", user.getUserName());

        userMapper.updateByChain(UpdateChain.make().plus("age", 2).where(Cnd.whereEQ("id", 1L)));
        user = userMapper.getById(1L);
        Assert.assertEquals(7, user.getAge().intValue());
        userMapper.updateByChain(UpdateChain.make().minus("age", 2).where(Cnd.whereEQ("id", 1L)));
        user = userMapper.getById(1L);
        Assert.assertEquals(5, user.getAge().intValue());
        userMapper.updateByChain(UpdateChain.make().multiply("age", 2).where(Cnd.whereEQ("id", 1L)));
        user = userMapper.getById(1L);
        Assert.assertEquals(10, user.getAge().intValue());
        userMapper.updateByChain(UpdateChain.make().divide("age", 2).where(Cnd.whereEQ("id", 1L)));
        user = userMapper.getById(1L);
        Assert.assertEquals(5, user.getAge().intValue());

        user.setGender(null);
        user.setBirthday(null);
        user.setPassword(null);
        user.setAge(null);
        user.setUserName("user_updateNotNull");

        userMapper.updateNotNullById(user);

        user = userMapper.getById(1L);
        Assert.assertEquals("user_updateNotNull", user.getUserName());
        Assert.assertNotSame(user.getModifyTime(), user.getCreateTime());
    }

    public void testInsert() {
        User user = new User();
        user.setAge(1);
        user.setPassword("123456");
        user.setUserName("test_for_insertOne");
        user.setGender((short) 1);
        user.setBirthday(new Date());

        userMapper.insert(user);

        Assert.assertNotNull(user.getId());
        user = userMapper.getById(user.getId());
        Assert.assertNotNull(user.getCreateTime());
        Assert.assertNotNull(user.getModifyTime());
    }

    public void testDelete() {
        userMapper.deleteById(64L);

        userMapper.delete(Cnd.whereLike("userName", "test_for_insert%"));

        Integer count = userMapper.getCount(Cnd.whereLike("userName", "test_for_insert%"));

        Assert.assertEquals(count.intValue(), 0);
    }

    public void testCustom() {
        Map<String, Object> params = Maps.newHashMap();
        params.put("userName", "%test_for%");
        Integer count = userMapper.selectCount2(params);
        Assert.assertNotNull(count);
        Assert.assertEquals(0, count.intValue());
        params.put("id", 2L);
        User user = userMapper.selectOne2(params);
        Assert.assertNotNull(user);
        Assert.assertEquals(user.getUserName(), "user2_modifyList");
    }

    public static String getSuffix() {
        return dynamicSuffix;
    }

    public void testPriceGet() {
        TestPrice price = priceMapper.get(Cnd.whereEQ("id", 1L).excludes("createTime"));
        Assert.assertNotNull(price);

        List<TestPrice> prices = priceMapper.getList(Cnd.whereGT("price", 305)
                .includes("id", "price")
                .desc("price"));
        Assert.assertNotNull(prices);
        Assert.assertEquals(7, prices.size());

        prices = priceMapper.getPageList(Cnd.where().excludes("createTime"), new RowBounds(1, 10));
        Assert.assertNotNull(prices);
        Assert.assertEquals(10, prices.size());

        Integer count = priceMapper.getCount(Cnd.whereEQ("id", 2L));
        Assert.assertEquals(1, count.intValue());
    }

    public void testPriceUpdate() {
        TestPrice price = priceMapper.get(Cnd.whereEQ("id", 1L)
                                             .dynamicSuffix(dynamicSuffix));
        Assert.assertNotNull(price);

        price.setPrice(250);

        priceMapper.updateById(price);
        price = priceMapper.get(Cnd.whereEQ("id", 1L).dynamicSuffix(dynamicSuffix));
        Assert.assertEquals(250, price.getPrice().intValue());

        priceMapper.updateByChain(UpdateChain.make("price", 298)
                .where(Cnd.whereEQ("id", 1L).dynamicSuffix(dynamicSuffix).dynamicSuffixSeparator("")));
        price = priceMapper.get(Cnd.whereEQ("id", 1L).dynamicSuffix(dynamicSuffix).dynamicSuffixSeparator(""));
        Assert.assertEquals(298, price.getPrice().intValue());
    }

    public void testPriceInsert() {
        TestPrice price = new TestPrice();
        price.setPrice(288);
        price.setPriceDate(Integer.parseInt(dynamicSuffix));
        price.setCreateTime(new Date());

        priceMapper.insert(price);

        Assert.assertNotNull(price.getId());
        price = priceMapper.get(Cnd.whereEQ("id", price.getId()).dynamicSuffix(dynamicSuffix));
        Assert.assertEquals(price.getPrice().intValue(), 288);
    }

    public void testPriceDelete() {
        priceMapper.delete(Cnd.whereEQ("id", 1L).dynamicSuffix(dynamicSuffix).dynamicSuffixSeparator(""));

        Integer count = priceMapper.getCount(Cnd.whereEQ("id", 1L).dynamicSuffix(dynamicSuffix).dynamicSuffixSeparator(""));

        Assert.assertEquals(count.intValue(), 0);
    }

    public void testInsertList() {
        List<User> users = mockData();
        userMapper.insertList(users);
        User user1 = userMapper.get(Cnd.whereEQ("userName", "a"));
        User user2 = userMapper.get(Cnd.whereEQ("userName", "b"));
        Assert.assertNotNull(user1);
        Assert.assertNotNull(user1.getCreateTime());
        Assert.assertNotNull(user1.getModifyTime());
        Assert.assertNotNull(user2);
        Assert.assertNotNull(user2.getCreateTime());
        Assert.assertNotNull(user2.getModifyTime());
    }

    private List<User> mockData() {
        User user1 = new User();
        user1.setAge(1);
        user1.setPassword("123456");
        user1.setUserName("a");
        user1.setGender((short) 1);
        user1.setBirthday(new Date());

        User user2 = new User();
        user2.setAge(2);
        user2.setPassword("123456");
        user2.setUserName("b");
        user2.setGender((short) 1);
        user2.setBirthday(new Date());
        return Arrays.asList(user1, user2);
    }
}


text:
#region copyright

#endregion

namespace VZF.Utils
{
	#region Using

	using System.Collections.Generic;
	using System.Text;

	using YAF.Types;

	#endregion

	/// <summary>
	/// The bit bool extensions.
	/// </summary>
	public static class BitBoolExtensions
	{
		#region Public Methods

		/// <summary>
		/// Gets boolean indicating whether bit on bitShift position in bitValue integer is set or not.
		/// </summary>
		/// <param name="bitValue">
		/// Integer value.
		/// </param>
		/// <param name="bitShift">
		/// Zero-based position of bit to get.
		/// </param>
		/// <returns>
		/// Returns boolean indicating whether bit at bitShift position is set or not.
		/// </returns>
		public static bool GetBitAsBool(int bitValue, int bitShift)
		{
			if (bitShift > 63)
			{
				bitShift %= 63;
			}

			return ((bitValue >> bitShift) & 0x00000001) == 1;
		}

		/// <summary>
		/// Sets or unsets bit of bitValue integer at position specified by bitShift, depending on value parameter.
		/// </summary>
		/// <param name="bitValue">
		/// Integer value.
		/// </param>
		/// <param name="bitShift">
		/// Zero-based position of bit to set.
		/// </param>
		/// <param name="value">
		/// New boolean value of bit.
		/// </param>
		/// <returns>
		/// Returns new integer value with bit at position specified by bitShift parameter set to value.
		/// </returns>
		public static int SetBitFromBool(int bitValue, int bitShift, bool value)
		{
			if (bitShift > 63)
			{
				bitShift %= 63;
			}

			if (GetBitAsBool(bitValue, bitShift) != value)
			{
				// toggle that value using XOR
				int tV = 0x00000001 << bitShift;
				bitValue ^= tV;
			}

			return bitValue;
		}

		/// <summary>
		/// The to hex string.
		/// </summary>
		/// <param name="hashedBytes">
		/// The hashed bytes.
		/// </param>
		/// <returns>
		/// The to hex string.
		/// </returns>
		[NotNull]
		public static string ToHexString([NotNull] this byte[] hashedBytes)
		{
			CodeContracts.ArgumentNotNull(hashedBytes, "hashedBytes");

			var hashedSB = new StringBuilder((hashedBytes.Length * 2) + 2);

			foreach (byte b in hashedBytes)
			{
				hashedSB.AppendFormat("{0:X2}", b);
			}

			return hashedSB.ToString();
		}

		/// <summary>
		/// Creates an integer value from an array of booleans.
		/// </summary>
		/// <param name="arrayBool">
		/// array of boolean
		/// </param>
		/// <returns>
		/// bit field of the array
		/// </returns>
		public static int ToIntOfBits(this IEnumerable<bool> arrayBool)
		{
			int finalValue = 0;
			arrayBool.ForEachIndex((b, i) => finalValue = SetBitFromBool(finalValue, i, b));

			return finalValue;
		}

		#endregion
	}
}

redpajama_set_name: RedPajamaGithub


text:
package io.silverspoon.bulldog.core.pwm;

import io.silverspoon.bulldog.core.Signal;
import io.silverspoon.bulldog.core.gpio.DigitalOutput;
import io.silverspoon.bulldog.core.pin.Pin;
import io.silverspoon.bulldog.core.util.BulldogUtil;
import io.silverspoon.bulldog.core.util.DaemonThreadFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class SoftPwm extends AbstractPwm implements Runnable {

   private static final long NANOSECONDS_PER_SECOND = 1000000000;

   private ScheduledExecutorService executorService;
   private DigitalOutput output;

   private int dutyInNanoseconds;
   private int periodInNanoseconds;
   private ScheduledFuture<?> future;

   public SoftPwm(Pin pin) {
      super(pin);
      if (!pin.hasFeature(DigitalOutput.class)) {
         throw new IllegalArgumentException("The pin must be able to act as a DigitalOutput");
      }

      this.output = pin.getFeature(DigitalOutput.class);
      pin.getFeatures().add(this);
   }

   public SoftPwm(DigitalOutput output) {
      this(output.getPin());
   }

   private void createScheduler() {
      if (executorService != null) {
         return;
      }
      executorService = Executors.newScheduledThreadPool(1, new DaemonThreadFactory());
      future = executorService.scheduleAtFixedRate(this, 0, periodInNanoseconds, TimeUnit.NANOSECONDS);
   }

   private void terminateScheduler() {
      if (executorService == null) {
         return;
      }
      if (future != null) {
         future.cancel(true);
         future = null;
      }
      executorService.shutdownNow();
      try {
         executorService.awaitTermination(1000, TimeUnit.MICROSECONDS);
      } catch (InterruptedException e) {
         e.printStackTrace();
      }
      executorService = null;
   }

   @Override
   public void run() {
      output.applySignal(Signal.High);
      BulldogUtil.sleepNs(dutyInNanoseconds);
      output.applySignal(Signal.Low);
   }

   @Override
   public void setupImpl() {
      output.setup();
   }

   @Override
   public void teardownImpl() {
      terminateScheduler();
      output.teardown();
   }

   @Override
   protected void setPwmImpl(double frequency, double duty) {
      periodInNanoseconds = (int) ((1.0 / frequency) * NANOSECONDS_PER_SECOND);
      dutyInNanoseconds = (int) (periodInNanoseconds * duty);
   }

   @Override
   protected void enableImpl() {
      if (!isActivatedFeature()) {
         activate();
      }

      blockPin();
      createScheduler();
   }

   @Override
   protected void disableImpl() {
      terminateScheduler();
      unblockPin();
   }

}


text:
#ifndef BOOST_SPIRIT_REPOSITORY_INCLUDE_QI_CONFIX
#define BOOST_SPIRIT_REPOSITORY_INCLUDE_QI_CONFIX

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/repository/home/qi/directive/confix.hpp>

#endif


text:
package com.anrisoftware.globalpom.math.format.measurement;

import static com.anrisoftware.globalpom.math.format.measurement.ValueFormatLogger.m.unparseable;
import static java.lang.String.format;
import static java.util.regex.Pattern.compile;

import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.anrisoftware.globalpom.math.measurement.ValueFactory;

public class ValueParserWorkerFactory {

    /**
     * {@code <(1)minus?>\d+}
     */
    private static String NUMBER_PATTERN = "%1$s?\\d+";

    /**
     * {@code <(1)minus?>\d+<(2)decimal?>\d*}
     */
    private static String DEC_PATTERN = "%1$s?\\d+%2$s?\\d*";

    /**
     * {@code <(2)exp><(1)minus?>\d+}
     */
    private static String EXP_PATTERN = "%2$s%1$s?\\d+";

    /**
     * {@code <(1)number><(2)exp?>}
     */
    private static String SIMPLE_PATTERN = "^(%1$s)(%2$s)?$";

    /**
     * {@code <(1)number><(3)exp?>(<(2)decnumber><(3)exp?>)}
     */
    private static String UNCERTAIN_PATTERN = "^(%1$s)(%3$s)?(\\(%2$s(?:%3$s)?\\))$";

    /**
     * {@code <(1)decnumber><(2)exp?>(<(1)decnumber><(2)exp?>)}
     */
    private static String DEC_UNCERTAIN_PATTERN = "^(%1$s)(%2$s)?(\\(%1$s(?:%2$s)?\\))$";

    /**
     * {@code <(1)decnumber><(2)exp?>(<(1)decnumber><(3)percent>)}
     */
    private static String UNCERTAIN_PERCENT_PATTERN = "^(%1$s)(%2$s)?(\\(%1$s%3$s\\))$";

    /**
     *

     * Pattern: {@code "<(2)decnumber>(<(1)number>)<(3)exp?>"}
     *

     *

     * Examples:
     *

     *
{@code 12.12(5)E5}
     *

     *

     */
    private static String UNCERTAIN_SHORT_PATTERN = "^(%2$s)(\\(%1$s\\))(%3$s)?$";

    private final Pattern simplePattern;

    private final DecimalFormatSymbols symbols;

    private final Locale locale;

    private final Integer significant;

    private final Integer decimal;

    private final ValueFactory valueFactory;

    private final Pattern uncertainPattern;

    private final Pattern uncertainPercentPattern;

    private final Pattern uncertainShortPattern;

    private final Pattern decUncertainPattern;

    public ValueParserWorkerFactory(DecimalFormatSymbols symbols, Locale locale, Integer significant, Integer decimal,
            ValueFactory valueFactory) {
        this.symbols = symbols;
        this.locale = locale;
        this.significant = significant;
        this.decimal = decimal;
        this.valueFactory = valueFactory;
        char min = symbols.getMinusSign();
        String ex = symbols.getExponentSeparator();
        char dec = symbols.getDecimalSeparator();
        char percent = symbols.getPercent();
        String decPattern = format(DEC_PATTERN, min, dec);
        String numberPattern = format(NUMBER_PATTERN, min, dec);
        String expPattern = format(EXP_PATTERN, min, ex);
        this.simplePattern = compile(format(SIMPLE_PATTERN, decPattern, expPattern), Pattern.MULTILINE);
        this.uncertainPattern = compile(format(UNCERTAIN_PATTERN, numberPattern, decPattern, expPattern),
                Pattern.MULTILINE);
        this.uncertainPercentPattern = compile(format(UNCERTAIN_PERCENT_PATTERN, decPattern, expPattern, percent),
                Pattern.MULTILINE);
        this.uncertainShortPattern = compile(format(UNCERTAIN_SHORT_PATTERN, numberPattern, decPattern, expPattern),
                Pattern.MULTILINE);
        this.decUncertainPattern = compile(format(DEC_UNCERTAIN_PATTERN, decPattern, expPattern), Pattern.MULTILINE);
    }

    public ValueParserWorker getValueParserWorker(String source, ParsePosition pos) throws ParseException {
        source = source.toUpperCase(locale);
        Matcher matcher = simplePattern.matcher(source);
        String valueStr;
        String exponentStr;
        String uncString;
        if (matcher.matches()) {
            valueStr = matcher.group(1);
            exponentStr = matcher.group(2);
            uncString = null;
            return new SimpleNumberValueParserWorker(symbols, locale, significant, decimal, valueFactory, valueStr,
                    exponentStr, uncString);
        }
        matcher = uncertainPattern.matcher(source);
        if (matcher.matches()) {
            valueStr = matcher.group(1);
            exponentStr = matcher.group(2);
            uncString = matcher.group(3);
            return new SimpleNumberValueParserWorker(symbols, locale, significant, decimal, valueFactory, valueStr,
                    exponentStr, uncString);
        }
        matcher = uncertainPercentPattern.matcher(source);
        if (matcher.matches()) {
            valueStr = matcher.group(1);
            exponentStr = matcher.group(2);
            uncString = matcher.group(3);
            return new SimpleNumberValueParserWorker(symbols, locale, significant, decimal, valueFactory, valueStr,
                    exponentStr, uncString);
        }
        matcher = uncertainShortPattern.matcher(source);
        if (matcher.matches()) {
            valueStr = matcher.group(1);
            exponentStr = matcher.group(3);
            uncString = matcher.group(2);
            return new UncertainShortNumberValueParserWorker(symbols, locale, significant, decimal, valueFactory,
                    valueStr, exponentStr, uncString);
        }
        matcher = decUncertainPattern.matcher(source);
        if (matcher.matches()) {
            valueStr = matcher.group(1);
            exponentStr = matcher.group(2);
            uncString = matcher.group(3);
            return new SimpleNumberValueParserWorker(symbols, locale, significant, decimal, valueFactory, valueStr,
                    exponentStr, uncString);
        }
        throw new ParseException(unparseable.toString(), pos.getErrorIndex());
    }
}


text:
<?php

class Sabre_DAV_Exception_MethodNotAllowed extends Sabre_DAV_Exception {

    /**
     * Returns the HTTP statuscode for this exception
     *
     * @return int
     */
    public function getHTTPCode() {

        return 405;

    }

    /**
     * This method allows the exception to return any extra HTTP response headers.
     *
     * The headers must be returned as an array.
     *
     * @return array
     */
    public function getHTTPHeaders(Sabre_DAV_Server $server) {

        $methods = $server->getAllowedMethods($server->getRequestUri());

        return array(
            'Allow' => strtoupper(implode(', ',$methods)),
        );

    }

}


text:
#include "../gtest.h"

#include <scraps/net/utility.h>

using namespace scraps;
using namespace scraps::net;

TEST(NetUtility, Resolve) {
    auto addresses = Resolve("google.com");
    EXPECT_FALSE(addresses.empty());
}

TEST(NetUtility, ResolveWithIPAddress) {
    auto addresses = Resolve("127.0.0.1");
    ASSERT_FALSE(addresses.empty());
    EXPECT_EQ(addresses[0].to_v4().to_ulong(), 0x7f000001);
}

TEST(NetUtility, IsLocal) {
    EXPECT_FALSE(IsLocal(Address::from_string("8.8.8.8")));
    EXPECT_TRUE(IsLocal(Address::from_string("127.0.0.1")));
    EXPECT_TRUE(IsLocal(Address::from_string("10.1.2.3")));
    EXPECT_TRUE(IsLocal(Address::from_string("192.168.1.2")));
    EXPECT_TRUE(IsLocal(Address::from_string("172.20.1.2")));
    EXPECT_FALSE(IsLocal(Address::from_string("172.10.1.2")));
}

TEST(NetUtility, ResolveRandomEndpoint) {
    auto first = ResolveRandomEndpoint("amazon.com", 80);
    ASSERT_TRUE(first);
    EXPECT_EQ(first->port(), 80);
    for (int i = 0; i < 20; ++i) {
        auto next = ResolveRandomEndpoint("amazon.com", 80);
        ASSERT_TRUE(next);
        EXPECT_EQ(next->port(), 80);
        if (*first != *next) {
            return;
        }
    }
    EXPECT_FALSE("we got the same endpoint every time. it should have been random");
}

TEST(NetUtility, ResolveRandomIPv4Endpoint) {
    auto first = ResolveRandomIPv4Endpoint("amazon.com", 80);
    ASSERT_TRUE(first);
    EXPECT_EQ(first->port(), 80);
    for (int i = 0; i < 20; ++i) {
        auto next = ResolveRandomIPv4Endpoint("amazon.com", 80);
        ASSERT_TRUE(next);
        EXPECT_TRUE(next->address().is_v4());
        EXPECT_EQ(next->port(), 80);
        if (*first != *next) {
            return;
        }
    }
    EXPECT_FALSE("we got the same endpoint every time. it should have been random");
}


text:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <refos/test.h>

/*! @file
    @brief Testing helper library. */

#ifdef CONFIG_REFOS_RUN_TESTS

/*! @brief The width at which the test results are aligned to. This should be larger than the
           lngest test name to ensure alignment. Too large and it may wrap around the terminal. */
#define REFOS_TEST_WIDTH 80

struct test_failure_log {
    int line;
    const char *file;
    const char *func;
    const char *check;
};

char *test_title = "";

static struct test_failure_log _testsFailLog[TEST_MAX_TESTS];
static unsigned int _testsFailed = 0;

void
test_start(const char *name)
{
    static char temp_buffer[TEST_TITLE_BUFFER_LEN];
    temp_buffer[0] = '\0';
    sprintf(temp_buffer, "%s | Testing %s ", test_title, name);
    tprintf("%s", temp_buffer);
    for (unsigned int i = strlen(temp_buffer); i < REFOS_TEST_WIDTH; i++) {
        tprintf(".");
    }
    tprintf(" ");
}

int
test_fail(const char *check, const char *file, const char *func, int line)
{
    tprintf(TEST_RED "FAILED" TEST_RESET ".\n");
    _testsFailLog[_testsFailed].check = check;
    _testsFailLog[_testsFailed].file = file;
    _testsFailLog[_testsFailed].func = func;
    _testsFailLog[_testsFailed].line = line;
    _testsFailed++;
    return -1;
}

int
test_success()
{
    tprintf(TEST_GREEN "PASSED" TEST_RESET ".\n");
    return 0;
}

void
test_print_log(void)
{
    for (unsigned int i = 0; i < _testsFailed; i++) {
        tprintf("%s | Test assert failed: %s, function %s, "
                "file %s, line %d.\n", test_title, _testsFailLog[i].check, _testsFailLog[i].func,
                _testsFailLog[i].file, _testsFailLog[i].line);
    }
    if (_testsFailed == 0) {
        tprintf("%s | All is well in the universe.\n", test_title);
    }
}

#endif /* CONFIG_REFOS_RUN_TESTS */


text:
Each directory is compiled to a page and it's files are compiled as page sections.

But you can modify some behaviour using **page configuration file**.

### Page configuration

To configure a page just create **`config.json`** file into page directory. This also aplies to root directory.

Following configuration properties are available for this default template:

:::sidecode
### Sample page configuration
./pages/My_Page/config.json
```json
{
	"icon": "school",
	"slug": "getting-started",
	"hidden": false,
	"template": "my-template",
	"page_title": "Getting Started page"
}
```
:::

| Property name | Description |
| ------------- | ----------- |
| icon | Specifies MDI icon name without `mdi-` prefix. |
| slug | Specifies custom URL slug for page that will be used instead of generated one. |
| hidden | Boolean value. If true page is then excluded from navigation tree but can be accessed directly by URL. |
| template | Specifies alternative template name - without `.jade` file extension. |
| page_title | Overrides page title which is set to page label by default. |

::: info
Page configuration properties also overrides default configuration. So you can set for example different description or keywords for each page.
:::


text:
package net.sourceforge.simcpux;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.justep.cordova.Config;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;

public class AppRegister extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		Config.init();
		final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
		// 将该app注册到微信
		msgApi.registerApp(Config.getPreferences().getString("weixinappid", ""));
	}
}


text:
<?php

use Webforge\Common\System\Dir;
use Webforge\Common\System\File;
use Webforge\Common\Preg;

/**
 *
 * $createCommand = function ($name, array|closure $configure, closure $execute, $help = NULL)
 *
 * // argument
 * $arg = function ($name, $description = NULL, $required = TRUE, $multiple = FALSE) // default: required
 *
 * // option
 * $opt = function($name, $short = NULL, $withValue = TRUE, $description = NULL) // default: mit value required
 * $flag = function($name, $short = NULL, $description) // ohne value
 */

$createCommand('compile:code-standards',
  array(
    $arg('code-standard-name', 'the namespace of the code-standards to compile: currently only PSR', $required = TRUE)
  ),
  function ($input, $output, $command) {
    $namespace = $input->getArgument('code-standard-name');
    $namespaceDir = Dir::factoryTS(__DIR__)->sub($fullNamespace = 'Webforge/TestData/PHPCodeStandard/'.$namespace.'/');
    $fullNamespace = str_replace('/', '\\', $fullNamespace);
    $resources = $namespaceDir->sub('resources/');
    $tplCode = $resources->getFile('CodeIndentationCase.template.php')->getContents();

    $convertName = function (File $caseFile) {
      return ucfirst(
        Preg::replace_callback($caseFile->getName(File::WITHOUT_EXTENSION), '/\-([a-z])/', function ($match) {
          return mb_strtoupper($match[1]);
        })
      ).'Case.php';
    };

    $output->writeln('writing test cases in '.$resources);

    $list = array();
    foreach ($resources->sub('Cases')->getFiles('php') as $caseFile) {
      $phpCode = mb_substr($caseFile->getContents(), mb_strlen("<?php\n"));

      $testCase = $namespaceDir->getFile($convertName($caseFile));
      $testCase->writeContents(
        \Psc\TPL\TPL::miniTemplate(
          $tplCode,
          array(
            'className'=>$className = $testCase->getName(File::WITHOUT_EXTENSION),
            'stringCode'=>$phpCode,
            'phpCode'=>$phpCode
          )
        )
      );

      $list[] = $fullNamespace.$className;

      $output->writeln('  wrote '.$testCase);
    }

    $indexFile = $resources->getFile('list.php');
    $output->writeln('writing index-list: '.$indexFile);
    $indexFile->writeContents('<?php'."\n".'$list = '.var_export($list, true).'; '."\n".'?>');

    $output->writeln('<info>finished.</info>');

    return 0;
  },
  'the command writes all cases for a code standard (coding style) out from its resources directory into'
);
?>


text:
Term48 is a terminal emulator for BlackBerry. It implements (relevant parts of) the [ECMA-48 standard][ecma], but also includes some other control sequences to make it compliant with the xterm-256color terminfo specification. It is a work in progress, but is good enough to be used regularly by the author.

You can get Term48 from BB World.

[http://appworld.blackberry.com/webstore/content/26272878/](http://appworld.blackberry.com/webstore/content/26272878/)

The current version runs on BB10 devices, and requires version >= 10.3. An older version is available for the Playbook.

To compile Term48, you will need some additional libraries:

* [libSDL][libsdl]
* [Touch Control Overlay][tco]
* [libconfig][libconfig]

Prebuilt versions of these shared libraries are available in `external/lib` (see Makefile); to build from source you will need to check out the submodules (call `git clone` with the `--recursive` option) and build them with the Momentics IDE. Note that when compiling SDL, you must define `-D__PLAYBOOK__ -DRAW_KEYBOARD_EVENTS`.

You can build and deploy Term48 without using Momentics IDE:

* Load the proper `bbndk-env` file
* Copy your debug token to `signing/debugtoken.bar` (or see section below on generating a debug token)
* Populate the `BBIP` and `BBPASS` fields in `signing/bbpass` with your device's dev-mode IP address and device password
* Update the `<author>` and `<authorId>` tags in `bar-descriptor.xml` to match the `Package-Author` and `Package-Author-Id` for your debug token: `unzip -p signing/debugtoken.bar META-INF/MANIFEST.MF | grep 'Package-Author:\|Package-Author-Id:'`
* `make`
* `make deploy`

You can set whatever PackageID and whatnot that you like in the bar-descriptor.xml file. If you want to be able to access shared files on the device, check the 'Files' box under `Application/Permissions`.

As this is a work in progress, pull requests or feature requests are welcome. Please report any bugs with an Issue.

[ecma]: http://www.ecma-international.org/publications/standards/Ecma-048.htm
[libsdl]: https://github.com/mordak/SDL/tree/term48
[tco]: https://github.com/blackberry/TouchControlOverlay
[libconfig]: http://www.hyperrealm.com/libconfig/

# Generating a Debug Token

* Use this form to obtain your `bbidtoken.csk` file: https://developer.blackberry.com/codesigning/
* Copy `bbidtoken.csk` to `signing/bbidtoken.csk`
* In `signing/bbpass`, fill in:
  - `CNNAME`: the Common Name for your signing cert (usually your name)
  - `KEYSTOREPASS`: CSK password you entered in step 1 signup
  - `BBPIN`: target device's PIN
  - `BBPASS`: target device's password
* Run `make` in `signing/Makefile` to request and deploy the token to your device.

Important: any symbols need to be escaped according to bash / Makefile rules e.g. backslashes before symbols `\!` and double dollar signs `\$$`.

# Debugging with GDB

To connect to the target device and enable debug tools such as GDB, the `blackberry-connect` tool must be started with the right arguments. For this, two terminals must have the correct `bbndk-env` environment loaded (or run the `make connect` command in the background).

## Terminal 1: `blackberry-connect`
* Start in the Term48 root directory.
* `cd signing`
* If the SSH key hasn't been generated yet, run `make ssh-key`.
* `make connect`
* Leave terminal running until done debugging.

## Terminal 2: `gdb`
* Start in the Term48 root directory.
* `make launch-debug`
* The package will be built, deployed to target device, and launched stopped. On host, `ntoarm-gdb` will start, connect to target device, and attach to the application process. To continue execution, run the GDB command `continue`. Further information on GDB can be found online.


text:
import rospy
import roslib
import sys
import math
import cv2
from sensor_msgs.msg import Image
from tip2d_detection_msgs.msg import Tip, Tips
from tip2d_detection import image_to_array, TipDetector, world_coordinates

import numpy as np

STATE={"image":None,"tip_publisher":None,"last_image_header":None}

def handle_images():
    tip_msg = Tip()

    # Set "header" for tip msg
    tip_msg.header = STATE["last_image_header"]

    # TODO: process STATE["image"] and get actual tip location
    # Detect tips in the image
    detect_tip = TipDetector
    image = STATE["image"]
    tips = detect_tip(image)
    #tips = (320,240)

    # print coordinates
    #rospy.logerr('Coordinates of tip: %s',
    #        tips)

    if tips[0] == 0 and tips[1] == 0:
        #rospy.logerr('Saving troublesome image')
        cv2.imwrite('/home/ros/workspace/src/robotic_surgery/tip2d_detection/image.png',image)
        #np.save('home/ros/workspace/src/robotic_surgery/tip2d_detection/image.png', image)
    else:
        # Convert to robot's world coordinates
        convert_world = world_coordinates
        tips2d = convert_world(tips[0],tips[1])

        # Set positions to real values
        tip_msg.x = tips2d[0] #np.random.random()
        tip_msg.z = tips2d[1] #np.random.random()

        # Publish the tip message to the other nodes which are interested
        STATE["tip_publisher"].publish(tip_msg)

def got_image(image_message):
    STATE["last_image_header"]=image_message.header
    STATE["image"]=image_to_array(image_message)
    if STATE["image"] is not None:
        handle_images()

def main():
    # Register the node with ROS
    rospy.init_node('localise_tip', anonymous=True)

    # Subscribe to the image
    rospy.Subscriber("image", Image, got_image)

    # Create a publisher for tip locations
    STATE["tip_publisher"] = rospy.Publisher(rospy.get_name() + '/tip', Tip, queue_size=1)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__=='__main__':
    main()


text:
module Sequel
  class Dataset
    # ---------------------
    # :section: 1 - Methods that return modified datasets
    # These methods all return modified copies of the receiver.
    # ---------------------

    # Hash of extension name symbols to callable objects to load the extension
    # into the Dataset object (usually by extending it with a module defined
    # in the extension).
    EXTENSIONS = {}

    # The dataset options that require the removal of cached columns
    # if changed.
    COLUMN_CHANGE_OPTS = [:select, :sql, :from, :join].freeze

    # Which options don't affect the SQL generation.  Used by simple_select_all?
    # to determine if this is a simple SELECT * FROM table.
    NON_SQL_OPTIONS = [:server, :defaults, :overrides, :graph, :eager_graph, :graph_aliases]

    # These symbols have _join methods created (e.g. inner_join) that
    # call join_table with the symbol, passing along the arguments and
    # block from the method call.
    CONDITIONED_JOIN_TYPES = [:inner, :full_outer, :right_outer, :left_outer, :full, :right, :left]

    # These symbols have _join methods created (e.g. natural_join) that
    # call join_table with the symbol.  They only accept a single table
    # argument which is passed to join_table, and they raise an error
    # if called with a block.
    UNCONDITIONED_JOIN_TYPES = [:natural, :natural_left, :natural_right, :natural_full, :cross]

    # All methods that return modified datasets with a joined table added.
    JOIN_METHODS = (CONDITIONED_JOIN_TYPES + UNCONDITIONED_JOIN_TYPES).map{|x| "#{x}_join".to_sym} + [:join, :join_table]

    # Methods that return modified datasets
    QUERY_METHODS = (<<-METHS).split.map{|x| x.to_sym} + JOIN_METHODS
      add_graph_aliases and distinct except exclude exclude_having exclude_where
      filter for_update from from_self graph grep group group_and_count group_by having intersect invert
      limit lock_style naked offset or order order_append order_by order_more order_prepend qualify
      reverse reverse_order select select_all select_append select_group select_more server
      set_graph_aliases unfiltered ungraphed ungrouped union
      unlimited unordered where with with_recursive with_sql
    METHS

    # Register an extension callback for Dataset objects.  ext should be the
    # extension name symbol, and mod should either be a Module that the
    # dataset is extended with, or a callable object called with the database
    # object.  If mod is not provided, a block can be provided and is treated
    # as the mod object.
    #
    # If mod is a module, this also registers a Database extension that will
    # extend all of the database's datasets.
    def self.register_extension(ext, mod=nil, &block)
      if mod
        raise(Error, "cannot provide both mod and block to Dataset.register_extension") if block
        if mod.is_a?(Module)
          block = proc{|ds| ds.extend(mod)}
          Sequel::Database.register_extension(ext){|db| db.extend_datasets(mod)}
        else
          block = mod
        end
      end
      Sequel.synchronize{EXTENSIONS[ext] = block}
    end

    # Alias for where.
    def and(*cond, &block)
      where(*cond, &block)
    end

    # Returns a new clone of the dataset with with the given options merged.
    # If the options changed include options in COLUMN_CHANGE_OPTS, the cached
    # columns are deleted.  This method should generally not be called
    # directly by user code.
    def clone(opts = nil)
      c = super()
      if opts
        c.instance_variable_set(:@opts, @opts.merge(opts))
        c.instance_variable_set(:@columns, nil) if @columns && !opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
      else
        c.instance_variable_set(:@opts, @opts.dup)
      end
      c
    end

    # Returns a copy of the dataset with the SQL DISTINCT clause.
    # The DISTINCT clause is used to remove duplicate rows from the
    # output.  If arguments are provided, uses a DISTINCT ON clause,
    # in which case it will only be distinct on those columns, instead
    # of all returned columns.  Raises an error if arguments
    # are given and DISTINCT ON is not supported.
    #
    #  DB[:items].distinct # SQL: SELECT DISTINCT * FROM items
    #  DB[:items].order(:id).distinct(:id) # SQL: SELECT DISTINCT ON (id) * FROM items ORDER BY id
    def distinct(*args)
      raise(InvalidOperation, "DISTINCT ON not supported") if !args.empty? && !supports_distinct_on?
      clone(:distinct => args)
    end

    # Adds an EXCEPT clause using a second dataset object.
    # An EXCEPT compound dataset returns all rows in the current dataset
    # that are not in the given dataset.
    # Raises an +InvalidOperation+ if the operation is not supported.
    # Options:
    # :alias :: Use the given value as the from_self alias
    # :all :: Set to true to use EXCEPT ALL instead of EXCEPT, so duplicate rows can occur
    # :from_self :: Set to false to not wrap the returned dataset in a from_self, use with care.
    #
    #   DB[:items].except(DB[:other_items])
    #   # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS t1
    #
    #   DB[:items].except(DB[:other_items], :all=>true, :from_self=>false)
    #   # SELECT * FROM items EXCEPT ALL SELECT * FROM other_items
    #
    #   DB[:items].except(DB[:other_items], :alias=>:i)
    #   # SELECT * FROM (SELECT * FROM items EXCEPT SELECT * FROM other_items) AS i
    def except(dataset, opts=OPTS)
      raise(InvalidOperation, "EXCEPT not supported") unless supports_intersect_except?
      raise(InvalidOperation, "EXCEPT ALL not supported") if opts[:all] && !supports_intersect_except_all?
      compound_clone(:except, dataset, opts)
    end

    # Performs the inverse of Dataset#where.  Note that if you have multiple filter
    # conditions, this is not the same as a negation of all conditions.
    #
    #   DB[:items].exclude(:category => 'software')
    #   # SELECT * FROM items WHERE (category != 'software')
    #
    #   DB[:items].exclude(:category => 'software', :id=>3)
    #   # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
    def exclude(*cond, &block)
      _filter_or_exclude(true, :where, *cond, &block)
    end

    # Inverts the given conditions and adds them to the HAVING clause.
    #
    #   DB[:items].select_group(:name).exclude_having{count(name) < 2}
    #   # SELECT name FROM items GROUP BY name HAVING (count(name) >= 2)
    def exclude_having(*cond, &block)
      _filter_or_exclude(true, :having, *cond, &block)
    end

    # Alias for exclude.
    def exclude_where(*cond, &block)
      exclude(*cond, &block)
    end

    # Return a clone of the dataset loaded with the extensions, see #extension!.
    def extension(*exts)
      clone.extension!(*exts)
    end

    # Alias for where.
    def filter(*cond, &block)
      where(*cond, &block)
    end

    # Returns a cloned dataset with a :update lock style.
    #
    #   DB[:table].for_update # SELECT * FROM table FOR UPDATE
    def for_update
      lock_style(:update)
    end

    # Returns a copy of the dataset with the source changed. If no
    # source is given, removes all tables.  If multiple sources
    # are given, it is the same as using a CROSS JOIN (cartesian product) between all tables.
    # If a block is given, it is treated as a virtual row block, similar to +where+.
    #
    #   DB[:items].from # SQL: SELECT *
    #   DB[:items].from(:blah) # SQL: SELECT * FROM blah
    #   DB[:items].from(:blah, :foo) # SQL: SELECT * FROM blah, foo
    #   DB[:items].from{fun(arg)} # SQL: SELECT * FROM fun(arg)
    def from(*source, &block)
      virtual_row_columns(source, block)
      table_alias_num = 0
      ctes = nil
      source.map! do |s|
        case s
        when Dataset
          if hoist_cte?(s)
            ctes ||= []
            ctes += s.opts[:with]
            s = s.clone(:with=>nil)
          end
          SQL::AliasedExpression.new(s, dataset_alias(table_alias_num+=1))
        when Symbol
          sch, table, aliaz = split_symbol(s)
          if aliaz
            s = sch ? SQL::QualifiedIdentifier.new(sch, table) : SQL::Identifier.new(table)
            SQL::AliasedExpression.new(s, aliaz.to_sym)
          else
            s
          end
        else
          s
        end
      end
      o = {:from=>source.empty? ? nil : source}
      o[:with] = (opts[:with] || []) + ctes if ctes
      o[:num_dataset_sources] = table_alias_num if table_alias_num > 0
      clone(o)
    end

    # Returns a dataset selecting from the current dataset.
    # Supplying the :alias option controls the alias of the result.
    #
    #   ds = DB[:items].order(:name).select(:id, :name)
    #   # SELECT id,name FROM items ORDER BY name
    #
    #   ds.from_self
    #   # SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS t1
    #
    #   ds.from_self(:alias=>:foo)
    #   # SELECT * FROM (SELECT id, name FROM items ORDER BY name) AS foo
    def from_self(opts=OPTS)
      fs = {}
      @opts.keys.each{|k| fs[k] = nil unless NON_SQL_OPTIONS.include?(k)}
      clone(fs).from(opts[:alias] ? as(opts[:alias]) : self)
    end

    # Match any of the columns to any of the patterns. The terms can be
    # strings (which use LIKE) or regular expressions (which are only
    # supported on MySQL and PostgreSQL).  Note that the total number of
    # pattern matches will be Array(columns).length * Array(terms).length,
    # which could cause performance issues.
    #
    # Options (all are boolean):
    #
    # :all_columns :: All columns must be matched to any of the given patterns.
    # :all_patterns :: All patterns must match at least one of the columns.
    # :case_insensitive :: Use a case insensitive pattern match (the default is
    #                      case sensitive if the database supports it).
    #
    # If both :all_columns and :all_patterns are true, all columns must match all patterns.
    #
    # Examples:
    #
    #   dataset.grep(:a, '%test%')
    #   # SELECT * FROM items WHERE (a LIKE '%test%')
    #
    #   dataset.grep([:a, :b], %w'%test% foo')
    #   # SELECT * FROM items WHERE ((a LIKE '%test%') OR (a LIKE 'foo') OR (b LIKE '%test%') OR (b LIKE 'foo'))
    #
    #   dataset.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true)
    #   # SELECT * FROM a WHERE (((a LIKE '%foo%') OR (b LIKE '%foo%')) AND ((a LIKE '%bar%') OR (b LIKE '%bar%')))
    #
    #   dataset.grep([:a, :b], %w'%foo% %bar%', :all_columns=>true)
    #   # SELECT * FROM a WHERE (((a LIKE '%foo%') OR (a LIKE '%bar%')) AND ((b LIKE '%foo%') OR (b LIKE '%bar%')))
    #
    #   dataset.grep([:a, :b], %w'%foo% %bar%', :all_patterns=>true, :all_columns=>true)
    #   # SELECT * FROM a WHERE ((a LIKE '%foo%') AND (b LIKE '%foo%') AND (a LIKE '%bar%') AND (b LIKE '%bar%'))
    def grep(columns, patterns, opts=OPTS)
      if opts[:all_patterns]
        conds = Array(patterns).map do |pat|
          SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *Array(columns).map{|c| SQL::StringExpression.like(c, pat, opts)})
        end
        where(SQL::BooleanExpression.new(opts[:all_patterns] ? :AND : :OR, *conds))
      else
        conds = Array(columns).map do |c|
          SQL::BooleanExpression.new(:OR, *Array(patterns).map{|pat| SQL::StringExpression.like(c, pat, opts)})
        end
        where(SQL::BooleanExpression.new(opts[:all_columns] ? :AND : :OR, *conds))
      end
    end

    # Returns a copy of the dataset with the results grouped by the value of
    # the given columns.  If a block is given, it is treated
    # as a virtual row block, similar to +where+.
    #
    #   DB[:items].group(:id) # SELECT * FROM items GROUP BY id
    #   DB[:items].group(:id, :name) # SELECT * FROM items GROUP BY id, name
    #   DB[:items].group{[a, sum(b)]} # SELECT * FROM items GROUP BY a, sum(b)
    def group(*columns, &block)
      virtual_row_columns(columns, block)
      clone(:group => (columns.compact.empty? ? nil : columns))
    end

    # Alias of group
    def group_by(*columns, &block)
      group(*columns, &block)
    end

    # Returns a dataset grouped by the given column with count by group.
    # Column aliases may be supplied, and will be included in the select clause.
    # If a block is given, it is treated as a virtual row block, similar to +where+.
    #
    # Examples:
    #
    #   DB[:items].group_and_count(:name).all
    #   # SELECT name, count(*) AS count FROM items GROUP BY name
    #   # => [{:name=>'a', :count=>1}, ...]
    #
    #   DB[:items].group_and_count(:first_name, :last_name).all
    #   # SELECT first_name, last_name, count(*) AS count FROM items GROUP BY first_name, last_name
    #   # => [{:first_name=>'a', :last_name=>'b', :count=>1}, ...]
    #
    #   DB[:items].group_and_count(:first_name___name).all
    #   # SELECT first_name AS name, count(*) AS count FROM items GROUP BY first_name
    #   # => [{:name=>'a', :count=>1}, ...]
    #
    #   DB[:items].group_and_count{substr(first_name, 1, 1).as(initial)}.all
    #   # SELECT substr(first_name, 1, 1) AS initial, count(*) AS count FROM items GROUP BY substr(first_name, 1, 1)
    #   # => [{:initial=>'a', :count=>1}, ...]
    def group_and_count(*columns, &block)
      select_group(*columns, &block).select_more(COUNT_OF_ALL_AS_COUNT)
    end

    # Adds the appropriate CUBE syntax to GROUP BY.
    def group_cube
      raise Error, "GROUP BY CUBE not supported on #{db.database_type}" unless supports_group_cube?
      clone(:group_options=>:cube)
    end

    # Adds the appropriate ROLLUP syntax to GROUP BY.
    def group_rollup
      raise Error, "GROUP BY ROLLUP not supported on #{db.database_type}" unless supports_group_rollup?
      clone(:group_options=>:rollup)
    end

    # Returns a copy of the dataset with the HAVING conditions changed. See #where for argument types.
    #
    #   DB[:items].group(:sum).having(:sum=>10)
    #   # SELECT * FROM items GROUP BY sum HAVING (sum = 10)
    def having(*cond, &block)
      _filter(:having, *cond, &block)
    end

    # Adds an INTERSECT clause using a second dataset object.
    # An INTERSECT compound dataset returns all rows in both the current dataset
    # and the given dataset.
    # Raises an +InvalidOperation+ if the operation is not supported.
    # Options:
    # :alias :: Use the given value as the from_self alias
    # :all :: Set to true to use INTERSECT ALL instead of INTERSECT, so duplicate rows can occur
    # :from_self :: Set to false to not wrap the returned dataset in a from_self, use with care.
    #
    #   DB[:items].intersect(DB[:other_items])
    #   # SELECT * FROM (SELECT * FROM items INTERSECT SELECT * FROM other_items) AS t1
    #
    #   DB[:items].intersect(DB[:other_items], :all=>true, :from_self=>false)
    #   # SELECT * FROM items INTERSECT ALL SELECT * FROM other_items
    #
    #   DB[:items].intersect(DB[:other_items], :alias=>:i)
    #   # SELECT * FROM (SELECT * FROM items INTERSECT SELECT * FROM other_items) AS i
    def intersect(dataset, opts=OPTS)
      raise(InvalidOperation, "INTERSECT not supported") unless supports_intersect_except?
      raise(InvalidOperation, "INTERSECT ALL not supported") if opts[:all] && !supports_intersect_except_all?
      compound_clone(:intersect, dataset, opts)
    end

    # Inverts the current WHERE and HAVING clauses.  If there is neither a
    # WHERE or HAVING clause, adds a WHERE clause that is always false.
    #
    #   DB[:items].where(:category => 'software').invert
    #   # SELECT * FROM items WHERE (category != 'software')
    #
    #   DB[:items].where(:category => 'software', :id=>3).invert
    #   # SELECT * FROM items WHERE ((category != 'software') OR (id != 3))
    def invert
      having, where = @opts.values_at(:having, :where)
      if having.nil? && where.nil?
        where(false)
      else
        o = {}
        o[:having] = SQL::BooleanExpression.invert(having) if having
        o[:where] = SQL::BooleanExpression.invert(where) if where
        clone(o)
      end
    end

    # Alias of +inner_join+
    def join(*args, &block)
      inner_join(*args, &block)
    end

    # Returns a joined dataset.  Not usually called directly, users should use the
    # appropriate join method (e.g. join, left_join, natural_join, cross_join) which fills
    # in the +type+ argument.
    #
    # Takes the following arguments:
    #
    # * type - The type of join to do (e.g. :inner)
    # * table - Depends on type:
    #   * Dataset - a subselect is performed with an alias of tN for some value of N
    #   * String, Symbol: table
    # * expr - specifies conditions, depends on type:
    #   * Hash, Array of two element arrays - Assumes key (1st arg) is column of joined table (unless already
    #     qualified), and value (2nd arg) is column of the last joined or primary table (or the
    #     :implicit_qualifier option).
    #     To specify multiple conditions on a single joined table column, you must use an array.
    #     Uses a JOIN with an ON clause.
    #   * Array - If all members of the array are symbols, considers them as columns and
    #     uses a JOIN with a USING clause.  Most databases will remove duplicate columns from
    #     the result set if this is used.
    #   * nil - If a block is not given, doesn't use ON or USING, so the JOIN should be a NATURAL
    #     or CROSS join. If a block is given, uses an ON clause based on the block, see below.
    #   * Everything else - pretty much the same as a using the argument in a call to where,
    #     so strings are considered literal, symbols specify boolean columns, and Sequel
    #     expressions can be used. Uses a JOIN with an ON clause.
    # * options - a hash of options, with any of the following keys:
    #   * :table_alias - the name of the table's alias when joining, necessary for joining
    #     to the same table more than once.  No alias is used by default.
    #   * :implicit_qualifier - The name to use for qualifying implicit conditions.  By default,
    #     the last joined or primary table is used.
    #   * :qualify - Can be set to false to not do any implicit qualification.  Can be set
    #     to :deep to use the Qualifier AST Transformer, which will attempt to qualify
    #     subexpressions of the expression tree.  Can be set to :symbol to only qualify
    #     symbols. Defaults to the value of default_join_table_qualification.
    # * block - The block argument should only be given if a JOIN with an ON clause is used,
    #   in which case it yields the table alias/name for the table currently being joined,
    #   the table alias/name for the last joined (or first table), and an array of previous
    #   SQL::JoinClause. Unlike +where+, this block is not treated as a virtual row block.
    #
    # Examples:
    #
    #   DB[:a].join_table(:cross, :b)
    #   # SELECT * FROM a CROSS JOIN b
    #
    #   DB[:a].join_table(:inner, DB[:b], :c=>d)
    #   # SELECT * FROM a INNER JOIN (SELECT * FROM b) AS t1 ON (t1.c = a.d)
    #
    #   DB[:a].join_table(:left, :b___c, [:d])
    #   # SELECT * FROM a LEFT JOIN b AS c USING (d)
    #
    #   DB[:a].natural_join(:b).join_table(:inner, :c) do |ta, jta, js|
    #     (Sequel.qualify(ta, :d) > Sequel.qualify(jta, :e)) & {Sequel.qualify(ta, :f)=>DB.from(js.first.table).select(:g)}
    #   end
    #   # SELECT * FROM a NATURAL JOIN b INNER JOIN c
    #   #   ON ((c.d > b.e) AND (c.f IN (SELECT g FROM b)))
    def join_table(type, table, expr=nil, options=OPTS, &block)
      if hoist_cte?(table)
        s, ds = hoist_cte(table)
        return s.join_table(type, ds, expr, options, &block)
      end

      using_join = expr.is_a?(Array) && !expr.empty? && expr.all?{|x| x.is_a?(Symbol)}
      if using_join && !supports_join_using?
        h = {}
        expr.each{|e| h[e] = e}
        return join_table(type, table, h, options)
      end

      table_alias = options[:table_alias]
      last_alias = options[:implicit_qualifier]
      qualify_type = options[:qualify]

      if table.is_a?(Dataset)
        if table_alias.nil?
          table_alias_num = (@opts[:num_dataset_sources] || 0) + 1
          table_alias = dataset_alias(table_alias_num)
        end
        table_name = table_alias
      else
        table, implicit_table_alias = split_alias(table)
        table_alias ||= implicit_table_alias
        table_name = table_alias || table
      end

      join = if expr.nil? and !block
        SQL::JoinClause.new(type, table, table_alias)
      elsif using_join
        raise(Sequel::Error, "can't use a block if providing an array of symbols as expr") if block
        SQL::JoinUsingClause.new(expr, type, table, table_alias)
      else
        last_alias ||= @opts[:last_joined_table] || first_source_alias
        if Sequel.condition_specifier?(expr)
          expr = expr.collect do |k, v|
            qualify_type = default_join_table_qualification if qualify_type.nil?
            case qualify_type
            when false
              nil # Do no qualification
            when :deep
              k = Sequel::Qualifier.new(self, table_name).transform(k)
              v = Sequel::Qualifier.new(self, last_alias).transform(v)
            else
              k = qualified_column_name(k, table_name) if k.is_a?(Symbol)
              v = qualified_column_name(v, last_alias) if v.is_a?(Symbol)
            end
            [k,v]
          end
          expr = SQL::BooleanExpression.from_value_pairs(expr)
        end
        if block
          expr2 = yield(table_name, last_alias, @opts[:join] || [])
          expr = expr ? SQL::BooleanExpression.new(:AND, expr, expr2) : expr2
        end
        SQL::JoinOnClause.new(expr, type, table, table_alias)
      end

      opts = {:join => (@opts[:join] || []) + [join], :last_joined_table => table_name}
      opts[:num_dataset_sources] = table_alias_num if table_alias_num
      clone(opts)
    end

    CONDITIONED_JOIN_TYPES.each do |jtype|
      class_eval("def #{jtype}_join(*args, &block); join_table(:#{jtype}, *args, &block) end", __FILE__, __LINE__)
    end
    UNCONDITIONED_JOIN_TYPES.each do |jtype|
      class_eval("def #{jtype}_join(table); raise(Sequel::Error, '#{jtype}_join does not accept join table blocks') if block_given?; join_table(:#{jtype}, table) end", __FILE__, __LINE__)
    end

    # Marks this dataset as a lateral dataset.  If used in another dataset's FROM
    # or JOIN clauses, it will surround the subquery with LATERAL to enable it
    # to deal with previous tables in the query:
    #
    #   DB.from(:a, DB[:b].where(:a__c=>:b__d).lateral)
    #   # SELECT * FROM a, LATERAL (SELECT * FROM b WHERE (a.c = b.d))
    def lateral
      clone(:lateral=>true)
    end

    # If given an integer, the dataset will contain only the first l results.
    # If given a range, it will contain only those at offsets within that
    # range. If a second argument is given, it is used as an offset. To use
    # an offset without a limit, pass nil as the first argument.
    #
    #   DB[:items].limit(10) # SELECT * FROM items LIMIT 10
    #   DB[:items].limit(10, 20) # SELECT * FROM items LIMIT 10 OFFSET 20
    #   DB[:items].limit(10...20) # SELECT * FROM items LIMIT 10 OFFSET 10
    #   DB[:items].limit(10..20) # SELECT * FROM items LIMIT 11 OFFSET 10
    #   DB[:items].limit(nil, 20) # SELECT * FROM items OFFSET 20
    def limit(l, o = (no_offset = true; nil))
      return from_self.limit(l, o) if @opts[:sql]

      if l.is_a?(Range)
        no_offset = false
        o = l.first
        l = l.last - l.first + (l.exclude_end? ? 0 : 1)
      end
      l = l.to_i if l.is_a?(String) && !l.is_a?(LiteralString)
      if l.is_a?(Integer)
        raise(Error, 'Limits must be greater than or equal to 1') unless l >= 1
      end

      ds = clone(:limit=>l)
      ds = ds.offset(o) unless no_offset
      ds
    end

    # Returns a cloned dataset with the given lock style.  If style is a
    # string, it will be used directly. You should never pass a string
    # to this method that is derived from user input, as that can lead to
    # SQL injection.
    #
    # A symbol may be used for database independent locking behavior, but
    # all supported symbols have separate methods (e.g. for_update).
    #
    #   DB[:items].lock_style('FOR SHARE NOWAIT') # SELECT * FROM items FOR SHARE NOWAIT
    def lock_style(style)
      clone(:lock => style)
    end

    # Returns a cloned dataset without a row_proc.
    #
    #   ds = DB[:items]
    #   ds.row_proc = proc{|r| r.invert}
    #   ds.all # => [{2=>:id}]
    #   ds.naked.all # => [{:id=>2}]
    def naked
      ds = clone
      ds.row_proc = nil
      ds
    end

    # Returns a copy of the dataset with a specified order. Can be safely combined with limit.
    # If you call limit with an offset, it will override override the offset if you've called
    # offset first.
    #
    #   DB[:items].offset(10) # SELECT * FROM items OFFSET 10
    def offset(o)
      o = o.to_i if o.is_a?(String) && !o.is_a?(LiteralString)
      if o.is_a?(Integer)
        raise(Error, 'Offsets must be greater than or equal to 0') unless o >= 0
      end
      clone(:offset => o)
    end

    # Adds an alternate filter to an existing filter using OR. If no filter
    # exists an +Error+ is raised.
    #
    #   DB[:items].where(:a).or(:b) # SELECT * FROM items WHERE a OR b
    def or(*cond, &block)
      cond = cond.first if cond.size == 1
      v = @opts[:where]
      if v.nil? || (cond.respond_to?(:empty?) && cond.empty? && !block)
        clone
      else
        clone(:where => SQL::BooleanExpression.new(:OR, v, filter_expr(cond, &block)))
      end
    end

    # Returns a copy of the dataset with the order changed. If the dataset has an
    # existing order, it is ignored and overwritten with this order. If a nil is given
    # the returned dataset has no order. This can accept multiple arguments
    # of varying kinds, such as SQL functions.  If a block is given, it is treated
    # as a virtual row block, similar to +where+.
    #
    #   DB[:items].order(:name) # SELECT * FROM items ORDER BY name
    #   DB[:items].order(:a, :b) # SELECT * FROM items ORDER BY a, b
    #   DB[:items].order(Sequel.lit('a + b')) # SELECT * FROM items ORDER BY a + b
    #   DB[:items].order(:a + :b) # SELECT * FROM items ORDER BY (a + b)
    #   DB[:items].order(Sequel.desc(:name)) # SELECT * FROM items ORDER BY name DESC
    #   DB[:items].order(Sequel.asc(:name, :nulls=>:last)) # SELECT * FROM items ORDER BY name ASC NULLS LAST
    #   DB[:items].order{sum(name).desc} # SELECT * FROM items ORDER BY sum(name) DESC
    #   DB[:items].order(nil) # SELECT * FROM items
    def order(*columns, &block)
      virtual_row_columns(columns, block)
      clone(:order => (columns.compact.empty?) ? nil : columns)
    end

    # Alias of order_more, for naming consistency with order_prepend.
    def order_append(*columns, &block)
      order_more(*columns, &block)
    end

    # Alias of order
    def order_by(*columns, &block)
      order(*columns, &block)
    end

    # Returns a copy of the dataset with the order columns added
    # to the end of the existing order.
    #
    #   DB[:items].order(:a).order(:b) # SELECT * FROM items ORDER BY b
    #   DB[:items].order(:a).order_more(:b) # SELECT * FROM items ORDER BY a, b
    def order_more(*columns, &block)
      columns = @opts[:order] + columns if @opts[:order]
      order(*columns, &block)
    end

    # Returns a copy of the dataset with the order columns added
    # to the beginning of the existing order.
    #
    #   DB[:items].order(:a).order(:b) # SELECT * FROM items ORDER BY b
    #   DB[:items].order(:a).order_prepend(:b) # SELECT * FROM items ORDER BY b, a
    def order_prepend(*columns, &block)
      ds = order(*columns, &block)
      @opts[:order] ? ds.order_more(*@opts[:order]) : ds
    end

    # Qualify to the given table, or first source if no table is given.
    #
    #   DB[:items].where(:id=>1).qualify
    #   # SELECT items.* FROM items WHERE (items.id = 1)
    #
    #   DB[:items].where(:id=>1).qualify(:i)
    #   # SELECT i.* FROM items WHERE (i.id = 1)
    def qualify(table=first_source)
      o = @opts
      return clone if o[:sql]
      h = {}
      (o.keys & QUALIFY_KEYS).each do |k|
        h[k] = qualified_expression(o[k], table)
      end
      h[:select] = [SQL::ColumnAll.new(table)] if !o[:select] || o[:select].empty?
      clone(h)
    end

    # Modify the RETURNING clause, only supported on a few databases.  If returning
    # is used, instead of insert returning the autogenerated primary key or
    # update/delete returning the number of modified rows, results are
    # returned using +fetch_rows+.
    #
    #   DB[:items].returning # RETURNING *
    #   DB[:items].returning(nil) # RETURNING NULL
    #   DB[:items].returning(:id, :name) # RETURNING id, name
    def returning(*values)
      clone(:returning=>values)
    end

    # Returns a copy of the dataset with the order reversed. If no order is
    # given, the existing order is inverted.
    #
    #   DB[:items].reverse(:id) # SELECT * FROM items ORDER BY id DESC
    #   DB[:items].reverse{foo(bar)} # SELECT * FROM items ORDER BY foo(bar) DESC
    #   DB[:items].order(:id).reverse # SELECT * FROM items ORDER BY id DESC
    #   DB[:items].order(:id).reverse(Sequel.desc(:name)) # SELECT * FROM items ORDER BY name ASC
    def reverse(*order, &block)
      virtual_row_columns(order, block)
      order(*invert_order(order.empty? ? @opts[:order] : order))
    end

    # Alias of +reverse+
    def reverse_order(*order, &block)
      reverse(*order, &block)
    end

    # Returns a copy of the dataset with the columns selected changed
    # to the given columns. This also takes a virtual row block,
    # similar to +where+.
    #
    #   DB[:items].select(:a) # SELECT a FROM items
    #   DB[:items].select(:a, :b) # SELECT a, b FROM items
    #   DB[:items].select{[a, sum(b)]} # SELECT a, sum(b) FROM items
    def select(*columns, &block)
      virtual_row_columns(columns, block)
      clone(:select => columns)
    end

    # Returns a copy of the dataset selecting the wildcard if no arguments
    # are given.  If arguments are given, treat them as tables and select
    # all columns (using the wildcard) from each table.
    #
    #   DB[:items].select(:a).select_all # SELECT * FROM items
    #   DB[:items].select_all(:items) # SELECT items.* FROM items
    #   DB[:items].select_all(:items, :foo) # SELECT items.*, foo.* FROM items
    def select_all(*tables)
      if tables.empty?
        clone(:select => nil)
      else
        select(*tables.map{|t| i, a = split_alias(t); a || i}.map{|t| SQL::ColumnAll.new(t)})
      end
    end

    # Returns a copy of the dataset with the given columns added
    # to the existing selected columns.  If no columns are currently selected,
    # it will select the columns given in addition to *.
    #
    #   DB[:items].select(:a).select(:b) # SELECT b FROM items
    #   DB[:items].select(:a).select_append(:b) # SELECT a, b FROM items
    #   DB[:items].select_append(:b) # SELECT *, b FROM items
    def select_append(*columns, &block)
      cur_sel = @opts[:select]
      if !cur_sel || cur_sel.empty?
        unless supports_select_all_and_column?
          return select_all(*(Array(@opts[:from]) + Array(@opts[:join]))).select_more(*columns, &block)
        end
        cur_sel = [WILDCARD]
      end
      select(*(cur_sel + columns), &block)
    end

    # Set both the select and group clauses with the given +columns+.
    # Column aliases may be supplied, and will be included in the select clause.
    # This also takes a virtual row block similar to +where+.
    #
    #   DB[:items].select_group(:a, :b)
    #   # SELECT a, b FROM items GROUP BY a, b
    #
    #   DB[:items].select_group(:c___a){f(c2)}
    #   # SELECT c AS a, f(c2) FROM items GROUP BY c, f(c2)
    def select_group(*columns, &block)
      virtual_row_columns(columns, block)
      select(*columns).group(*columns.map{|c| unaliased_identifier(c)})
    end

    # Alias for select_append.
    def select_more(*columns, &block)
      select_append(*columns, &block)
    end

    # Set the server for this dataset to use.  Used to pick a specific database
    # shard to run a query against, or to override the default (where SELECT uses
    # :read_only database and all other queries use the :default database).  This
    # method is always available but is only useful when database sharding is being
    # used.
    #
    #   DB[:items].all # Uses the :read_only or :default server
    #   DB[:items].delete # Uses the :default server
    #   DB[:items].server(:blah).delete # Uses the :blah server
    def server(servr)
      clone(:server=>servr)
    end

    # Unbind bound variables from this dataset's filter and return an array of two
    # objects.  The first object is a modified dataset where the filter has been
    # replaced with one that uses bound variable placeholders.  The second object
    # is the hash of unbound variables.  You can then prepare and execute (or just
    # call) the dataset with the bound variables to get results.
    #
    #   ds, bv = DB[:items].where(:a=>1).unbind
    #   ds # SELECT * FROM items WHERE (a = $a)
    #   bv #  {:a => 1}
    #   ds.call(:select, bv)
    def unbind
      u = Unbinder.new
      ds = clone(:where=>u.transform(opts[:where]), :join=>u.transform(opts[:join]))
      [ds, u.binds]
    end

    # Returns a copy of the dataset with no filters (HAVING or WHERE clause) applied.
    #
    #   DB[:items].group(:a).having(:a=>1).where(:b).unfiltered
    #   # SELECT * FROM items GROUP BY a
    def unfiltered
      clone(:where => nil, :having => nil)
    end

    # Returns a copy of the dataset with no grouping (GROUP or HAVING clause) applied.
    #
    #   DB[:items].group(:a).having(:a=>1).where(:b).ungrouped
    #   # SELECT * FROM items WHERE b
    def ungrouped
      clone(:group => nil, :having => nil)
    end

    # Adds a UNION clause using a second dataset object.
    # A UNION compound dataset returns all rows in either the current dataset
    # or the given dataset.
    # Options:
    # :alias :: Use the given value as the from_self alias
    # :all :: Set to true to use UNION ALL instead of UNION, so duplicate rows can occur
    # :from_self :: Set to false to not wrap the returned dataset in a from_self, use with care.
    #
    #   DB[:items].union(DB[:other_items])
    #   # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS t1
    #
    #   DB[:items].union(DB[:other_items], :all=>true, :from_self=>false)
    #   # SELECT * FROM items UNION ALL SELECT * FROM other_items
    #
    #   DB[:items].union(DB[:other_items], :alias=>:i)
    #   # SELECT * FROM (SELECT * FROM items UNION SELECT * FROM other_items) AS i
    def union(dataset, opts=OPTS)
      compound_clone(:union, dataset, opts)
    end

    # Returns a copy of the dataset with no limit or offset.
    #
    #   DB[:items].limit(10, 20).unlimited # SELECT * FROM items
    def unlimited
      clone(:limit=>nil, :offset=>nil)
    end

    # Returns a copy of the dataset with no order.
    #
    #   DB[:items].order(:a).unordered # SELECT * FROM items
    def unordered
      order(nil)
    end

    # Returns a copy of the dataset with the given WHERE conditions imposed upon it.
    #
    # Accepts the following argument types:
    #
    # * Hash - list of equality/inclusion expressions
    # * Array - depends:
    #   * If first member is a string, assumes the rest of the arguments
    #     are parameters and interpolates them into the string.
    #   * If all members are arrays of length two, treats the same way
    #     as a hash, except it allows for duplicate keys to be
    #     specified.
    #   * Otherwise, treats each argument as a separate condition.
    # * String - taken literally
    # * Symbol - taken as a boolean column argument (e.g. WHERE active)
    # * Sequel::SQL::BooleanExpression - an existing condition expression,
    #   probably created using the Sequel expression filter DSL.
    #
    # where also accepts a block, which should return one of the above argument
    # types, and is treated the same way.  This block yields a virtual row object,
    # which is easy to use to create identifiers and functions.  For more details
    # on the virtual row support, see the {"Virtual Rows" guide}[rdoc-ref:doc/virtual_rows.rdoc]
    #
    # If both a block and regular argument are provided, they get ANDed together.
    #
    # Examples:
    #
    #   DB[:items].where(:id => 3)
    #   # SELECT * FROM items WHERE (id = 3)
    #
    #   DB[:items].where('price < ?', 100)
    #   # SELECT * FROM items WHERE price < 100
    #
    #   DB[:items].where([[:id, [1,2,3]], [:id, 0..10]])
    #   # SELECT * FROM items WHERE ((id IN (1, 2, 3)) AND ((id >= 0) AND (id <= 10)))
    #
    #   DB[:items].where('price < 100')
    #   # SELECT * FROM items WHERE price < 100
    #
    #   DB[:items].where(:active)
    #   # SELECT * FROM items WHERE :active
    #
    #   DB[:items].where{price < 100}
    #   # SELECT * FROM items WHERE (price < 100)
    #
    # Multiple where calls can be chained for scoping:
    #
    #   software = dataset.where(:category => 'software').where{price < 100}
    #   # SELECT * FROM items WHERE ((category = 'software') AND (price < 100))
    #
    # See the {"Dataset Filtering" guide}[rdoc-ref:doc/dataset_filtering.rdoc] for more examples and details.
    def where(*cond, &block)
      _filter(:where, *cond, &block)
    end

    # Add a common table expression (CTE) with the given name and a dataset that defines the CTE.
    # A common table expression acts as an inline view for the query.
    # Options:
    # :args :: Specify the arguments/columns for the CTE, should be an array of symbols.
    # :recursive :: Specify that this is a recursive CTE
    #
    #   DB[:items].with(:items, DB[:syx].where(:name.like('A%')))
    #   # WITH items AS (SELECT * FROM syx WHERE (name LIKE 'A%')) SELECT * FROM items
    def with(name, dataset, opts=OPTS)
      raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
      if hoist_cte?(dataset)
        s, ds = hoist_cte(dataset)
        s.with(name, ds, opts)
      else
        clone(:with=>(@opts[:with]||[]) + [opts.merge(:name=>name, :dataset=>dataset)])
      end
    end

    # Add a recursive common table expression (CTE) with the given name, a dataset that
    # defines the nonrecursive part of the CTE, and a dataset that defines the recursive part
    # of the CTE.  Options:
    # :args :: Specify the arguments/columns for the CTE, should be an array of symbols.
    # :union_all :: Set to false to use UNION instead of UNION ALL combining the nonrecursive and recursive parts.
    #
    #   DB[:t].with_recursive(:t,
    #     DB[:i1].select(:id, :parent_id).where(:parent_id=>nil),
    #     DB[:i1].join(:t, :id=>:parent_id).select(:i1__id, :i1__parent_id),
    #     :args=>[:id, :parent_id])
    #
    #   # WITH RECURSIVE "t"("id", "parent_id") AS (
    #   #   SELECT "id", "parent_id" FROM "i1" WHERE ("parent_id" IS NULL)
    #   #   UNION ALL
    #   #   SELECT "i1"."id", "i1"."parent_id" FROM "i1" INNER JOIN "t" ON ("t"."id" = "i1"."parent_id")
    #   # ) SELECT * FROM "t"
    def with_recursive(name, nonrecursive, recursive, opts=OPTS)
      raise(Error, 'This datatset does not support common table expressions') unless supports_cte?
      if hoist_cte?(nonrecursive)
        s, ds = hoist_cte(nonrecursive)
        s.with_recursive(name, ds, recursive, opts)
      elsif hoist_cte?(recursive)
        s, ds = hoist_cte(recursive)
        s.with_recursive(name, nonrecursive, ds, opts)
      else
        clone(:with=>(@opts[:with]||[]) + [opts.merge(:recursive=>true, :name=>name, :dataset=>nonrecursive.union(recursive, {:all=>opts[:union_all] != false, :from_self=>false}))])
      end
    end

    # Returns a copy of the dataset with the static SQL used.  This is useful if you want
    # to keep the same row_proc/graph, but change the SQL used to custom SQL.
    #
    #   DB[:items].with_sql('SELECT * FROM foo') # SELECT * FROM foo
    #
    # You can use placeholders in your SQL and provide arguments for those placeholders:
    #
    #   DB[:items].with_sql('SELECT ? FROM foo', 1) # SELECT 1 FROM foo
    #
    # You can also provide a method name and arguments to call to get the SQL:
    #
    #   DB[:items].with_sql(:insert_sql, :b=>1) # INSERT INTO items (b) VALUES (1)
    def with_sql(sql, *args)
      if sql.is_a?(Symbol)
        sql = send(sql, *args)
      else
        sql = SQL::PlaceholderLiteralString.new(sql, args) unless args.empty?
      end
      clone(:sql=>sql)
    end

    protected

    # Add the dataset to the list of compounds
    def compound_clone(type, dataset, opts)
      if hoist_cte?(dataset)
        s, ds = hoist_cte(dataset)
        return s.compound_clone(type, ds, opts)
      end
      ds = compound_from_self.clone(:compounds=>Array(@opts[:compounds]).map{|x| x.dup} + [[type, dataset.compound_from_self, opts[:all]]])
      opts[:from_self] == false ? ds : ds.from_self(opts)
    end

    # Return true if the dataset has a non-nil value for any key in opts.
    def options_overlap(opts)
      !(@opts.collect{|k,v| k unless v.nil?}.compact & opts).empty?
    end

    # Whether this dataset is a simple select from an underlying table, such as:
    #
    #   SELECT * FROM table
    #   SELECT table.* FROM table
    def simple_select_all?
      o = @opts.reject{|k,v| v.nil? || NON_SQL_OPTIONS.include?(k)}
      if (f = o[:from]) && f.length == 1 && (f.first.is_a?(Symbol) || f.first.is_a?(SQL::AliasedExpression))
        case o.length
        when 1
          true
        when 2
          (s = o[:select]) && s.length == 1 && s.first.is_a?(SQL::ColumnAll)
        else
          false
        end
      else
        false
      end
    end

    private

    # Internal filtering method so it works on either the WHERE or HAVING clauses, with or
    # without inversion.
    def _filter_or_exclude(invert, clause, *cond, &block)
      cond = cond.first if cond.size == 1
      if cond.respond_to?(:empty?) && cond.empty? && !block
        clone
      else
        cond = filter_expr(cond, &block)
        cond = SQL::BooleanExpression.invert(cond) if invert
        cond = SQL::BooleanExpression.new(:AND, @opts[clause], cond) if @opts[clause]
        clone(clause => cond)
      end
    end

    # Internal filter method so it works on either the having or where clauses.
    def _filter(clause, *cond, &block)
      _filter_or_exclude(false, clause, *cond, &block)
    end

    # The default :qualify option to use for join tables if one is not specified.
    def default_join_table_qualification
      :symbol
    end

    # SQL expression object based on the expr type.  See +where+.
    def filter_expr(expr = nil, &block)
      expr = nil if expr == []
      if expr && block
        return SQL::BooleanExpression.new(:AND, filter_expr(expr), filter_expr(block))
      elsif block
        expr = block
      end
      case expr
      when Hash
        SQL::BooleanExpression.from_value_pairs(expr)
      when Array
        if (sexpr = expr.at(0)).is_a?(String)
          SQL::PlaceholderLiteralString.new(sexpr, expr[1..-1], true)
        elsif Sequel.condition_specifier?(expr)
          SQL::BooleanExpression.from_value_pairs(expr)
        else
          SQL::BooleanExpression.new(:AND, *expr.map{|x| filter_expr(x)})
        end
      when Proc
        filter_expr(Sequel.virtual_row(&expr))
      when SQL::NumericExpression, SQL::StringExpression
        raise(Error, "Invalid SQL Expression type: #{expr.inspect}")
      when Symbol, SQL::Expression
        expr
      when TrueClass, FalseClass
        if supports_where_true?
          SQL::BooleanExpression.new(:NOOP, expr)
        elsif expr
          SQL::Constants::SQLTRUE
        else
          SQL::Constants::SQLFALSE
        end
      when String
        LiteralString.new("(#{expr})")
      else
        raise(Error, "Invalid filter argument: #{expr.inspect}")
      end
    end

    # Return two datasets, the first a clone of the receiver with the WITH
    # clause from the given dataset added to it, and the second a clone of
    # the given dataset with the WITH clause removed.
    def hoist_cte(ds)
      [clone(:with => (opts[:with] || []) + ds.opts[:with]), ds.clone(:with => nil)]
    end

    # Whether CTEs need to be hoisted from the given ds into the current ds.
    def hoist_cte?(ds)
      ds.is_a?(Dataset) && ds.opts[:with] && !supports_cte_in_subqueries?
    end

    # Inverts the given order by breaking it into a list of column references
    # and inverting them.
    #
    #   DB[:items].invert_order([Sequel.desc(:id)]]) #=> [Sequel.asc(:id)]
    #   DB[:items].invert_order([:category, Sequel.desc(:price)]) #=> [Sequel.desc(:category), Sequel.asc(:price)]
    def invert_order(order)
      return nil unless order
      order.map do |f|
        case f
        when SQL::OrderedExpression
          f.invert
        else
          SQL::OrderedExpression.new(f)
        end
      end
    end

    # Return self if the dataset already has a server, or a cloned dataset with the
    # default server otherwise.
    def default_server
      @opts[:server] ? self : clone(:server=>:default)
    end

    # Treat the +block+ as a virtual_row block if not +nil+ and
    # add the resulting columns to the +columns+ array (modifies +columns+).
    def virtual_row_columns(columns, block)
      if block
        v = Sequel.virtual_row(&block)
        if v.is_a?(Array)
          columns.concat(v)
        else
          columns << v
        end
      end
    end
  end
end


text:
package au.net.bunney.bamboo.plugins.envwallboard.admin;

import com.atlassian.bamboo.ww2.BambooActionSupport;

/**
 * @author Gavin Bunney
 */
public class ManageEnvironmentsAction extends BambooActionSupport {

    public ManageEnvironmentsAction() {
        //
    }
}


text:
class S3Signer
  attr_reader :expiry

  def initialize
    @expiry = 30.minutes.from_now
  end

  def sign(options = {})
    type = options[:type]
    directory = options[:directory]

    {
      acl: "public-read",
      awsAccessKeyId: ENV["aws_access_key_id"],
      bucket: AwsSettings.bucket,
      "Cache-Control" => "max-age=630720000, public",
      "Content-Type" => type,
      expires: expiry,
      key: "#{directory}/#{RandomFilename.new(type).generate}",
      policy: encoded_policy,
      signature: signature,
      success_action_status: "201"
    }
  end

  private

  def encoded_policy
    Base64.strict_encode64(policy.to_json)
  end

  def policy
    {
      expiration: expiry,
      conditions: [
        { bucket: AwsSettings.bucket },
        { acl: "public-read" },
        { expires: expiry },
        { success_action_status: "201" },
        ["starts-with", "$key", ""],
        ["starts-with", "$Content-Type", ""],
        ["starts-with", "$Cache-Control", ""],
        ["content-length-range", 0, 524288000]
      ]
    }
  end

  def signature
    Base64.strict_encode64(
      OpenSSL::HMAC.digest(
        OpenSSL::Digest::Digest.new("sha1"),
        ENV["aws_secret_access_key"],
        encoded_policy
      )
    )
  end
end


text:
layout: post
tags:
- TMG
- Networking
title: moving your TMG SQL server Logs DB and other TMG tips
date: 2012-11-22  8:27:55
---
In house, I have been using [Microsoft TMG 2010 Server][1] for a while now. I use it as a firewall for some of the machines on the network, and also as a proxy for most, if not all, machines. When acting as a Firewall, all traffic flows though the machine, be it HTTP/HTTPS, SMTP/POP3/IMAP, or anything for that matter. You can also lock down ports on the box, which is a feature of most firewalls, but i like TMG due to its relitive ease of use...

Anyway, one problem with routing all traffic from different machines though TMG is after a while, the logging starts getting big. Single TMG by default is set to use [SQL Server][2], it can start using lots of memory, hard drive space, etc. So, there are a couple of articles which should make moving your TMG's SQL DB to a different machine easier...

* [Configuring Forefront TMG Logs][3]
* [Configuring (TMG) logging to a remote server][4]
* [How to configure Forefront TMG logging into a central Microsoft SQL Server database][5]

Some other tips you may find useful

* If you have Malware Inspection turned on, but you know there are certain sites that wont serve Malware (for example, Ubutnu Archives or YouTube.com) you can add these to the "Destination Exceptions" list. Under "Web Access Policy", click "Malware Inspection" and click "Destination Exceptions". Double click on the "Sites Exempt from Malware Inspection" and add your URL. I put *.ubuntu.com and *.youtube.com in here (Microsoft Updates are already on the list). Now, when downloading files from these locations, they do not run though inspection and save CPU cycles. **WANRING** You need to trust these sites!
* There is a nice little app to add into TMG called [Bandwidth Splitter][6] which allows you to not only monitor what traffic is going though your network, but also put limits on different machine sets, users, etc. There is a [Free editon][7] which works with only 10 clients, but does what i need it to do to start with.

[1]:http://www.microsoft.com/tmg
[2]:http://www.microsoft.com/sql
[3]:http://technet.microsoft.com/en-us/library/bb794937.aspx
[4]:http://technet.microsoft.com/en-us/library/dd441079.aspx
[5]:http://www.isaserver.org/tutorials/How-configure-Forefront-TMG-logging-into-central-Microsoft-SQL-Server-database.html
[6]:http://www.bsplitter.com/
[7]:http://www.bsplitter.com/download.aspx#trial_restrictions


text:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using System.Xml;

namespace Shannan.StrawMan.Utils
{
    internal static class EmojiUtils
    {
        private static Dictionary<string, BitmapImage> _emojiCodes = new Dictionary<string, BitmapImage>();

        static EmojiUtils()
        {
            Init();
        }

        public static Dictionary<string, BitmapImage> EmojiCodes
        {
            get
            {
                return _emojiCodes;
            }
        }

        private static void Init()
        {
            XmlDocument xmlDoc = new XmlDocument();
            StreamResourceInfo info = Application.GetResourceStream(new Uri("/Resources/Emojis.xml", UriKind.Relative));
            xmlDoc.Load(info.Stream);
            XmlNode root = xmlDoc.SelectSingleNode("array");
            XmlNodeList nodeList = root.ChildNodes;
            //循环列表,获得相应的内容
            foreach (XmlNode xn in nodeList)
            {
                XmlElement xe = xn as XmlElement;
                XmlNodeList subList = xe.ChildNodes;
                foreach (XmlNode xmlNode in subList)
                {
                    if (xmlNode.Name == "array")
                    {
                        XmlElement lastXe = xmlNode as XmlElement;
                        foreach (XmlNode lastNode in lastXe)
                        {
                            if (lastNode.Name == "a")
                            {
                                string key = "[" + lastNode.InnerText + "]";
                                string val = lastNode.Attributes[1].Value.ToString();

                                BitmapImage bitmap = new BitmapImage();
                                bitmap.BeginInit();
                                bitmap.UriSource = new Uri("pack://application:,,,/Images/Emojis/" + val + ".png");
                                bitmap.EndInit();
                                _emojiCodes.Add(key, bitmap);
                            }
                        }
                    }
                }
            }
        }
    }
}


text:
require File.dirname(__FILE__) + '/../../spec_helper'
require File.dirname(__FILE__) + '/fixtures/classes'

describe "Enumerable#reject" do
  it "returns an array of the elements for which block is false" do
    EnumerableSpecs::Numerous.new.reject { |i| i > 3 }.should == [2, 3, 1]
    entries = (1..10).to_a
    numerous = EnumerableSpecs::Numerous.new(*entries)
    numerous.reject {|i| i % 2 == 0 }.should == [1,3,5,7,9]
    numerous.reject {|i| true }.should == []
    numerous.reject {|i| false }.should == entries
  end

  ruby_version_is "" ... "1.8.7" do
    it "raises a LocalJumpError if no block is given" do
      lambda { EnumerableSpecs::Numerous.new.reject }.should raise_error(LocalJumpError)
    end
  end

  ruby_version_is "1.8.7" do
    it "returns an Enumerator if called without a block" do
      EnumerableSpecs::Numerous.new.reject.should be_kind_of(Enumerable::Enumerator)
    end
  end
end


text:
package com.ibaguo.nlp.dictionary.py;

import static com.ibaguo.nlp.utility.Predefine.logger;

import java.util.*;

import com.ibaguo.nlp.MyNLP;
import com.ibaguo.nlp.collection.set.UnEmptyStringSet;
import com.ibaguo.nlp.corpus.dictionary.StringDictionary;
import com.ibaguo.nlp.corpus.io.IOUtil;

public class SYTDictionary
{
    static Set<String> smSet = new UnEmptyStringSet();
    static Set<String> ymSet = new UnEmptyStringSet();
    static Set<String> ydSet = new UnEmptyStringSet();
    static Map<String, String[]> map = new TreeMap<String, String[]>();

    static
    {
        StringDictionary dictionary = new StringDictionary();
        if (dictionary.load(MyNLP.Config.SYTDictionaryPath))
        {
            logger.info("载入声母韵母音调词典" + MyNLP.Config.SYTDictionaryPath + "成功");
            for (Map.Entry<String, String> entry : dictionary.entrySet())
            {
                //      0  1 2
                // bai1=b,ai,1
                String[] args = entry.getValue().split(",");
                if (args[0].length() == 0) args[0] = "none";
                smSet.add(args[0]);
                ymSet.add(args[1]);
                ydSet.add(args[2]);
                String[] valueArray = new String[4];
                System.arraycopy(args, 0, valueArray, 0, args.length);
                valueArray[3] = PinyinUtil.convertToneNumber2ToneMark(entry.getKey());
                map.put(entry.getKey(), valueArray);
            }
        }
        else
        {
            logger.warning("载入声母韵母音调词典" + MyNLP.Config.SYTDictionaryPath + "失败");
        }
    }

    public static void dumpEnum(String path)
    {
        dumpEnum(smSet, path + "sm.txt");
        dumpEnum(ymSet, path + "ym.txt");
        dumpEnum(ydSet, path + "yd.txt");
        Set<String> hdSet = new TreeSet<String>();
        for (Pinyin pinyin : PinyinDictionary.pinyins)
        {
            hdSet.add(pinyin.getHeadString());
        }
        dumpEnum(hdSet, path + "head.txt");
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String[]> entry : map.entrySet())
        {
            // 0声母 1韵母 2音调 3带音标
            String[] value = entry.getValue();
            Pinyin pinyin = Pinyin.valueOf(entry.getKey());
            sb.append(entry.getKey() + "(" + Shengmu.class.getSimpleName() + "." + value[0] + ", " + Yunmu.class.getSimpleName() + "." + value[1] + ", " + value[2] + ", \"" + value[3] + "\", \"" + entry.getKey().substring(0, entry.getKey().length() - 1)  + "\"" + ", " + Head.class.getSimpleName() + "." + pinyin.getHeadString() + ", '" + pinyin.getFirstChar() + "'" + "),\n");
        }
        IOUtil.saveTxt(path + "py.txt", sb.toString());
    }

    private static boolean dumpEnum(Set<String> set, String path)
    {
        StringBuilder sb = new StringBuilder();
        for (String s : set)
        {
            sb.append(s);
            sb.append(",\n");
        }
        return IOUtil.saveTxt(path, sb.toString());
    }
}


text:
package com.dotosoft.dotoquiz.tools;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import com.dotosoft.dot4command.chain.Command;
import com.dotosoft.dotoquiz.tools.config.DotoQuizContext;
import com.dotosoft.dotoquiz.tools.util.CatalogLoader;

public class App {

	public App(String args[])
	{
		try {
			DotoQuizContext ctx = new DotoQuizContext();
			if( ctx.getSettings().loadSettings(args) ) {
				Command command = CatalogLoader.getInstance().getCatalog().getCommand(ctx.getSettings().getApplicationType());
				if(command != null) {
					command.execute(ctx);
					ctx = null;
					System.exit(0);
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		showError();
	}

	public void showError()
	{
		System.err.println("Error: Could not run SyncQuizParser.");
		System.err.println("Run: java -jar SyncQuizParser.jar "+ Arrays.toString(listCommands()) + " [file config]");
	}

	public Object[] listCommands()
	{
		try {
			Iterator<String> keyCommand = CatalogLoader.getInstance().getCatalog().getNames();
			List<String> commands = new ArrayList<String>();
			while(keyCommand.hasNext()) {
				String command = keyCommand.next();
				if(command.indexOf("do") == 0) continue;
				commands.add(command);
			}
			return commands.toArray();
		} catch (Exception ex) {
			ex.printStackTrace();
			showError();
		}

		return new String[] {};
	}

	public static void main(String args[])
	{
		new App(args);
	}
}