Browse Source

Merge pull request #4832 from nocodb/develop

pull/4834/head
github-actions[bot] 2 years ago committed by GitHub
parent
commit
f96bd9e04c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/release-pr.yml
  2. 2
      charts/nocodb/.gitignore
  3. 23
      charts/nocodb/.helmignore
  4. 12
      charts/nocodb/Chart.yaml
  5. 22
      charts/nocodb/templates/NOTES.txt
  6. 82
      charts/nocodb/templates/_helpers.tpl
  7. 13
      charts/nocodb/templates/configmap.yaml
  8. 73
      charts/nocodb/templates/deployment.yaml
  9. 28
      charts/nocodb/templates/hpa.yaml
  10. 61
      charts/nocodb/templates/ingress.yaml
  11. 14
      charts/nocodb/templates/pvc.yaml
  12. 13
      charts/nocodb/templates/secret.yaml
  13. 15
      charts/nocodb/templates/service.yaml
  14. 12
      charts/nocodb/templates/serviceaccount.yaml
  15. 15
      charts/nocodb/templates/tests/test-connection.yaml
  16. 98
      charts/nocodb/values.yaml
  17. 2
      packages/nc-gui/components/smartsheet/column/LookupOptions.vue
  18. 2
      packages/nc-gui/components/smartsheet/column/RollupOptions.vue
  19. 13
      packages/nc-gui/composables/useSharedFormViewStore.ts
  20. 1
      packages/nc-gui/lang/ar.json
  21. 1
      packages/nc-gui/lang/bn_IN.json
  22. 1
      packages/nc-gui/lang/cs.json
  23. 1
      packages/nc-gui/lang/da.json
  24. 4
      packages/nc-gui/lang/de.json
  25. 1
      packages/nc-gui/lang/en.json
  26. 1
      packages/nc-gui/lang/es.json
  27. 1
      packages/nc-gui/lang/eu.json
  28. 1
      packages/nc-gui/lang/fa.json
  29. 1
      packages/nc-gui/lang/fi.json
  30. 1
      packages/nc-gui/lang/fr.json
  31. 1
      packages/nc-gui/lang/he.json
  32. 1
      packages/nc-gui/lang/hi.json
  33. 1
      packages/nc-gui/lang/hr.json
  34. 1
      packages/nc-gui/lang/id.json
  35. 1
      packages/nc-gui/lang/it.json
  36. 1
      packages/nc-gui/lang/ja.json
  37. 1
      packages/nc-gui/lang/ko.json
  38. 1
      packages/nc-gui/lang/lv.json
  39. 1
      packages/nc-gui/lang/nl.json
  40. 1
      packages/nc-gui/lang/no.json
  41. 1
      packages/nc-gui/lang/pl.json
  42. 1
      packages/nc-gui/lang/pt.json
  43. 1
      packages/nc-gui/lang/pt_BR.json
  44. 1
      packages/nc-gui/lang/ru.json
  45. 1
      packages/nc-gui/lang/sk.json
  46. 1
      packages/nc-gui/lang/sl.json
  47. 1
      packages/nc-gui/lang/sv.json
  48. 1
      packages/nc-gui/lang/th.json
  49. 1
      packages/nc-gui/lang/tr.json
  50. 1
      packages/nc-gui/lang/uk.json
  51. 1
      packages/nc-gui/lang/vi.json
  52. 1
      packages/nc-gui/lang/zh-Hans.json
  53. 1
      packages/nc-gui/lang/zh-Hant.json
  54. 52
      packages/nc-gui/package-lock.json
  55. 2
      packages/nc-gui/package.json
  56. 8
      packages/noco-docs/content/en/setup-and-usages/account-settings.md
  57. 4
      packages/nocodb-sdk/package-lock.json
  58. 2
      packages/nocodb-sdk/src/lib/Api.ts
  59. 30
      packages/nocodb/package-lock.json
  60. 4
      packages/nocodb/package.json
  61. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  62. 18
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts
  63. 3
      scripts/sdk/swagger.json
  64. 22
      tests/playwright/tests/columnFormula.spec.ts

2
.github/workflows/release-pr.yml

@ -33,7 +33,7 @@ jobs:
# Get current PR number
PR_NUMBER=${{github.event.number}}
# Get current version
CURRENT_VERSION=$(curl -fs https://docs.nocodb.com/releases | grep article | grep div | grep h2 | grep 'id\="[^"]*' -o | cut -c 5-)
CURRENT_VERSION=$(curl -fs https://docs.nocodb.com/releases | grep article | grep div | grep h2 | grep 'id\="[^"]*' -o | cut -c 5- | cut -d\: -f1)
# Construct tag name
TAG_NAME=pr-${PR_NUMBER}-${CURRENT_DATE}-${CURRENT_TIME}
echo "TARGET_TAG=${TAG_NAME}" >> $GITHUB_OUTPUT

2
charts/nocodb/.gitignore vendored

@ -0,0 +1,2 @@
charts/
Chart.lock

23
charts/nocodb/.helmignore

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

12
charts/nocodb/Chart.yaml

@ -0,0 +1,12 @@
apiVersion: v2
appVersion: 0.100.2
dependencies:
- condition: postgresql.enabled
name: postgresql
repository: https://charts.bitnami.com/bitnami
version: ~11.6.6
description: A Helm chart for Kubernetes
maintainers: []
name: nocodb
type: application
version: 0.3.0

22
charts/nocodb/templates/NOTES.txt

@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nocodb.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nocodb.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nocodb.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nocodb.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

82
charts/nocodb/templates/_helpers.tpl

@ -0,0 +1,82 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "nocodb.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "nocodb.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "nocodb.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "nocodb.labels" -}}
helm.sh/chart: {{ include "nocodb.chart" . }}
{{ include "nocodb.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "nocodb.selectorLabels" -}}
app.kubernetes.io/name: {{ include "nocodb.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "nocodb.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "nocodb.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{- define "postgresHost" -}}
{{- printf "%s-postgresql" .Release.Name }}
{{- end }}
{{- define "postgresDatabase" -}}
{{- .Values.postgresql.auth.database }}
{{- end }}
{{- define "postgresUsername" -}}
{{- .Values.postgresql.auth.username }}
{{- end }}
{{- define "postgresPassword" -}}
{{- .Values.postgresql.auth.password }}
{{- end }}
{{- define "databaseUri" -}}
{{- printf "pg://%s:5432?u=%s&p=%s&d=%s" (include "postgresHost" .) (include "postgresUsername" .) (include "postgresPassword" .) (include "postgresDatabase" .) }}
{{- end }}

13
charts/nocodb/templates/configmap.yaml

@ -0,0 +1,13 @@
{{- if .Values.extraEnvs }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "nocodb.fullname" . }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
data:
{{- range $key, $value := .Values.extraEnvs }}
{{ $key }}: |-
{{- $value | nindent 4 }}
{{- end }}
{{- end }}

73
charts/nocodb/templates/deployment.yaml

@ -0,0 +1,73 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "nocodb.fullname" . }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "nocodb.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "nocodb.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "nocodb.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
volumeMounts:
- name: {{ include "nocodb.fullname" . }}
mountPath: /usr/app/data
envFrom:
- configMapRef:
name: {{ include "nocodb.fullname" . }}
- secretRef:
name: {{ include "nocodb.fullname" . }}
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: {{ include "nocodb.fullname" . }}
persistentVolumeClaim:
claimName: {{ include "nocodb.fullname" . }}

28
charts/nocodb/templates/hpa.yaml

@ -0,0 +1,28 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "nocodb.fullname" . }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "nocodb.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

61
charts/nocodb/templates/ingress.yaml

@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "nocodb.fullname" . -}}
{{- $svcPort := .Values.ingress.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

14
charts/nocodb/templates/pvc.yaml

@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "nocodb.fullname" . }}
labels:
{{- include "nocodb.selectorLabels" . | nindent 8 }}
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: {{ .Values.storage.size }}
storageClassName: {{ .Values.storage.storageClassName }}
volumeMode: Filesystem

13
charts/nocodb/templates/secret.yaml

@ -0,0 +1,13 @@
{{- if .Values.extraSecretEnvs }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "nocodb.fullname" . }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
data:
NC_DB: {{ include "databaseUri" . | b64enc}}
{{- range $key, $value := .Values.extraSecretEnvs }}
{{ $key }}: '{{ $value | b64enc }}'
{{- end }}
{{- end }}

15
charts/nocodb/templates/service.yaml

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "nocodb.fullname" . }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "nocodb.selectorLabels" . | nindent 4 }}

12
charts/nocodb/templates/serviceaccount.yaml

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "nocodb.serviceAccountName" . }}
labels:
{{- include "nocodb.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

15
charts/nocodb/templates/tests/test-connection.yaml

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "nocodb.fullname" . }}-test-connection"
labels:
{{- include "nocodb.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "nocodb.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

98
charts/nocodb/values.yaml

@ -0,0 +1,98 @@
# Default values for nocodb.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nocodb/nocodb
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: false
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 8080
ingress:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths: []
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
extraEnvs:
NC_PUBLIC_URL: https:/nocodb.local.org
extraSecretEnvs:
NC_AUTH_JWT_SECRET: secretString
storage:
size: 3Gi
storageClassName: ""
postgresql:
enabled: false
auth:
database: nocodb
username: nocodb
password: secretPass
persistence:
size: 8Gi

2
packages/nc-gui/components/smartsheet/column/LookupOptions.vue

@ -56,7 +56,7 @@ const columns = $computed<ColumnType[]>(() => {
<template>
<div class="p-6 w-full flex flex-col border-2 mb-2 mt-4">
<div class="w-full flex flex-row space-x-2">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.childTable')" v-bind="validateInfos.fk_relation_column_id">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.linkToAnotherRecord')" v-bind="validateInfos.fk_relation_column_id">
<a-select
v-model:value="vModel.fk_relation_column_id"
dropdown-class-name="!w-64 nc-dropdown-relation-table"

2
packages/nc-gui/components/smartsheet/column/RollupOptions.vue

@ -76,7 +76,7 @@ const columns = $computed(() => {
<template>
<div class="p-6 w-full flex flex-col border-2 mb-2 mt-4">
<div class="w-full flex flex-row space-x-2">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.childTable')" v-bind="validateInfos.fk_relation_column_id">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.linkToAnotherRecord')" v-bind="validateInfos.fk_relation_column_id">
<a-select
v-model:value="vModel.fk_relation_column_id"
dropdown-class-name="!w-64 nc-dropdown-relation-table"

13
packages/nc-gui/composables/useSharedFormViewStore.ts

@ -43,7 +43,7 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share
const { metas, setMeta } = useMetas()
const { loadProject } = useProject()
const { project } = useProject()
const { t } = useI18n()
@ -86,7 +86,16 @@ const [useProvideSharedFormStore, useSharedFormStore] = useInjectionState((share
await setMeta(viewMeta.model)
await loadProject(true, viewMeta.project_id)
// if project is not defined then set it with an object containing base
if (!project.value?.bases)
project.value = {
bases: [
{
id: viewMeta.base_id,
type: viewMeta.client,
},
],
}
const relatedMetas = { ...viewMeta.relatedMetas }

1
packages/nc-gui/lang/ar.json

@ -277,6 +277,7 @@
"selectUserRole": "حدد دور المستخدم",
"childTable": "جدول فرعي",
"childColumn": "عمود فرعي",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "عند التحديث",
"onDelete": "عند الحذف",
"account": "حساب",

1
packages/nc-gui/lang/bn_IN.json

@ -277,6 +277,7 @@
"selectUserRole": "বযবহরকর ভিিচন করন",
"childTable": "Child table",
"childColumn": "Child column",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "আপড",
"onDelete": "ডিিটএ",
"account": "Account",

1
packages/nc-gui/lang/cs.json

@ -277,6 +277,7 @@
"selectUserRole": "Vybrat uživatelskou roli",
"childTable": "Podřízená tabulka",
"childColumn": "Podřízený sloupec",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Při aktualizaci",
"onDelete": "Při odstranění",
"account": "Účet",

1
packages/nc-gui/lang/da.json

@ -277,6 +277,7 @@
"selectUserRole": "Vælg brugerrolle",
"childTable": "Børnebord",
"childColumn": "Barn kolonne",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "På opdatering",
"onDelete": "På Delete.",
"account": "Account",

4
packages/nc-gui/lang/de.json

@ -277,6 +277,7 @@
"selectUserRole": "Benutzerrolle auswählen",
"childTable": "Child-Tabelle",
"childColumn": "Child-Spalte",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Update",
"onDelete": "Löschen",
"account": "Benutzerkonto",
@ -504,8 +505,7 @@
},
"nonEditableFields": {
"computedFieldUnableToClear": "Warning: Computed field - unable to clear text",
"qrFieldsCannotBeDirectlyChanged": "Warning: QR fields cannot be directly changed.",
"barcodeFieldsCannotBeDirectlyChanged": "Warning: Barcode fields cannot be directly changed."
"qrFieldsCannotBeDirectlyChanged": "Warning: QR fields cannot be directly changed."
}
},
"info": {

1
packages/nc-gui/lang/en.json

@ -277,6 +277,7 @@
"selectUserRole": "Select User Role",
"childTable": "Child table",
"childColumn": "Child column",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "On Update",
"onDelete": "On Delete",
"account": "Account",

1
packages/nc-gui/lang/es.json

@ -277,6 +277,7 @@
"selectUserRole": "Seleccione el rol de usuario",
"childTable": "Tabla hija",
"childColumn": "Columna hija",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "En actualización",
"onDelete": "En eliminar",
"account": "Account",

1
packages/nc-gui/lang/eu.json

@ -277,6 +277,7 @@
"selectUserRole": "Select User Role",
"childTable": "Child table",
"childColumn": "Child column",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "On Update",
"onDelete": "On Delete",
"account": "Account",

1
packages/nc-gui/lang/fa.json

@ -277,6 +277,7 @@
"selectUserRole": "نقش کاربر را انتخاب کنید",
"childTable": "جدول فرزند",
"childColumn": "ستون فرزند",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "هنگام به روز رسانی",
"onDelete": "هنگام حذف",
"account": "Account",

1
packages/nc-gui/lang/fi.json

@ -277,6 +277,7 @@
"selectUserRole": "Valitse käyttäjän rooli",
"childTable": "Lapsipöytä",
"childColumn": "Lapsipylväs",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Päivitys",
"onDelete": "Poista",
"account": "Account",

1
packages/nc-gui/lang/fr.json

@ -277,6 +277,7 @@
"selectUserRole": "Sélectionner le rôle d'utilisateur",
"childTable": "Table enfant",
"childColumn": "Colonne enfant",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Mise à jour en cours",
"onDelete": "Suppression en cours",
"account": "Compte",

1
packages/nc-gui/lang/he.json

@ -277,6 +277,7 @@
"selectUserRole": "בחר תפקיד משתמש",
"childTable": "טבלת ילדים",
"childColumn": "טור ילדים",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "על עדכון",
"onDelete": "על מחיקה",
"account": "Account",

1
packages/nc-gui/lang/hi.json

@ -277,6 +277,7 @@
"selectUserRole": "Select User Role",
"childTable": "Child table",
"childColumn": "Child column",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "On Update",
"onDelete": "On Delete",
"account": "Account",

1
packages/nc-gui/lang/hr.json

@ -277,6 +277,7 @@
"selectUserRole": "Odaberite korisničku ulogu",
"childTable": "Dječji stol",
"childColumn": "Dječji stupac",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Na ažuriranje",
"onDelete": "Na brisanje",
"account": "Account",

1
packages/nc-gui/lang/id.json

@ -277,6 +277,7 @@
"selectUserRole": "Pilih Peran Pengguna",
"childTable": "Tabel Anak",
"childColumn": "Kolom anak.",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Pada pembaruan",
"onDelete": "Hapus",
"account": "Account",

1
packages/nc-gui/lang/it.json

@ -277,6 +277,7 @@
"selectUserRole": "Seleziona il ruolo utente",
"childTable": "Sottotabella",
"childColumn": "Sottocolonna",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "All'aggiornamento",
"onDelete": "All'eliminazione",
"account": "Account",

1
packages/nc-gui/lang/ja.json

@ -277,6 +277,7 @@
"selectUserRole": "ユーザーのロールを選択してください",
"childTable": "子テーブル",
"childColumn": "子カラム",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "更新中",
"onDelete": "削除中",
"account": "アカウント",

1
packages/nc-gui/lang/ko.json

@ -277,6 +277,7 @@
"selectUserRole": "사용자 역할을 선택하세요",
"childTable": "자식 테이블",
"childColumn": "자식 컬럼",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "업데이트 시 ",
"onDelete": "삭제 시",
"account": "Account",

1
packages/nc-gui/lang/lv.json

@ -277,6 +277,7 @@
"selectUserRole": "Izvēlēties lietotāja lomu",
"childTable": "Apakštabula",
"childColumn": "Apakškolonna",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Atjaunojot",
"onDelete": "Dzēšot",
"account": "Account",

1
packages/nc-gui/lang/nl.json

@ -277,6 +277,7 @@
"selectUserRole": "Selecteer de rol van de gebruiker",
"childTable": "Child Tabel",
"childColumn": "Child Kolom",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Bij update",
"onDelete": "Bij verwijdering",
"account": "Account",

1
packages/nc-gui/lang/no.json

@ -277,6 +277,7 @@
"selectUserRole": "Velg Brukerrolle",
"childTable": "Barnbord",
"childColumn": "Barn kolonne",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "På oppdatering",
"onDelete": "På slette",
"account": "Account",

1
packages/nc-gui/lang/pl.json

@ -277,6 +277,7 @@
"selectUserRole": "Wybierz rolę użytkownika",
"childTable": "Stół dziecka.",
"childColumn": "Kolumna dla dzieci",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Na aktualizacji",
"onDelete": "Na delete.",
"account": "Konto",

1
packages/nc-gui/lang/pt.json

@ -277,6 +277,7 @@
"selectUserRole": "Selecione a função do usuário",
"childTable": "Mesa de criança",
"childColumn": "Coluna de criança",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Na atualização",
"onDelete": "Em excluir",
"account": "Account",

1
packages/nc-gui/lang/pt_BR.json

@ -277,6 +277,7 @@
"selectUserRole": "Selecione a função do usuário",
"childTable": "Mesa de criança",
"childColumn": "Coluna de criança",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Na atualização",
"onDelete": "Em excluir",
"account": "Account",

1
packages/nc-gui/lang/ru.json

@ -277,6 +277,7 @@
"selectUserRole": "Выберите роль пользователя",
"childTable": "Дочерняя таблица",
"childColumn": "Дочерний столбец",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "При обновлении",
"onDelete": "При удалении",
"account": "Учётная запись",

1
packages/nc-gui/lang/sk.json

@ -277,6 +277,7 @@
"selectUserRole": "Select User Role",
"childTable": "Child table",
"childColumn": "Child column",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "On Update",
"onDelete": "On Delete",
"account": "Account",

1
packages/nc-gui/lang/sl.json

@ -277,6 +277,7 @@
"selectUserRole": "Izberite vlogo uporabnika",
"childTable": "Otroška miza",
"childColumn": "Otroška stolpec",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Na posodobitvi",
"onDelete": "Na izbrisu",
"account": "Account",

1
packages/nc-gui/lang/sv.json

@ -277,6 +277,7 @@
"selectUserRole": "Välj användarroll",
"childTable": "Barnbord",
"childColumn": "Barnkolonn",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Vid uppdatering",
"onDelete": "På radera",
"account": "Account",

1
packages/nc-gui/lang/th.json

@ -277,6 +277,7 @@
"selectUserRole": "เลอกบทบาทผใช",
"childTable": "โตะเดก",
"childColumn": "คอลมนเดก",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "เมออปเดต",
"onDelete": "ในการลบ",
"account": "Account",

1
packages/nc-gui/lang/tr.json

@ -277,6 +277,7 @@
"selectUserRole": "Kullanıcı Rolü Seç",
"childTable": "Alt tablo",
"childColumn": "Alt sütun",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Güncellenince",
"onDelete": "Silinince",
"account": "Account",

1
packages/nc-gui/lang/uk.json

@ -277,6 +277,7 @@
"selectUserRole": "Виберіть Роль користувача",
"childTable": "Дитячий стіл",
"childColumn": "Дитяча колонка",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "На оновлення",
"onDelete": "На видалі",
"account": "Обліковий запис",

1
packages/nc-gui/lang/vi.json

@ -277,6 +277,7 @@
"selectUserRole": "Chọn vai trò người dùng",
"childTable": "Bảng con",
"childColumn": "Cột trẻ con.",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "Trên bản cập nhật",
"onDelete": "Trên xóa",
"account": "Tài khoản",

1
packages/nc-gui/lang/zh-Hans.json

@ -277,6 +277,7 @@
"selectUserRole": "选择用户角色",
"childTable": "子表",
"childColumn": "子列",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "更新",
"onDelete": "删除",
"account": "帐户",

1
packages/nc-gui/lang/zh-Hant.json

@ -277,6 +277,7 @@
"selectUserRole": "選擇使用者角色",
"childTable": "子表格",
"childColumn": "子欄",
"linkToAnotherRecord": "Link to another record",
"onUpdate": "更新",
"onDelete": "在刪除",
"account": "Account",

52
packages/nc-gui/package-lock.json generated

@ -29,7 +29,7 @@
"jwt-decode": "^3.1.2",
"locale-codes": "^1.3.1",
"monaco-editor": "^0.33.0",
"nocodb-sdk": "0.101.0",
"nocodb-sdk": "file:../nocodb-sdk",
"papaparse": "^5.3.2",
"qrcode": "^1.5.1",
"socket.io-client": "^4.5.1",
@ -96,7 +96,6 @@
},
"../nocodb-sdk": {
"version": "0.101.0",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -8544,6 +8543,7 @@
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"devOptional": true,
"funding": [
{
"type": "individual",
@ -11959,21 +11959,8 @@
}
},
"node_modules/nocodb-sdk": {
"version": "0.101.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0.tgz",
"integrity": "sha512-7TZ+ZlJq1DCW9lqf9yOFGGe9r9KuyFEzjxkrrcYigBgIb9I4ob+VGb/XbYIplhh73EeDFhxWLkC1lnTr1bWD5A==",
"dependencies": {
"axios": "^0.21.1",
"jsep": "^1.3.6"
}
},
"node_modules/nocodb-sdk/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dependencies": {
"follow-redirects": "^1.14.0"
}
"resolved": "../nocodb-sdk",
"link": true
},
"node_modules/node-abi": {
"version": "3.23.0",
@ -23937,7 +23924,8 @@
"follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"devOptional": true
},
"form-data": {
"version": "4.0.0",
@ -26410,22 +26398,22 @@
}
},
"nocodb-sdk": {
"version": "0.101.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0.tgz",
"integrity": "sha512-7TZ+ZlJq1DCW9lqf9yOFGGe9r9KuyFEzjxkrrcYigBgIb9I4ob+VGb/XbYIplhh73EeDFhxWLkC1lnTr1bWD5A==",
"version": "file:../nocodb-sdk",
"requires": {
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.21.1",
"jsep": "^1.3.6"
},
"dependencies": {
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"requires": {
"follow-redirects": "^1.14.0"
}
}
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^4.0.0",
"jsep": "^1.3.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"typescript": "^4.0.2"
}
},
"node-abi": {

2
packages/nc-gui/package.json

@ -52,7 +52,7 @@
"jwt-decode": "^3.1.2",
"locale-codes": "^1.3.1",
"monaco-editor": "^0.33.0",
"nocodb-sdk": "0.101.0",
"nocodb-sdk": "file:../nocodb-sdk",
"papaparse": "^5.3.2",
"qrcode": "^1.5.1",
"socket.io-client": "^4.5.1",

8
packages/noco-docs/content/en/setup-and-usages/account-settings.md

@ -45,4 +45,10 @@ Signup without an invitation is disabled by default and can be managed from UI b
You can also manage the app store plugins here.
![image](https://user-images.githubusercontent.com/35857179/203267619-24a8f5f5-1c8c-4419-a7a1-be4377fe6216.png)
![image](https://user-images.githubusercontent.com/35857179/203267619-24a8f5f5-1c8c-4419-a7a1-be4377fe6216.png)
## License
You can configure NocoDB Enterprise `License key` here
![Screenshot 2023-01-12 at 2 30 57 PM](https://user-images.githubusercontent.com/86527202/212023989-0129af0a-689d-465e-bdda-3d54399ea6b7.png)

4
packages/nocodb-sdk/package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "nocodb-sdk",
"version": "0.101.0-beta.0",
"version": "0.101.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb-sdk",
"version": "0.101.0-beta.0",
"version": "0.101.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",

2
packages/nocodb-sdk/src/lib/Api.ts

@ -4004,6 +4004,7 @@ export class Api<
* @response `200` `(ViewType & {
relatedMetas?: any,
client?: string,
base_id?: string,
columns?: ((GridColumnType | FormColumnType | GalleryColumnType) & ColumnType),
model?: TableType,
@ -4017,6 +4018,7 @@ export class Api<
ViewType & {
relatedMetas?: any;
client?: string;
base_id?: string;
columns?: (GridColumnType | FormColumnType | GalleryColumnType) &
ColumnType;
model?: TableType;

30
packages/nocodb/package-lock.json generated

@ -68,7 +68,7 @@
"nc-lib-gui": "0.101.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "0.101.0",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"os-locale": "^5.0.0",
@ -154,7 +154,6 @@
},
"../nocodb-sdk": {
"version": "0.101.0",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -11223,13 +11222,8 @@
"dev": true
},
"node_modules/nocodb-sdk": {
"version": "0.101.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0.tgz",
"integrity": "sha512-7TZ+ZlJq1DCW9lqf9yOFGGe9r9KuyFEzjxkrrcYigBgIb9I4ob+VGb/XbYIplhh73EeDFhxWLkC1lnTr1bWD5A==",
"dependencies": {
"axios": "^0.21.1",
"jsep": "^1.3.6"
}
"resolved": "../nocodb-sdk",
"link": true
},
"node_modules/node-abort-controller": {
"version": "3.0.1",
@ -27742,12 +27736,22 @@
"dev": true
},
"nocodb-sdk": {
"version": "0.101.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0.tgz",
"integrity": "sha512-7TZ+ZlJq1DCW9lqf9yOFGGe9r9KuyFEzjxkrrcYigBgIb9I4ob+VGb/XbYIplhh73EeDFhxWLkC1lnTr1bWD5A==",
"version": "file:../nocodb-sdk",
"requires": {
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.21.1",
"jsep": "^1.3.6"
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^4.0.0",
"jsep": "^1.3.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"typescript": "^4.0.2"
}
},
"node-abort-controller": {

4
packages/nocodb/package.json

@ -108,7 +108,7 @@
"nc-lib-gui": "0.101.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "0.101.0",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"os-locale": "^5.0.0",
@ -183,4 +183,4 @@
"prettier": {
"singleQuote": true
}
}
}

2
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts

@ -91,7 +91,7 @@ const pg = {
DATE_PART('year', AGE(${datetime_expr2}, '1900/01/01')) * 4) - 1)`;
break;
case 'year':
sql = `DATE_PART('year', ${datetime_expr1}::TIMESTAMP) - DATE_PART('year', ${datetime_expr2}::TIMESTAMP)`;
sql = `DATE_PART('year', AGE(${datetime_expr1}, ${datetime_expr2}))`;
break;
case 'day':
sql = `DATE_PART('day', ${datetime_expr1}::TIMESTAMP - ${datetime_expr2}::TIMESTAMP)`;

18
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

@ -130,7 +130,23 @@ const sqlite3 = {
sql = `(strftime('%Y', ${datetime_expr1}) - strftime('%Y', ${datetime_expr2})) * 4 + (strftime('%m', ${datetime_expr1}) - strftime('%m', ${datetime_expr2})) / 3`;
break;
case 'years':
sql = `strftime('%Y', ${datetime_expr1}) - strftime('%Y', ${datetime_expr2})`;
sql = `CASE
WHEN (${datetime_expr2} < ${datetime_expr1}) THEN
(
(strftime('%Y', ${datetime_expr1}) - strftime('%Y', ${datetime_expr2}))
- (strftime('%m', ${datetime_expr1}) < strftime('%m', ${datetime_expr2})
OR (strftime('%m', ${datetime_expr1}) = strftime('%m', ${datetime_expr2})
AND strftime('%d', ${datetime_expr1}) < strftime('%d', ${datetime_expr2})))
)
WHEN (${datetime_expr2} > ${datetime_expr1}) THEN
-1 * (
(strftime('%Y', ${datetime_expr2}) - strftime('%Y', ${datetime_expr1}))
- (strftime('%m', ${datetime_expr2}) < strftime('%m', ${datetime_expr1})
OR (strftime('%m', ${datetime_expr2}) = strftime('%m', ${datetime_expr1})
AND strftime('%d', ${datetime_expr2}) < strftime('%d', ${datetime_expr1})))
)
ELSE 0
END`;
break;
case 'days':
sql = `JULIANDAY(${datetime_expr1}) - JULIANDAY(${datetime_expr2})`;

3
scripts/sdk/swagger.json

@ -5529,6 +5529,9 @@
"client": {
"type": "string"
},
"base_id": {
"type": "string"
},
"columns": {
"allOf": [
{

22
tests/playwright/tests/columnFormula.spec.ts

@ -38,6 +38,10 @@ const formulaDataByDbType = (context: NcContext) => [
formula: `DATETIME_DIFF("2022/10/14", "2022/10/15", "minutes")`,
result: ['-1440', '-1440', '-1440', '-1440', '-1440'],
},
{
formula: `DATETIME_DIFF("2023/10/14", "2023/01/13", "minutes")`,
result: ['394560', '394560', '394560', '394560', '394560'],
},
{
formula: `DATETIME_DIFF("2022/10/14", "2022/10/15", "seconds")`,
result: ['-86400', '-86400', '-86400', '-86400', '-86400'],
@ -67,19 +71,31 @@ const formulaDataByDbType = (context: NcContext) => [
result: ['-1', '-1', '-1', '-1', '-1'],
},
{
formula: `DATETIME_DIFF(NOW(), "2023/10/14", "y")`,
formula: `DATETIME_DIFF("2023/01/12", "2023/10/14", "y")`,
result: ['0', '0', '0', '0', '0'],
},
{
formula: `DATETIME_DIFF("2023/10/14", NOW(), "y")`,
formula: `DATETIME_DIFF("2023/10/14", "2023/01/12", "y")`,
result: ['0', '0', '0', '0', '0'],
},
{
formula: `DATETIME_DIFF("2023-01-12", "2021-08-29", "y")`,
result: ['1', '1', '1', '1', '1'],
},
{
formula: `DATETIME_DIFF("2021-01-12", "2026-01-29", "y")`,
result: ['-5', '-5', '-5', '-5', '-5'],
},
{
formula: `DATETIME_DIFF("1990-01-12", "2046-12-29", "y")`,
result: ['-56', '-56', '-56', '-56', '-56'],
},
{
formula: `DATETIME_DIFF("2022/10/14", "2023/10/14", "d")`,
result: ['-365', '-365', '-365', '-365', '-365'],
},
{
formula: `DATETIME_DIFF("2022/10/14", NOW(), "d")`,
formula: `DATETIME_DIFF("2022/10/14", "2023/01/12", "d")`,
result: ['-90', '-90', '-90', '-90', '-90'],
},
{

Loading…
Cancel
Save