Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a User-Defined Stored Procedure to the SQLite schema #236

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ libstuff.a
sqlitecluster/sqlitecluster
libstuff/libstuff.d
libstuff/libstuff.h.gch
udf.so
29 changes: 27 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@ clustertest: test/clustertest/clustertest testplugin
testplugin:
cd test/clustertest/testplugin && make

.PHONY: docker udf

docker:
docker build -t bedbugs $(PROJECT)/docker/bedbugs
docker run -t --rm -v $(PROJECT):/src bedbugs bedrock udf
cp $(PROJECT)/bedrock $(PROJECT)/docker/bedrook/bedrock
cp $(PROJECT)/udf.so $(PROJECT)/docker/bedrook/udf.so
docker build -t bedrock $(PROJECT)/docker/bedrook

udf: udf.so

UDFSRC = udf.c
UDFCPP = udfplug.cpp
UDFOBJ = $(UDFSRC:%.c=$(INTERMEDIATEDIR)/%.o)
UDFOBJ += $(UDFCPP:%.cpp=$(INTERMEDIATEDIR)/%.o)

CFLAGS += -fPIC -I$(PROJECT)/libstuff

udf.so: $(UDFOBJ)
$(GXX) $(CXXFLAGS) -shared -o $@ $(UDFOBJ)

# Set up our precompiled header. This makes building *way* faster (roughly twice as fast).
# Including it here causes it to be generated.
# Depends on one of our mbedtls files, to make sure the submodule gets pulled and built.
Expand All @@ -53,7 +74,9 @@ PRECOMPILE_INCLUDE =-include libstuff/libstuff.h
libstuff/libstuff.h.gch libstuff/libstuff.d: libstuff/libstuff.h mbedtls/library/libmbedcrypto.a
$(GXX) $(CXXFLAGS) -MMD -MF libstuff/libstuff.d -MT libstuff/libstuff.h.gch -c libstuff/libstuff.h
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),docker)
-include libstuff/libstuff.d
endif
endif
endif

Expand Down Expand Up @@ -84,7 +107,7 @@ STUFFC = $(shell find libstuff -name '*.c')
STUFFOBJ = $(STUFFCPP:%.cpp=$(INTERMEDIATEDIR)/%.o) $(STUFFC:%.c=$(INTERMEDIATEDIR)/%.o)
STUFFDEP = $(STUFFCPP:%.cpp=$(INTERMEDIATEDIR)/%.d)

LIBBEDROCKCPP = $(shell find * -name '*.cpp' -not -name main.cpp -not -path 'test*' -not -path 'libstuff*')
LIBBEDROCKCPP = $(shell find * -name '*.cpp' -not -name main.cpp -not -name udfplug.cpp -not -path 'test*' -not -path 'libstuff*')
LIBBEDROCKOBJ = $(LIBBEDROCKCPP:%.cpp=$(INTERMEDIATEDIR)/%.o)
LIBBEDROCKDEP = $(LIBBEDROCKCPP:%.cpp=$(INTERMEDIATEDIR)/%.d)

Expand All @@ -103,11 +126,13 @@ CLUSTERTESTDEP = $(CLUSTERTESTCPP:%.cpp=$(INTERMEDIATEDIR)/%.d)
# Bring in the dependency files. This will cause them to be created if necessary. This is skipped if we're cleaning, as
# they'll just get deleted anyway.
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),docker)
-include $(STUFFDEP)
-include $(LIBBEDROCKDEP)
-include $(BEDROCKDEP)
#-include $(TESTDEP)
#-include $(CLUSTERTESTDEP)
endif
endif

# Our static libraries just depend on their object files.
Expand All @@ -118,7 +143,7 @@ libbedrock.a: $(LIBBEDROCKOBJ)

# We use the same library paths and required libraries for both binaries.
LIBPATHS =-Lmbedtls/library -L$(PROJECT)
LIBRARIES =-lbedrock -lstuff -ldl -lpcrecpp -lpthread -lmbedtls -lmbedx509 -lmbedcrypto -lz
LIBRARIES =-lbedrock -lstuff -ldl -lpcrecpp -lpthread -lmbedtls -lmbedx509 -lmbedcrypto -lz -lexecinfo

# The prerequisites for both binaries are the same. We only include one of the mbedtls libs to avoid building three
# times in parallel.
Expand Down
18 changes: 18 additions & 0 deletions docker/bedbugs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM alpine:3.6

# Requirements
RUN apk update \
&& apk add alpine-sdk

RUN apk add musl-dev pcre-dev zlib-dev libexecinfo-dev

RUN adduser -h /out -u 1000 -D build \
&& chgrp build /lib \
&& chmod 775 /lib

COPY makeme /usr/bin

USER build
WORKDIR /src

ENTRYPOINT ["makeme"]
8 changes: 8 additions & 0 deletions docker/bedbugs/makeme
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh

echo makeme "$@"

export GXX=g++
export CC=gcc

make -C /src -e "$@"
17 changes: 17 additions & 0 deletions docker/bedrook/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM alpine:3.6

RUN apk update \
&& apk add libpcrecpp libstdc++ libgcc libexecinfo

RUN adduser -h /db -u 1000 -D bed \
&& chgrp bed /lib \
&& chmod 775 /lib

COPY bedrock start-bedrock /usr/local/bin/
COPY udf.so /usr/local/lib/

#USER bed
VOLUME /db
WORKDIR /db

ENTRYPOINT ["start-bedrock"]
26 changes: 26 additions & 0 deletions docker/bedrook/start-bedrock
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh

export NODE=ohio
export DB=/db/bedrock.db
export CFG=/db/bedrock.cfg
export PEERS=/db/bedrock.peers
export PRIO=30
export RUN=/var/run/bedrock.pid

syslogd -S

if [ ! -f $CFG ]
then
echo "-plugins db,jobs,cache,mysql" >$CFG
fi

touch $DB $PEERS

cat $CFG $PEERS | xargs bedrock -fork -v -db $DB -pidfile $RUN

#bedrock -fork -nodeName $NODE -db $DB \
# -serverHost 0.0.0.0:8888 -nodeHost 0.0.0.0:8889 -priority $PRIO -pidfile $RUN \
# -quorumCheckpoint 100 -readThreads 4 -cache 10001 -plugins status,db,jobs,cache,mysql \
# -v

sh -i
Binary file added docker/bedrook/udf.so
Binary file not shown.
4 changes: 2 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ set<string> loadPlugins(SData& args) {
// Open the library.
void* lib = dlopen(pluginName.c_str(), RTLD_NOW);
if(!lib) {
cout << "Error loading bedrock plugin " << pluginName << ": " << dlerror() << endl;
SWARN("Error loading bedrock plugin " << pluginName << ": " << dlerror());
} else {
void* sym = dlsym(lib, symbolName.c_str());
if (!sym) {
cout << "Couldn't find symbol " << symbolName << endl;
SWARN("Couldn't find symbol " << symbolName);
} else {
// Call the plugin registration function with the same name.
((void(*)()) sym)();
Expand Down
65 changes: 65 additions & 0 deletions udf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2017 Guy Riddle

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

/*
* One sample SQLite stored function that is automatically loaded into each database opened.
*
* You might use a different cheese, of course.
*
* Demonstrate via: "SELECT gouda(1.2, 2.3, 5.0, 3.4);"
*
*/

static void
gouda_function(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
double a = sqlite3_value_double(argv[0]);
double b = sqlite3_value_double(argv[1]);
double c = sqlite3_value_double(argv[2]);
double d = sqlite3_value_double(argv[3]);
double answer;

answer = a*b - c*d;

sqlite3_result_double(context, answer);
}

int
load_udf_definitions(
sqlite3 *db,
const char **pzErrMsg,
const struct sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);

rc = sqlite3_create_function(db, "gouda", 4, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, gouda_function, 0, 0);

return(rc);
};

#undef sqlite3_auto_extension

void
udf_initialize(){
sqlite3_auto_extension((void *) &load_udf_definitions);
}
Binary file added udf.so
Binary file not shown.
23 changes: 23 additions & 0 deletions udfplug.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#include <BedrockPlugin.h>

/*
* We don't really need the Bedrock plugin APIs, just the loading mechanism.
*
* The SQLite stored functions we register get done in udf_initialize()
*
*/

class BedrockPlugin_UDF : public BedrockPlugin
{
public:
virtual string getName() { return "UDF"; }
};

extern "C" void udf_initialize();

extern "C" void BEDROCK_PLUGIN_REGISTER_UDF() {
new BedrockPlugin_UDF();

udf_initialize();
}