autoincrement
This is the equivalent of Prisma's autoincrement(). It automatically assigns unique, monotonically increasing values during create operations.
Schema vs. Constructor
When using the CLI, this setting is written in schema.prisma. When using the GAS editor alone, you pass it to the GassmaClient constructor (the examples on the rest of this page use the constructor form).
| How to write it | |
|---|---|
| Schema (CLI) | id Int @id @default(autoincrement()) |
| Constructor (GAS editor) | autoincrement: { Users: "id" } |
model Users {
id Int @id @default(autoincrement())
name String
}
For how to write schemas, see Schema.
Basic Usage
const gassma = new Gassma.GassmaClient({
autoincrement: {
Users: "id",
},
});
// id is automatically assigned during create
gassma.Users.create({
data: { name: "Alice" },
});
// => \{ id: 1, name: "Alice" \}
gassma.Users.create({
data: { name: "Bob" },
});
// => \{ id: 2, name: "Bob" \}
Multiple Columns
You can specify multiple columns using an array.
autoincrement: {
Users: ["id", "seq"],
}
Behavior with createMany
With createMany, counters for all rows are reserved at once before being assigned to each row.
gassma.Users.createMany({
data: [{ name: "Alice" }, { name: "Bob" }],
});
// => id: 1, 2 are assigned respectively
How It Works
- Exclusive control by acquiring the
GassmaClient'slockwithwaitLock(10000) - Read the counter from
PropertiesService.getScriptProperties() - Increment by +1 (+N for createMany) and write back
- Release the lock
The client generated by npx gassma generate fills lock with LockService.getScriptLock() by default. On a client that has no lock (for example one constructed in the GAS editor without passing lock), numbers are assigned without taking a lock (this is not an error).
This feature only works in the GAS environment because it uses GAS's LockService and PropertiesService.
Behavior with Explicit Values
If a value is explicitly specified for a field, auto-increment is skipped.
gassma.Users.create({
data: { id: 100, name: "Alice" },
});
// => id is 100 (auto-increment is not applied)
Adopting GASsma on a Sheet That Already Has Data
The counter starts at 0 and does not look at the values already in the sheet. So if you adopt GASsma on a sheet whose id values run from 1 to 500, the first create assigns id: 1 and collides with an existing row.
Calling $syncAutoincrement() restarts the counter just after the largest value in that column. Call it once when you adopt GASsma.
// When the existing ids run from 1 to 500
gassma.Users.$syncAutoincrement("id");
// => 501
gassma.Users.create({
data: { name: "Alice" },
});
// => { id: 501, name: "Alice" }
If rows are added by editing the spreadsheet by hand and the counter falls out of sync, calling $syncAutoincrement() again brings it back in the same way.
Operating the Counter
In Prisma, autoincrement() takes no arguments, and the counter is adjusted with SQL such as ALTER SEQUENCE ... RESTART WITH. The GASsma counter lives in PropertiesService and can be reached neither from the schema nor from SQL, so it is exposed as methods on the model instead.
All three methods speak in terms of the value that will be issued next. This is the same meaning as ALTER SEQUENCE ... RESTART WITH 1000.
| Method | Return value | Description |
|---|---|---|
$getAutoincrement(field) | number | Returns the value that will be issued next (1 if nothing has been issued yet) |
$setAutoincrement(field, next) | void | Makes next the value that will be issued next |
$syncAutoincrement(field) | number | Sets the counter to the largest value in the column + 1 and returns it |
gassma.Users.$getAutoincrement("id");
// => 1
gassma.Users.$setAutoincrement("id", 501);
gassma.Users.$getAutoincrement("id");
// => 501
Use $setAutoincrement when you want to decide the value yourself. If you only want to match the existing data, use $syncAutoincrement.
With the CLI, the type of field on all three methods is narrowed to the fields of that model that have autoincrement configured. Writing a field name that is not configured is a type error, and on a model with no autoincrement field at all the type of field is never, so the methods cannot be called.
What $syncAutoincrement Looks At
- It reads only the column of the target field (not the whole sheet)
- It takes the maximum of numeric values only. Empty cells and non-numeric values are ignored
- Decimals are truncated (if
3.7is present, the next value is4) - If there are no numeric values at all, or only negative numbers, the next value is
1
Related Errors
| Error | Trigger condition |
|---|---|
GassmaAutoincrementNotConfiguredError | A field that is not configured with autoincrement is passed as field |
GassmaAutoincrementInTransactionError | $setAutoincrement / $syncAutoincrement is called inside $transaction |
GassmaInvalidValueError | The next of $setAutoincrement is not an integer of 1 or greater (NaN / Infinity / a decimal / 0 or less / a non-number) |
GassmaInvalidValueError | $syncAutoincrement is called when the column of the field configured with autoincrement does not exist on the sheet (for example after the column was renamed) |
For details, see the Error List.
$setAutoincrement / $syncAutoincrement cannot be called inside $transaction. The counter lives in PropertiesService and never enters the sheet buffer, so it is not rolled back when the transaction fails. $getAutoincrement only reads, so it can be called inside a transaction.