library; import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; import 'src/generated/ql2.pb.dart' as p; import 'dart:collection'; import 'dart:convert'; import 'package:hashlib/hashlib.dart' as hashlib; import 'package:crypto/crypto.dart'; import 'dart:math' as math; part 'src/ast.dart'; part 'src/errors.dart'; part 'src/net.dart'; part 'src/cursor.dart'; class AddFunction { final RqlQuery? _rqlQuery; AddFunction([this._rqlQuery]); Add call(obj) { if (_rqlQuery != null) { return Add([_rqlQuery, obj]); } else if (obj is Args) { return Add([obj]); } else { throw RqlDriverError("Called add with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Add(positionalArguments); } } /// computes logical 'and' of two or more values class AndFunction { final RqlQuery? _rqlQuery; AndFunction([this._rqlQuery]); And call(obj) { if (_rqlQuery != null) { return And([_rqlQuery, obj]); } else { throw RqlDriverError("Called and with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return And(positionalArguments); } } /// If the test expression returns false or null, the [falseBranch] will be executed. /// In the other cases, the [trueBranch] is the one that will be evaluated. class BranchFunction { Branch call(test, [trueBranch, falseBranch]) { return Branch(test, trueBranch, falseBranch); } @override dynamic noSuchMethod(Invocation invocation) { return Branch.fromArgs(Args(invocation.positionalArguments)); } } class DivFunction { final RqlQuery? _rqlQuery; DivFunction([this._rqlQuery]); Div call(number) { if (_rqlQuery != null) { return Div([_rqlQuery, number]); } else if (number is Args) { return Div([number]); } else { throw RqlDriverError("Called div with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Div(positionalArguments); } } class EqFunction { final RqlQuery? _rqlQuery; EqFunction([this._rqlQuery]); Eq call(value) { if (_rqlQuery != null) { return Eq([_rqlQuery, value]); } else if (value is Args) { return Eq([value]); } else { throw RqlDriverError("Called eq with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Eq(positionalArguments); } } class GeFunction { final RqlQuery? _rqlQuery; GeFunction([this._rqlQuery]); Ge call(number) { if (_rqlQuery != null) { return Ge([_rqlQuery, number]); } else if (number is Args) { return Ge([number]); } else { throw RqlDriverError("Called ge with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Ge(positionalArguments); } } class GtFunction { final RqlQuery? _rqlQuery; GtFunction([this._rqlQuery]); Gt call(number) { if (_rqlQuery != null) { return Gt([_rqlQuery, number]); } else if (number is Args) { return Gt([number]); } else { throw RqlDriverError("Called gt with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Gt(positionalArguments); } } class LeFunction { final RqlQuery? _rqlQuery; LeFunction([this._rqlQuery]); Le call(number) { if (_rqlQuery != null) { return Le([_rqlQuery, number]); } else if (number is Args) { return Le([number]); } else { throw RqlDriverError("Called le with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Le(positionalArguments); } } /// Construct a geometric line class LineFunction { Line call(point1, point2) { return Line([point1, point2]); } @override dynamic noSuchMethod(Invocation invocation) { return Line(invocation.positionalArguments); } } class LtFunction { final RqlQuery? _rqlQuery; LtFunction([this._rqlQuery]); Lt call(number) { if (_rqlQuery != null) { return Lt([_rqlQuery, number]); } else if (number is Args) { return Lt([number]); } else { throw RqlDriverError("Called lt with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Lt(positionalArguments); } } /// Executes the mappingFunction for each item in a sequence or array /// and returns the transformed array. multiple sequences and arrays /// may be passed class MapFunction { RqlMap call(seq, mappingFunction) { return RqlMap([seq], mappingFunction); } @override dynamic noSuchMethod(Invocation invocation) { List args = List.from(invocation.positionalArguments); return RqlMap(args.sublist(0, args.length - 1), args.last); } } class MulFunction { final RqlQuery? _rqlQuery; MulFunction([this._rqlQuery]); Mul call(number) { if (_rqlQuery != null) { return Mul([_rqlQuery, number]); } else if (number is Args) { return Mul([number]); } else { throw RqlDriverError("Called mul with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Mul(positionalArguments); } } class NeFunction { final RqlQuery? _rqlQuery; NeFunction([this._rqlQuery]); Ne call(value) { if (_rqlQuery != null) { return Ne([_rqlQuery, value]); } else if (value is Args) { return Ne([value]); } else { throw RqlDriverError("Called ne with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Ne(positionalArguments); } } /// Adds fields to an object class ObjectFunction { final RethinkDb _rethinkdb; ObjectFunction(this._rethinkdb); RqlObject call(args) { return RqlObject(args); } @override dynamic noSuchMethod(Invocation invocation) { return _rethinkdb.object(invocation.positionalArguments); } } /// computes logical 'or' of two or more values class OrFunction { final RqlQuery? _rqlQuery; OrFunction([this._rqlQuery]); Or call(number) { if (_rqlQuery != null) { return Or([_rqlQuery, number]); } else { throw RqlDriverError("Called or with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Or(positionalArguments); } } /// Construct a geometric polygon class PolygonFunction { Polygon call(point1, point2, point3) { return Polygon([point1, point2, point3]); } @override dynamic noSuchMethod(Invocation invocation) { return Polygon(invocation.positionalArguments); } } /// Evaluate the expr in the context of one or more value bindings. /// The type of the result is the type of the value returned from expr. class RqlDoFunction { final RethinkDb _rethinkdb; RqlDoFunction(this._rethinkdb); FunCall call(arg, [expr]) { return FunCall(arg, expr); } @override dynamic noSuchMethod(Invocation invocation) { List args = List.from(invocation.positionalArguments); return _rethinkdb.rqlDo(args.sublist(0, args.length - 1), args.last); } } class SubFunction { final RqlQuery? _rqlQuery; SubFunction([this._rqlQuery]); Sub call(number) { if (_rqlQuery != null) { return Sub([_rqlQuery, number]); } else if (number is Args) { return Sub([number]); } else { throw RqlDriverError("Called sub with too few values"); } } @override dynamic noSuchMethod(Invocation invocation) { List positionalArguments = []; if (_rqlQuery != null) { positionalArguments.add(_rqlQuery); } positionalArguments.addAll(invocation.positionalArguments); return Sub(positionalArguments); } } class RethinkDb { // Connection Management /// Create a new connection to the database server. Accepts the following options: /// host: the host to connect to (default localhost). /// port: the port to connect on (default 28015). /// db: the default database (defaults to test). /// user: the user name for the db (defaults to admin). /// password: password for the user (default ""). Future connect({ String db = 'test', String host = "localhost", int port = 28015, String user = "admin", String password = "", Map? ssl, }) => Connection(db, host, port, user, password, ssl).reconnect(); /// Reference a database.This command can be chained with other commands to do further processing on the data. DB db(String dbName) => DB(dbName); /// Create a database. A RethinkDB database is a collection of tables, similar to relational databases. /// If successful, the operation returns an object: {created: 1}. If a database with the same name already exists the operation throws RqlRuntimeError. /// Note: that you can only use alphanumeric characters and underscores for the database name. DbCreate dbCreate(String dbName) => DbCreate(dbName); /// Drop a database. The database, all its tables, and corresponding data will be deleted. /// If successful, the operation returns the object {dropped: 1}. /// If the specified database doesn't exist a RqlRuntimeError is thrown. DbDrop dbDrop(String dbName) => DbDrop(dbName, {}); /// List all database names in the system. The result is a list of strings. DbList dbList() => DbList(); /// Returns a rang bewteen the start and end values. If no start or /// end are specified, an 'infinite' stream will be returned. Range range([start, end]) { if (start == null) { return Range.asStream(); } else if (end == null) { return Range(start); } else { return Range.withStart(start, end); } } /// Select all documents in a table. This command can be chained with other commands to do further processing on the data. Table table(String tableName, [Map? options]) => Table(tableName, options); /// Create a table. A RethinkDB table is a collection of JSON documents. /// If successful, the operation returns an object: {created: 1}. If a table with the same name already exists, the operation throws RqlRuntimeError. /// Note: that you can only use alphanumeric characters and underscores for the table name. TableCreate tableCreate(String tableName, [Map? options]) => TableCreate(tableName, options); /// List all table names in a database. The result is a list of strings. TableList tableList() => TableList(); /// Drop a table. The table and all its data will be deleted. TableDrop tableDrop(String tableName, [Map? options]) => TableDrop(tableName, options); /// Specify ascending order on an attribute Asc asc(String attr) => Asc(attr); /// Specify descending order on an attribute Desc desc(String attr) => Desc(attr); /// Create a time object for a specific time. Time time(int year, int month, int day, {String timezone = 'Z', int? hour, int? minute, num? second}) { if (second != null) { return Time(Args([year, month, day, hour, minute, second, timezone])); } else { return Time(Args([year, month, day, timezone])); } } /// Create a time object from a Dart DateTime object. /// Time nativeTime(DateTime val) => expr(val); /// Create a time object based on an iso8601 date-time string (e.g. '2013-01-01T01:01:01+00:00'). /// We support all valid ISO 8601 formats except for week dates. /// If you pass an ISO 8601 date-time without a time zone, you must specify the time zone with the optarg default_timezone. /// // ignore: non_constant_identifier_names RqlISO8601 ISO8601(String stringTime, [defaultTimeZone = "Z"]) => RqlISO8601(stringTime, defaultTimeZone); /// Create a time object based on seconds since epoch. /// The first argument is a double and will be rounded to three decimal places (millisecond-precision). EpochTime epochTime(int eptime) => EpochTime(eptime); /// Return a time object representing the current time in UTC. /// The command now() is computed once when the server receives the query, so multiple instances of r.now() will always return the same time inside a query. Now now() => Now(); /// Evaluate the expr in the context of one or more value bindings. /// The type of the result is the type of the value returned from expr. dynamic get rqlDo => RqlDoFunction(this); /// If the test expression returns false or null, the [falseBranch] will be executed. /// In the other cases, the [trueBranch] is the one that will be evaluated. dynamic get branch => BranchFunction(); /// Throw a runtime error. If called with no arguments inside the second argument to default, re-throw the current error. UserError error(String message) => UserError(message, {}); /// Create a javascript expression. JavaScript js(String js, [Map? options]) => JavaScript(js, options); /// Parse a JSON string on the server. Json json(String json) => Json(json, {}); /// Count the total size of the group. Map count = {"COUNT": true}; /// Compute the sum of the given field in the group. Map sum(String attr) => {'SUM': attr}; /// Compute the average value of the given attribute for the group. Map avg(String attr) => {"AVG": attr}; /// Returns the currently visited document. ImplicitVar row = ImplicitVar(); /// Adds fields to an object dynamic get object => ObjectFunction(this); /// Acts like the ruby splat operator; unpacks a list of arguments. Args args(args) => Args(args); /// Returns data from a specified http url Http http(url, [optargs]) => Http(url, optargs); /// Generates a random number between two bounds Random random([left, right, options]) { if (right != null) { return Random.rightBound(left, right, options); } else if (left != null) { return Random.leftBound(left, options); } else { return Random(options); } } /// Returns logical inverse of the arguments given Not not([value]) => Not(value ?? true); /// Executes the mappingFunction for each item in a sequence or array /// and returns the transformed array. multiple sequences and arrays /// may be passed dynamic get map => MapFunction(); /// computes logical 'and' of two or more values dynamic get and => AndFunction(); /// computes logical 'or' of two or more values dynamic get or => OrFunction(); /// Replace an object in a field instead of merging it with an existing object in a [merge] or [update] operation. Literal literal(args) => Literal(args); /// Convert native dart object into a RqlObject expr(val) => RqlQuery()._expr(val); /// Convert a GeoJSON object to a ReQL geometry object. GeoJson geojson(Map geoJson) => GeoJson(geoJson); /// Construct a circular line or polygon. Circle circle(point, num radius, [Map? options]) => Circle(point, radius, options); /// Compute the distance between a point and a geometry object Distance distance(geo1, geo2, [Map? options]) => Distance(geo1, geo2, options); /// Construct a geometric line dynamic get line => LineFunction(); /// Construct a geometric point Point point(num long, num lat) => Point(long, lat); /// Construct a geometric polygon dynamic get polygon => PolygonFunction(); dynamic get eq => EqFunction(); dynamic get ne => NeFunction(); dynamic get lt => LtFunction(); dynamic get le => LeFunction(); dynamic get gt => GtFunction(); dynamic get ge => GeFunction(); dynamic get add => AddFunction(); dynamic get sub => SubFunction(); dynamic get mul => MulFunction(); dynamic get div => DivFunction(); /// Encapsulate binary data within a query. Binary binary(var data) => Binary(data); RqlTimeName monday = RqlTimeName(p.Term_TermType.MONDAY); RqlTimeName tuesday = RqlTimeName(p.Term_TermType.TUESDAY); RqlTimeName wednesday = RqlTimeName(p.Term_TermType.WEDNESDAY); RqlTimeName thursday = RqlTimeName(p.Term_TermType.THURSDAY); RqlTimeName friday = RqlTimeName(p.Term_TermType.FRIDAY); RqlTimeName saturday = RqlTimeName(p.Term_TermType.SATURDAY); RqlTimeName sunday = RqlTimeName(p.Term_TermType.SUNDAY); RqlTimeName january = RqlTimeName(p.Term_TermType.JANUARY); RqlTimeName february = RqlTimeName(p.Term_TermType.FEBRUARY); RqlTimeName march = RqlTimeName(p.Term_TermType.MARCH); RqlTimeName april = RqlTimeName(p.Term_TermType.APRIL); RqlTimeName may = RqlTimeName(p.Term_TermType.MAY); RqlTimeName june = RqlTimeName(p.Term_TermType.JUNE); RqlTimeName july = RqlTimeName(p.Term_TermType.JULY); RqlTimeName august = RqlTimeName(p.Term_TermType.AUGUST); RqlTimeName september = RqlTimeName(p.Term_TermType.SEPTEMBER); RqlTimeName october = RqlTimeName(p.Term_TermType.OCTOBER); RqlTimeName november = RqlTimeName(p.Term_TermType.NOVEMBER); RqlTimeName december = RqlTimeName(p.Term_TermType.DECEMBER); RqlConstant minval = RqlConstant(p.Term_TermType.MINVAL); RqlConstant maxval = RqlConstant(p.Term_TermType.MAXVAL); Uuid uuid([str]) => Uuid(str); }