Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ MQ::Query.list.map { contains("important") }
.to_html # to_html() — HTML string
.to_string # to_string() — string coercion
.to_number # to_number() — numeric coercion
.to_boolean # to_boolean() — boolean coercion
.to_array # to_array()
.to_bytes # to_bytes()
.to_markdown_string # to_markdown_string()
Expand All @@ -267,18 +268,22 @@ MQ::Query.list.map { contains("important") }
.rtrim # rtrim()
.downcase # downcase()
.upcase # upcase()
.ascii_downcase # ascii_downcase()
.ascii_upcase # ascii_upcase()
.len # len()
.utf8bytelen # utf8bytelen()
.explode # explode() — string to codepoints
.implode # implode() — codepoints to string
.url_encode # url_encode()
.url_decode # url_decode()
.intern # intern()

.split(",") # split(",")
.gsub("pat", "r") # gsub("pat", "r") — regex replace all
.replace("a", "b") # replace("a", "b") — literal replace
.test("\\d+") # test("\\d+") — regex test → bool
.capture("(\\w+)") # capture("(\\w+)") — regex capture
.scan("(\\w+)") # scan("(\\w+)") — all regex matches
.slice(0, 5) # slice(0, 5)
.index("sub") # index("sub") — position of substring
.rindex("sub") # rindex("sub") — last position
Expand Down Expand Up @@ -309,6 +314,8 @@ MQ::Query.list.map { contains("important") }
.range(3) # range(3)
.del("key") # del("key")
.insert(0, "val") # insert(0, "val")
.shuffle # shuffle() — random order
.sample(3) # sample(3) — n random elements, no replacement
```

#### Math Operations
Expand Down Expand Up @@ -350,8 +357,17 @@ MQ::Query.list.map { contains("important") }
.sha512 # sha512()
.from_hex # from_hex()
.to_hex # to_hex()
.uuid # uuid() — random (v4) UUID
.uuid_v4 # uuid_v4() — alias of uuid
.uuid_v7 # uuid_v7() — time-ordered (v7) UUID
.rand # rand() — pseudo-random number in [0, 1)
.rand_int(1, 10) # rand_int(1, 10) — pseudo-random integer in [min, max]
```

`MQ::Query.uuid`, `.uuid_v4`, `.uuid_v7`, `.rand`, and `.rand_int(min, max)` are
also available as class-level generators to start a query without a preceding
selector, e.g. `MQ::Query.uuid.to_query # => "uuid()"`.

#### Path Operations

```ruby
Expand Down
33 changes: 33 additions & 0 deletions lib/mq/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def to_mdx = pipe_with("to_mdx()")
def to_html = pipe_with("to_html()")
def to_string = pipe_with("to_string()")
def to_number = pipe_with("to_number()")
def to_boolean = pipe_with("to_boolean()")
def to_array = pipe_with("to_array()")
def to_bytes = pipe_with("to_bytes()")
def to_markdown_string = pipe_with("to_markdown_string()")
Expand Down Expand Up @@ -135,14 +136,23 @@ def repeat(n)
pipe_with("repeat(#{n})")
end

def shuffle = pipe_with("shuffle()")

def sample(n)
pipe_with("sample(#{n})")
end

def trim = pipe_with("trim()")
def ltrim = pipe_with("ltrim()")
def rtrim = pipe_with("rtrim()")
def downcase = pipe_with("downcase()")
def upcase = pipe_with("upcase()")
def ascii_downcase = pipe_with("ascii_downcase()")
def ascii_upcase = pipe_with("ascii_upcase()")
def explode = pipe_with("explode()")
def implode = pipe_with("implode()")
def url_encode = pipe_with("url_encode()")
def url_decode = pipe_with("url_decode()")
def intern = pipe_with("intern()")

def gsub(pattern, replacement)
Expand All @@ -161,6 +171,10 @@ def capture(pattern)
pipe_with("capture(#{pattern.inspect})")
end

def scan(pattern)
pipe_with("scan(#{pattern.inspect})")
end

def abs = pipe_with("abs()")
def ceil = pipe_with("ceil()")
def floor = pipe_with("floor()")
Expand Down Expand Up @@ -205,6 +219,15 @@ def from_hex = pipe_with("from_hex()")
def to_hex = pipe_with("to_hex()")
def to_hex_str = pipe_with("to_hex()")

def uuid = pipe_with("uuid()")
def uuid_v4 = pipe_with("uuid_v4()")
def uuid_v7 = pipe_with("uuid_v7()")
def rand = pipe_with("rand()")

def rand_int(min, max)
pipe_with("rand_int(#{min}, #{max})")
end

def basename = pipe_with("basename()")
def dirname = pipe_with("dirname()")
def extname = pipe_with("extname()")
Expand Down Expand Up @@ -453,6 +476,16 @@ def select(filter = nil, &block)

def to_text = new("to_text()")
def to_markdown = new("to_markdown()")

# --- Value generators (usable as query starting points) ---
def uuid = new("uuid()")
def uuid_v4 = new("uuid_v4()")
def uuid_v7 = new("uuid_v7()")
def rand = new("rand()")

def rand_int(min, max)
new("rand_int(#{min}, #{max})")
end
end

private
Expand Down
42 changes: 42 additions & 0 deletions spec/mq_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
it "chains to_html" do expect(MQ::Query.text.to_html.to_query).to eq(".text | to_html()") end
it "chains to_string" do expect(MQ::Query.text.to_string.to_query).to eq(".text | to_string()") end
it "chains to_number" do expect(MQ::Query.text.to_number.to_query).to eq(".text | to_number()") end
it "chains to_boolean" do expect(MQ::Query.text.to_boolean.to_query).to eq(".text | to_boolean()") end
it "chains to_array" do expect(MQ::Query.text.to_array.to_query).to eq(".text | to_array()") end
it "chains to_markdown_string" do expect(MQ::Query.text.to_markdown_string.to_query).to eq(".text | to_markdown_string()") end
end
Expand All @@ -380,9 +381,12 @@
it "chains rtrim" do expect(MQ::Query.text.rtrim.to_query).to eq(".text | rtrim()") end
it "chains downcase" do expect(MQ::Query.text.downcase.to_query).to eq(".text | downcase()") end
it "chains upcase" do expect(MQ::Query.text.upcase.to_query).to eq(".text | upcase()") end
it "chains ascii_downcase" do expect(MQ::Query.text.ascii_downcase.to_query).to eq(".text | ascii_downcase()") end
it "chains ascii_upcase" do expect(MQ::Query.text.ascii_upcase.to_query).to eq(".text | ascii_upcase()") end
it "chains explode" do expect(MQ::Query.text.explode.to_query).to eq(".text | explode()") end
it "chains implode" do expect(MQ::Query.text.implode.to_query).to eq(".text | implode()") end
it "chains url_encode" do expect(MQ::Query.text.url_encode.to_query).to eq(".text | url_encode()") end
it "chains url_decode" do expect(MQ::Query.text.url_decode.to_query).to eq(".text | url_decode()") end
it "chains intern" do expect(MQ::Query.text.intern.to_query).to eq(".text | intern()") end
it "chains len" do expect(MQ::Query.text.len.to_query).to eq(".text | len()") end
it "chains utf8bytelen" do expect(MQ::Query.text.utf8bytelen.to_query).to eq(".text | utf8bytelen()") end
Expand All @@ -403,6 +407,10 @@
expect(MQ::Query.text.capture("(\\w+)").to_query).to eq('.text | capture("(\\\\w+)")')
end

it "chains scan with regex pattern" do
expect(MQ::Query.text.scan("(\\w+)").to_query).to eq('.text | scan("(\\\\w+)")')
end

it "chains split" do
expect(MQ::Query.text.split(",").to_query).to eq('.text | split(",")')
end
Expand Down Expand Up @@ -455,6 +463,12 @@
it "chains insert" do
expect(MQ::Query.list.insert(0, "new").to_query).to eq('.[] | insert(0, "new")')
end

it "chains shuffle" do expect(MQ::Query.list.shuffle.to_query).to eq(".[] | shuffle()") end

it "chains sample" do
expect(MQ::Query.list.sample(3).to_query).to eq(".[] | sample(3)")
end
end

describe "math methods" do
Expand Down Expand Up @@ -502,6 +516,34 @@
it "chains sha512" do expect(MQ::Query.text.sha512.to_query).to eq(".text | sha512()") end
it "chains from_hex" do expect(MQ::Query.text.from_hex.to_query).to eq(".text | from_hex()") end
it "chains to_hex" do expect(MQ::Query.text.to_hex.to_query).to eq(".text | to_hex()") end
it "chains uuid" do expect(MQ::Query.text.uuid.to_query).to eq(".text | uuid()") end
it "chains uuid_v4" do expect(MQ::Query.text.uuid_v4.to_query).to eq(".text | uuid_v4()") end
it "chains uuid_v7" do expect(MQ::Query.text.uuid_v7.to_query).to eq(".text | uuid_v7()") end
it "chains rand" do expect(MQ::Query.text.rand.to_query).to eq(".text | rand()") end

it "chains rand_int" do
expect(MQ::Query.text.rand_int(1, 10).to_query).to eq(".text | rand_int(1, 10)")
end

it "builds uuid as a class-level generator" do
expect(MQ::Query.uuid.to_query).to eq("uuid()")
end

it "builds uuid_v4 as a class-level generator" do
expect(MQ::Query.uuid_v4.to_query).to eq("uuid_v4()")
end

it "builds uuid_v7 as a class-level generator" do
expect(MQ::Query.uuid_v7.to_query).to eq("uuid_v7()")
end

it "builds rand as a class-level generator" do
expect(MQ::Query.rand.to_query).to eq("rand()")
end

it "builds rand_int as a class-level generator" do
expect(MQ::Query.rand_int(1, 10).to_query).to eq("rand_int(1, 10)")
end
end

describe "path methods" do
Expand Down