Function View

Function view provides a flexible way to control user access to databases and tables in DolphinDB. A function view is a user-defined function that encapsulates statements requiring access to databases. Even without direct read privileges, users can indirectly access database by executing function views to obtain desired calculation results. Function views can be added by specifying user-defined functions or module namespaces.

User-Defined Functions

A user-defined function can be added as a function view with addFunctionView.

In the following example, user1 does not have the privilege to read and write to table dfs://db1/pt. Login as an admin, define function getAvg as a function review, and grant VIEW_EXEC to user1. Although not granted to read table dfs://db1/pt, user1 can still execute getAvg to calculate daily average value.
// create table dfs://db1/pt
login(userId=`admin, password=`123456)
db = database(directory="dfs://db1", partitionType=VALUE, 
  partitionScheme=2024.01.01..2024.01.10)
t = table(stretch(2024.01.01..2024.01.10,100) as date, rand(1000,100) as val)
pt = createPartitionedTable(dbHandle=db, table=t, tableName="pt", 
  partitionColumns="date")
pt.tableInsert(t)

// define getAvg as function view
def getAvg(){
  return select avg(val) from loadTable(database="dfs://db1", tableName="pt") group by date
}
login(userId=`admin, password=`123456)
addFunctionView(udf=getAvg)

// create user1 and grant VIEW_EXEC
createUser(userId=`user1, password=`123456)
grant(userId=`user1, accessType=VIEW_EXEC, objs="getAvg")

// user1 cannot query table pt
login(userId=`user1, password=`123456)
select avg(val) from loadTable(database="dfs://db1", tableName="pt") group by date 
// <NoPrivilege>Not granted to read table dfs://db1/pt

// user1 executes getAvg()
getAvg()
date avg_val
2024.01.01 438
2024.01.02 447.6
2024.01.03 499.6
2024.01.04 355.2
2024.01.05 551.9
2024.01.06 330.2
2024.01.07 366.5
2024.01.08 547.9
2024.01.09 473
2024.01.10 369.2

The value column in the example is randomly generated, so the average value (avg_val) in the result may be different on each execution.

To check function views (with definitions), use getFunctionViews:
getFunctionViews()
name body
getAvg def getAvg(){ return select avg(val) as avg_val from loadTable("dfs://db1", "pt") group by date }
If a DolphinDB cluster is restarted, a previously defined function view can still be used. However, the definition of a function view cannot be modified. You can delete the function view with dropFunctionView and then redefine it.
dropFunctionView("getAvg")

Module Functions

Functions defined within a module can be added as views by specifying the module namespace.

For example, declare a module myModule and define functions f1() and f2() in the file [home]/modules/dir1/myModule.dos.
module dir1::myModule

def f1(){
    print "dir1::myModule::f1"
}
def f2(){
    print "dir1::myModule::f2"
}
Reference the module with use, then add all functions within the module as views by specifying moduleName="dir1::myModule".
login(userId=`admin, password=`123456)
use dir1::myModule
addFunctionView(moduleName="dir1::myModule")
To check all defined function views (with definitions), simply use getFunctionViews:
getFunctionViews()
name body
dir1::myModule::f1 def f1(){ print("dir1::myModule::f1") }
dir1::myModule::f2 def f2(){ print("dir1::myModule::f2")}
Function views added by a module can be dropped either independently or in batches. To drop a single function view, specify its full name including the namespace. To drop multiple function views at once, specify the module namespace.
// drop the function view of f1
dropFunctionView(name="dir1::myModule::f1")

// drop all views within dir1::myModule
dropFunctionView(name="dir1::myModule",isNamespace=true)