答案 0 :(得分:10)
由于问题是关于Java或Groovy的解决方案,有人可以在这里寻找Java解决方案(就像我一样)
下面你可以看到验证的简单函数,如果提供的日期是在同一天:
public class IsSameDay extends Function {
@Override
protected void xFunc() throws SQLException {
if (args() != 2) {
throw new SQLException("IsSameDay(date1,date2): Invalid argument count. Requires 2, but found " + args());
}
try {
DateTime t1 = DateTime.parse(value_text(0).replace(" ", "T"));
DateTime t2 = DateTime.parse(value_text(1).replace(" ", "T"));
if (t1.getYear() == t2.getYear() && t1.getDayOfYear() == t2.getDayOfYear()) {
result(1);
} else {
result(0);
}
} catch (Exception exception) {
throw new SQLDataException("IsSameDay(date1,date2): One of Arguments is invalid: " + exception.getLocalizedMessage());
}
}
}
如果有人需要进行聚合功能,那么可能会发现这个例子很有用:
public class MyMax extends Function.Aggregate {
private long buff = 0;
public MyMax() {
}
@Override
protected void xStep() throws SQLException {
long current = value_long(0);
if (current > buff) {
buff = current;
}
}
@Override
protected void xFinal() throws SQLException {
result(buff);
}
}
累加器有效,因为在每个查询中都克隆了MyMax实例,因此在实例化对象时可以提供起始值。
最后一个示例显示了如何附加函数:
Function.create(c, IsSameDay.class.getSimpleName(), new IsSameDay());
Function.create(c, MyMax.class.getSimpleName(), new MyMax());
希望有人能发现它有用。
答案 1 :(得分:8)
事实证明,使用SQLiteJDBC编写用户定义的函数实际上非常简单。这是一个Groovy示例:
@GrabConfig(systemClassLoader=true)
@Grab('org.xerial:sqlite-jdbc:3.6.16')
import org.sqlite.*
import java.sql.*
db = groovy.sql.Sql.newInstance("jdbc:sqlite::memory:","org.sqlite.JDBC")
// a distance function using the spherical law of cosines
Function.create(db.getConnection(), "distance", new Function() {
protected void xFunc() throws SQLException {
def lat1 = value_double(0)
def lon1 = value_double(1)
def lat2 = value_double(2)
def lon2 = value_double(3)
double theta = lon1 - lon2;
double dist = (Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))) +
(Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta)))
dist = Math.acos(dist)
dist = rad2deg(dist)
dist = dist * 60 * 1.1515
dist = dist * 1.609344
result(dist);
}
def deg2rad(deg) {
deg * Math.PI / 180.0
}
def rad2deg(rad) {
rad * 180.0 / Math.PI
}
})
db.execute("CREATE TABLE city(name, lat, lon)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('New York City', 40.7143, -74.0060)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('San Francisco', 37.7749, -122.4194)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('Paris', 48.8567, 2.3510)")
db.execute("INSERT INTO city(name, lat, lon) VALUES('Cologne', 50.9407, 6.9599)")
db.eachRow("SELECT a.name as a, b.name as b, distance(a.lat, a.lon, b.lat, b.lon) as d FROM city a, city b WHERE a.name != b.name ORDER BY d;") {
println "Distance from ${it.a} to ${it.b}: ${it.d}km"
}
答案 2 :(得分:0)
我认为,这是创建自定义函数的简单方法,
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell : UICollectionViewCell = collectionView.cellForItem(at: indexPath) as! CategoryCollectionViewCell
handleMultipleCellSelection(cell, indexPath: indexPath)
}
答案 3 :(得分:0)
创建接受参数并返回结果的函数的简单方法:
Function.create(conn, "addNS", new Function() {
@Override
protected void xFunc() {
System.out.println("myFunc called!");
String arg1;
try {
arg1 = value_text(0);
System.out.println("function arg1:"+arg1);
result("NS-"+arg1);
} catch (SQLException e) {
e.printStackTrace();
}
}
}, 1, Function.FLAG_DETERMINISTIC);
rs = conn.createStatement().executeQuery("select addNS('xyz');");
while(rs.next()) {
String val = rs.getString(1);
System.out.println("Function return val : " + val);
}